diff --git a/src/kernel_evm_mockup/src/block.rs b/src/kernel_evm_mockup/src/block.rs index 812463cf37734cb76a896fbc7f1f21874692cf5b..0ccfc03ad21f49b324a85025ce738f3862500246 100644 --- a/src/kernel_evm_mockup/src/block.rs +++ b/src/kernel_evm_mockup/src/block.rs @@ -2,7 +2,13 @@ // // SPDX-License-Identifier: MIT +use crate::blueprint::Queue; +use crate::error::Error; use crate::eth_gen::{L2Level, OwnedHash, Quantity, RawTransactions}; +use crate::inbox; +use crate::storage; +use host::rollup_core::RawRollupCore; +use host::runtime::Runtime; pub struct L2Block { // This choice of a L2 block representation is totally @@ -41,10 +47,10 @@ impl L2Block { L2Block::DUMMY_HASH.into() } - pub fn new(number: L2Level, hash: OwnedHash, transactions: RawTransactions) -> Self { + pub fn new(number: L2Level, transactions: RawTransactions) -> Self { L2Block { number, - hash, + hash: L2Block::dummy_hash(), parent_hash: L2Block::dummy_hash(), nonce: L2Block::DUMMY_QUANTITY, sha3_uncles: L2Block::dummy_hash(), @@ -65,3 +71,29 @@ impl L2Block { } } } + +fn validate(block: L2Block) -> Result { + // TODO: https://gitlab.com/tezos/tezos/-/issues/4749 + Ok(block) +} + +pub fn produce(host: &mut Host, queue: Queue) { + for proposal in queue.proposals.iter() { + let current_level = storage::read_current_block_number(host); + let next_level = match current_level { + Ok(current_level) => current_level + 1, + Err(_) => 0, + }; + let raw_transactions = proposal + .transactions + .iter() + .map(inbox::Transaction::to_raw_transaction) + .collect(); + let candidate_block = L2Block::new(next_level, raw_transactions); + if let Ok(valid_block) = validate(candidate_block) { + storage::store_current_block(host, valid_block).unwrap_or_else(|_| { + panic!("Error while storing the current block: stopping the daemon.") + }) + } + } +} diff --git a/src/kernel_evm_mockup/src/blueprint.rs b/src/kernel_evm_mockup/src/blueprint.rs index aeeb8f9763afb090151a233996ee2997b335bf23..dccf0dc64e601f231480936e5ecbcedf646a4f70 100644 --- a/src/kernel_evm_mockup/src/blueprint.rs +++ b/src/kernel_evm_mockup/src/blueprint.rs @@ -12,6 +12,7 @@ pub struct Blueprint { pub transactions: Vec, } +#[derive(Default)] pub struct Queue { // In our case, to make it simple and straightforward it will be // an array of pendings transactions even though it'll be only a @@ -20,6 +21,12 @@ pub struct Queue { } impl Queue { + pub fn new() -> Queue { + Queue { + proposals: Vec::new(), + } + } + pub fn add(queue: &mut Queue, transactions: Vec) { queue.proposals.push(Blueprint { transactions }) } diff --git a/src/kernel_evm_mockup/src/inbox.rs b/src/kernel_evm_mockup/src/inbox.rs index afe5ecc54a4322febed4082b6444574cd961c510..f59c8734f671761b1c01d87c5c89a83433b44809 100644 --- a/src/kernel_evm_mockup/src/inbox.rs +++ b/src/kernel_evm_mockup/src/inbox.rs @@ -28,6 +28,10 @@ impl Transaction { tx, } } + + pub fn to_raw_transaction(&self) -> RawTransaction { + self.tx.clone() + } } pub fn read_input( diff --git a/src/kernel_evm_mockup/src/lib.rs b/src/kernel_evm_mockup/src/lib.rs index 053c037c8b36dcab7027d8e6286f4684a0fbb490..ae36aa132a48541e326a461c5d65f5f92e167567 100644 --- a/src/kernel_evm_mockup/src/lib.rs +++ b/src/kernel_evm_mockup/src/lib.rs @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: MIT +use block::L2Block; use host::rollup_core::RawRollupCore; use host::runtime::Runtime; @@ -24,7 +25,31 @@ mod storage; mod wei; pub fn stage_one(host: &mut Host) -> Queue { - fetch(host) + let queue = fetch(host); + + for (i, blueprint) in queue.proposals.iter().enumerate() { + debug_msg!(host; "Blueprint {} contains {} transactions.\n", i, blueprint.transactions.len()); + } + + queue +} + +pub fn stage_two(host: &mut Host, queue: Queue) { + block::produce(host, queue); + + if let Ok(L2Block { + number, + hash, + transactions, + .. + }) = storage::read_current_block(host) + { + debug_msg!(host; "Block {} at number {} contains {} transaction(s).\n", + String::from_utf8(hash).expect("INVALID HASH"), + number, + transactions.len() + ) + } } pub fn init_mock_account(host: &mut Host) -> Result<(), Error> { @@ -43,11 +68,9 @@ pub fn main(host: &mut Host) { Err(_) => panic!("The account should be writable"), } - // Stage 1. - let Queue { proposals } = stage_one(host); - for (i, blueprint) in proposals.iter().enumerate() { - debug_msg!(host; "Blueprint {} contains {} transactions.\n", i, blueprint.transactions.len()); - } + let queue = stage_one(host); + + stage_two(host, queue) } kernel_entry!(main); diff --git a/src/kernel_evm_mockup/src/storage.rs b/src/kernel_evm_mockup/src/storage.rs index ef6d0fb2352dfce73684c584cb48a1de4bb212ef..8aee05b7a90add1cd6f7f0cec18d93c3b620b825 100644 --- a/src/kernel_evm_mockup/src/storage.rs +++ b/src/kernel_evm_mockup/src/storage.rs @@ -12,7 +12,7 @@ use std::str::from_utf8; use crate::account::*; use crate::block::L2Block; use crate::error::Error; -use crate::eth_gen::{Hash, L2Level, RawTransactions}; +use crate::eth_gen::{Hash, L2Level, RawTransaction, RawTransactions}; use crate::wei::Wei; use primitive_types::U256; @@ -29,7 +29,7 @@ const EVM_BLOCKS_NUMBER: RefPath = RefPath::assert_from(b"/number"); const EVM_BLOCKS_HASH: RefPath = RefPath::assert_from(b"/hash"); const EVM_BLOCKS_TRANSACTIONS: RefPath = RefPath::assert_from(b"/transactions"); -const CODE_HASH_SIZE: usize = 32; +const HASH_MAX_SIZE: usize = 32; /// The size of one 256 bit word. Size in bytes pub const WORD_SIZE: usize = 32usize; @@ -90,7 +90,7 @@ pub fn read_account_code_hash( account_path: &OwnedPath, ) -> Result, Error> { let path = concat(account_path, &EVM_ACCOUNT_CODE_HASH)?; - host.store_read(&path, 0, CODE_HASH_SIZE) + host.store_read(&path, 0, HASH_MAX_SIZE) .map_err(Error::from) } @@ -149,6 +149,35 @@ pub fn store_account( store_code_hash(host, &account_path, &account.code_hash) } +pub fn read_current_block_number( + host: &mut Host, +) -> Result { + let path = concat(&EVM_CURRENT_BLOCK, &EVM_BLOCKS_NUMBER)?; + let mut buffer = [0_u8; 8]; + + match load_value_slice(host, &path, &mut buffer) { + Ok(8) => Ok(u64::from_le_bytes(buffer)), + _ => Err(Error::Generic), + } +} + +fn read_current_block_transactions( + host: &mut Host, +) -> Result { + let path = concat(&EVM_CURRENT_BLOCK, &EVM_BLOCKS_TRANSACTIONS)?; + host.store_read(&path, 0, HASH_MAX_SIZE) + .map_err(Error::from) +} + +pub fn read_current_block( + host: &mut Host, +) -> Result { + let number = read_current_block_number(host)?; + let transactions = vec![read_current_block_transactions(host)?]; + + Ok(L2Block::new(number, transactions)) +} + fn store_block_number( host: &mut Host, block_path: &OwnedPath,