From 86cd5c8ac801f951fdcab978a468e0a6c7064a9b Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Fri, 24 Feb 2023 16:53:32 +0100 Subject: [PATCH 1/6] EVM/Mockup: convenient generic ethereum types --- src/kernel_evm_mockup/src/eth_gen.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/kernel_evm_mockup/src/eth_gen.rs diff --git a/src/kernel_evm_mockup/src/eth_gen.rs b/src/kernel_evm_mockup/src/eth_gen.rs new file mode 100644 index 000000000000..95deac0ada9d --- /dev/null +++ b/src/kernel_evm_mockup/src/eth_gen.rs @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: 2023 Nomadic Labs +// +// SPDX-License-Identifier: MIT + +pub type RawTransaction = Vec; +pub type RawTransactions = Vec; +pub type L2Level = u64; +pub type Quantity = u64; -- GitLab From bb2d62add5b3da63ab64c6159fb0c2fa14cf3773 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 27 Feb 2023 11:22:55 +0100 Subject: [PATCH 2/6] EVM/Mockup: move OwnedHash and Hash into eth_gen --- src/kernel_evm_mockup/src/account.rs | 7 ++----- src/kernel_evm_mockup/src/eth_gen.rs | 2 ++ src/kernel_evm_mockup/src/storage.rs | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel_evm_mockup/src/account.rs b/src/kernel_evm_mockup/src/account.rs index edd304e315c5..ab8379f302dc 100644 --- a/src/kernel_evm_mockup/src/account.rs +++ b/src/kernel_evm_mockup/src/account.rs @@ -2,17 +2,14 @@ // // SPDX-License-Identifier: MIT +use crate::eth_gen::{OwnedHash, Quantity}; use crate::wei::Wei; -pub type OwnedHash = Vec; - -pub type Hash<'a> = &'a Vec; - // Simple representation of an account, only contains fixed-sized values (no // code nor storage). pub struct Account { pub hash: OwnedHash, - pub nonce: u64, // initially 0, updated after each transaction + pub nonce: Quantity, // initially 0, updated after each transaction pub balance: Wei, pub code_hash: OwnedHash, // 256 bits hash } diff --git a/src/kernel_evm_mockup/src/eth_gen.rs b/src/kernel_evm_mockup/src/eth_gen.rs index 95deac0ada9d..766bed10558f 100644 --- a/src/kernel_evm_mockup/src/eth_gen.rs +++ b/src/kernel_evm_mockup/src/eth_gen.rs @@ -6,3 +6,5 @@ pub type RawTransaction = Vec; pub type RawTransactions = Vec; pub type L2Level = u64; pub type Quantity = u64; +pub type OwnedHash = Vec; +pub type Hash<'a> = &'a Vec; diff --git a/src/kernel_evm_mockup/src/storage.rs b/src/kernel_evm_mockup/src/storage.rs index 38219c5ec68e..56fcc5cb3e63 100644 --- a/src/kernel_evm_mockup/src/storage.rs +++ b/src/kernel_evm_mockup/src/storage.rs @@ -11,6 +11,7 @@ use std::str::from_utf8; use crate::account::*; use crate::error::Error; +use crate::eth_gen::Hash; use crate::wei::Wei; use primitive_types::U256; -- GitLab From 2511b78dc0c77301fc0e424f7a819cf501068a00 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Fri, 24 Feb 2023 16:55:11 +0100 Subject: [PATCH 3/6] EVM/Mockup: expose eth_gen in lib and readapt inbox Transaction structure --- src/kernel_evm_mockup/src/inbox.rs | 4 +++- src/kernel_evm_mockup/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/kernel_evm_mockup/src/inbox.rs b/src/kernel_evm_mockup/src/inbox.rs index 657e458f91fc..afe5ecc54a43 100644 --- a/src/kernel_evm_mockup/src/inbox.rs +++ b/src/kernel_evm_mockup/src/inbox.rs @@ -9,9 +9,11 @@ use host::input::Message; use host::rollup_core::RawRollupCore; use host::runtime::Runtime; +use crate::eth_gen::RawTransaction; + pub struct Transaction { pub level: i32, - pub tx: Vec, + pub tx: RawTransaction, } pub enum Error { diff --git a/src/kernel_evm_mockup/src/lib.rs b/src/kernel_evm_mockup/src/lib.rs index c1d5438f1429..6c96769b67b5 100644 --- a/src/kernel_evm_mockup/src/lib.rs +++ b/src/kernel_evm_mockup/src/lib.rs @@ -17,6 +17,7 @@ use crate::wei::{from_eth, Wei}; mod account; mod blueprint; mod error; +mod eth_gen; mod inbox; mod storage; mod wei; -- GitLab From 3f3c829c1868eab76dce21c5236abc8d9976ce3b Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Fri, 24 Feb 2023 13:45:54 +0100 Subject: [PATCH 4/6] EVM/Mockup: L2 Block prototype representation + expose blocks in lib --- src/kernel_evm_mockup/src/block.rs | 67 ++++++++++++++++++++++++++++++ src/kernel_evm_mockup/src/lib.rs | 1 + 2 files changed, 68 insertions(+) create mode 100644 src/kernel_evm_mockup/src/block.rs diff --git a/src/kernel_evm_mockup/src/block.rs b/src/kernel_evm_mockup/src/block.rs new file mode 100644 index 000000000000..812463cf3773 --- /dev/null +++ b/src/kernel_evm_mockup/src/block.rs @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2023 Nomadic Labs +// +// SPDX-License-Identifier: MIT + +use crate::eth_gen::{L2Level, OwnedHash, Quantity, RawTransactions}; + +pub struct L2Block { + // This choice of a L2 block representation is totally + // arbitrarily based on what is an Ethereum block and is + // subject to change. + pub number: L2Level, + pub hash: OwnedHash, // 32 bytes + pub parent_hash: OwnedHash, + pub nonce: Quantity, + pub sha3_uncles: OwnedHash, + pub logs_bloom: Option, + pub transactions_root: OwnedHash, + pub state_root: OwnedHash, + pub receipts_root: OwnedHash, + pub miner: OwnedHash, + pub difficulty: Quantity, + pub total_difficulty: Quantity, + pub extra_data: OwnedHash, + pub size: Quantity, + pub gas_limit: Quantity, + pub gas_used: Quantity, + pub timestamp: Quantity, + pub transactions: RawTransactions, + pub uncles: Vec, +} + +impl L2Block { + // dead code is allowed in this implementation because the following constants + // are not used outside the scope of L2Block + #![allow(dead_code)] + + const DUMMY_QUANTITY: Quantity = 0; + const DUMMY_HASH: &str = "0000000000000000000000000000000000000000"; + + fn dummy_hash() -> OwnedHash { + L2Block::DUMMY_HASH.into() + } + + pub fn new(number: L2Level, hash: OwnedHash, transactions: RawTransactions) -> Self { + L2Block { + number, + hash, + parent_hash: L2Block::dummy_hash(), + nonce: L2Block::DUMMY_QUANTITY, + sha3_uncles: L2Block::dummy_hash(), + logs_bloom: None, + transactions_root: L2Block::dummy_hash(), + state_root: L2Block::dummy_hash(), + receipts_root: L2Block::dummy_hash(), + miner: L2Block::dummy_hash(), + difficulty: L2Block::DUMMY_QUANTITY, + total_difficulty: L2Block::DUMMY_QUANTITY, + extra_data: L2Block::dummy_hash(), + size: L2Block::DUMMY_QUANTITY, + gas_limit: L2Block::DUMMY_QUANTITY, + gas_used: L2Block::DUMMY_QUANTITY, + timestamp: L2Block::DUMMY_QUANTITY, + transactions, + uncles: Vec::new(), + } + } +} diff --git a/src/kernel_evm_mockup/src/lib.rs b/src/kernel_evm_mockup/src/lib.rs index 6c96769b67b5..053c037c8b36 100644 --- a/src/kernel_evm_mockup/src/lib.rs +++ b/src/kernel_evm_mockup/src/lib.rs @@ -15,6 +15,7 @@ use crate::storage::store_account; use crate::wei::{from_eth, Wei}; mod account; +mod block; mod blueprint; mod error; mod eth_gen; -- GitLab From a0fc4474bd7183ea4d82982989233e00fca302c9 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 27 Feb 2023 11:32:05 +0100 Subject: [PATCH 5/6] EVM/Mockup: store block in storage --- src/kernel_evm_mockup/src/storage.rs | 76 +++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/kernel_evm_mockup/src/storage.rs b/src/kernel_evm_mockup/src/storage.rs index 56fcc5cb3e63..6cb002e5da02 100644 --- a/src/kernel_evm_mockup/src/storage.rs +++ b/src/kernel_evm_mockup/src/storage.rs @@ -10,8 +10,9 @@ use host::runtime::{load_value_slice, Runtime}; use std::str::from_utf8; use crate::account::*; +use crate::block::L2Block; use crate::error::Error; -use crate::eth_gen::Hash; +use crate::eth_gen::{Hash, L2Level, RawTransactions}; use crate::wei::Wei; use primitive_types::U256; @@ -22,6 +23,12 @@ const EVM_ACCOUNT_BALANCE: RefPath = RefPath::assert_from(b"/balance"); const EVM_ACCOUNT_NONCE: RefPath = RefPath::assert_from(b"/nonce"); const EVM_ACCOUNT_CODE_HASH: RefPath = RefPath::assert_from(b"/code_hash"); +const EVM_CURRENT_BLOCK: RefPath = RefPath::assert_from(b"/evm/blocks/current"); +const EVM_BLOCKS: RefPath = RefPath::assert_from(b"/evm/blocks"); +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; /// The size of one 256 bit word. Size in bytes @@ -50,6 +57,13 @@ pub fn account_path(address: Hash) -> Result { concat(&EVM_ACCOUNTS, &address_hash).map_err(Error::from) } +fn block_path(number: L2Level) -> Result { + let number: &str = &number.to_string(); + let raw_number_path: Vec = format!("/{}", &number).into(); + let number_path = OwnedPath::try_from(raw_number_path).map_err(Error::from)?; + concat(&EVM_BLOCKS, &number_path).map_err(Error::from) +} + pub fn read_account_nonce( host: &mut Host, account_path: &OwnedPath, @@ -134,3 +148,63 @@ pub fn store_account( store_balance(host, &account_path, account.balance)?; store_code_hash(host, &account_path, &account.code_hash) } + +fn store_block_number( + host: &mut Host, + block_path: &OwnedPath, + block_number: L2Level, +) -> Result<(), Error> { + let path = concat(block_path, &EVM_BLOCKS_NUMBER)?; + host.store_write(&path, &u64::to_le_bytes(block_number), 0) + .map_err(Error::from) +} + +fn store_block_hash( + host: &mut Host, + block_path: &OwnedPath, + block_hash: Hash, +) -> Result<(), Error> { + let path = concat(block_path, &EVM_BLOCKS_HASH)?; + host.store_write(&path, block_hash, 0).map_err(Error::from) +} + +fn store_block_transactions( + host: &mut Host, + block_path: &OwnedPath, + block_transactions: &RawTransactions, +) -> Result<(), Error> { + let path = concat(block_path, &EVM_BLOCKS_TRANSACTIONS)?; + /* For now, to keep it simple we made the assumption that ONE BLOCK = ONE TRANSACTION, + this is why the following code make sense in this case: */ + let transaction = &block_transactions[0]; + host.store_write(&path, transaction, 0).map_err(Error::from) +} + +fn store_block( + host: &mut Host, + block: &L2Block, + block_path: OwnedPath, +) -> Result<(), Error> { + store_block_number(host, &block_path, block.number)?; + store_block_hash(host, &block_path, &block.hash)?; + store_block_transactions(host, &block_path, &block.transactions) +} + +pub fn store_block_by_number( + host: &mut Host, + block: &L2Block, +) -> Result<(), Error> { + let block_path = block_path(block.number)?; + store_block(host, block, block_path) +} + +pub fn store_current_block( + host: &mut Host, + block: L2Block, +) -> Result<(), Error> { + let current_block_path = OwnedPath::from(EVM_CURRENT_BLOCK); + store_block(host, &block, current_block_path)?; + /* When storing the current block's infos we need to store it under the [evm/blocks/] + path as well, thus the following line: */ + store_block_by_number(host, &block) +} -- GitLab From 2b701731f21f631274c1a4a3b467bf09399e5f84 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 27 Feb 2023 11:33:26 +0100 Subject: [PATCH 6/6] EVM/Mockup: remove unecessary exposure from storage functions --- src/kernel_evm_mockup/src/storage.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel_evm_mockup/src/storage.rs b/src/kernel_evm_mockup/src/storage.rs index 6cb002e5da02..ef6d0fb2352d 100644 --- a/src/kernel_evm_mockup/src/storage.rs +++ b/src/kernel_evm_mockup/src/storage.rs @@ -46,13 +46,13 @@ fn write_u256(host: &mut impl Runtime, path: &OwnedPath, value: U256) -> Result< host.store_write(path, &bytes, 0).map_err(Error::from) } -pub fn address_path(address: Hash) -> Result { +fn address_path(address: Hash) -> Result { let address: &str = from_utf8(address)?; let address_path: Vec = format!("/{}", &address).into(); OwnedPath::try_from(address_path).map_err(Error::from) } -pub fn account_path(address: Hash) -> Result { +fn account_path(address: Hash) -> Result { let address_hash = address_path(address)?; concat(&EVM_ACCOUNTS, &address_hash).map_err(Error::from) } @@ -111,7 +111,7 @@ pub fn read_account( }) } -pub fn store_nonce( +fn store_nonce( host: &mut Host, account_path: &OwnedPath, nonce: u64, @@ -121,7 +121,7 @@ pub fn store_nonce( .map_err(Error::from) } -pub fn store_balance( +fn store_balance( host: &mut Host, account_path: &OwnedPath, balance: Wei, @@ -130,7 +130,7 @@ pub fn store_balance( write_u256(host, &path, balance) } -pub fn store_code_hash( +fn store_code_hash( host: &mut Host, account_path: &OwnedPath, code_hash: Hash, -- GitLab