diff --git a/benches/loop.rs b/benches/loop.rs index b9ca7ae78..687a9a13f 100644 --- a/benches/loop.rs +++ b/benches/loop.rs @@ -20,17 +20,18 @@ fn run_loop_contract() { chain_id: U256::one(), block_base_fee_per_gas: U256::zero(), block_randomness: None, + blob_base_fee: None, }; let mut state = BTreeMap::new(); state.insert( H160::from_str("0x1000000000000000000000000000000000000000").unwrap(), MemoryAccount { - nonce: U256::one(), - balance: U256::from(10000000), - storage: BTreeMap::new(), - code: hex::decode("6080604052348015600f57600080fd5b506004361060285760003560e01c80630f14a40614602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b6000806000905060005b83811015608f5760018201915080806001019150506076565b508091505091905056fea26469706673582212202bc9ec597249a9700278fe4ce78da83273cb236e76d4d6797b441454784f901d64736f6c63430007040033").unwrap(), - } + nonce: U256::one(), + balance: U256::from(10000000), + storage: BTreeMap::new(), + code: hex::decode("6080604052348015600f57600080fd5b506004361060285760003560e01c80630f14a40614602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b6000806000905060005b83811015608f5760018201915080806001019150506076565b508091505091905056fea26469706673582212202bc9ec597249a9700278fe4ce78da83273cb236e76d4d6797b441454784f901d64736f6c63430007040033").unwrap(), + }, ); state.insert( H160::from_str("0xf000000000000000000000000000000000000000").unwrap(), diff --git a/evm-tests/ethjson/src/vm.rs b/evm-tests/ethjson/src/vm.rs index f028c6c10..71406a07b 100644 --- a/evm-tests/ethjson/src/vm.rs +++ b/evm-tests/ethjson/src/vm.rs @@ -125,6 +125,9 @@ pub struct Env { #[serde(rename = "currentRandom")] #[serde(default)] pub random: Option, + /// EIP-7516: Blob base fee + #[serde(default)] + pub blob_base_fee: Option, } #[cfg(test)] @@ -199,6 +202,7 @@ mod tests { timestamp: Uint(1.into()), block_base_fee_per_gas: Uint(0.into()), random: Some(Uint(1.into())), + blob_base_fee: None, } ); assert_eq!( diff --git a/evm-tests/jsontests/src/state.rs b/evm-tests/jsontests/src/state.rs index a846ff8c2..c468fe038 100644 --- a/evm-tests/jsontests/src/state.rs +++ b/evm-tests/jsontests/src/state.rs @@ -97,6 +97,7 @@ impl Test { chain_id: U256::one(), block_base_fee_per_gas, block_randomness, + blob_base_fee: self.0.env.blob_base_fee, }) } } diff --git a/evm-tests/jsontests/src/vm.rs b/evm-tests/jsontests/src/vm.rs index cc0d69b5d..5d388399e 100644 --- a/evm-tests/jsontests/src/vm.rs +++ b/evm-tests/jsontests/src/vm.rs @@ -41,6 +41,7 @@ impl Test { chain_id: U256::zero(), block_base_fee_per_gas: self.0.transaction.gas_price.into(), block_randomness, + blob_base_fee: None, } } diff --git a/runtime/src/eval/system.rs b/runtime/src/eval/system.rs index 829651d85..7161c8476 100644 --- a/runtime/src/eval/system.rs +++ b/runtime/src/eval/system.rs @@ -86,16 +86,19 @@ pub fn gasprice(runtime: &mut Runtime, handler: &H) -> Control { } pub fn base_fee(runtime: &mut Runtime, handler: &H) -> Control { - let mut ret = H256::default(); - handler.block_base_fee_per_gas().to_big_endian(&mut ret[..]); - push_h256!(runtime, ret); - + // let mut ret = H256::default(); + // handler.block_base_fee_per_gas().to_big_endian(&mut ret[..]); + push_u256!(runtime, handler.block_base_fee_per_gas()); Control::Continue } -pub fn blob_base_fee(_runtime: &mut Runtime, _handler: &H) -> Control { - // CANCUN - todo!() +/// CANCUN hard fork +/// EIP-7516: BLOBBASEFEE opcode +pub fn blob_base_fee(runtime: &mut Runtime, handler: &H) -> Control { + let x = handler.blob_base_fee().unwrap_or_default(); + let ret = U256::from(x); + push_u256!(runtime, ret); + Control::Continue } pub fn blob_hash(_runtime: &mut Runtime, _handler: &H) -> Control { diff --git a/runtime/src/handler.rs b/runtime/src/handler.rs index 4f15d9a3d..3982a4cff 100644 --- a/runtime/src/handler.rs +++ b/runtime/src/handler.rs @@ -14,7 +14,7 @@ pub struct Transfer { } /// EVM context handler. -#[auto_impl::auto_impl(&mut, Box)] +#[auto_impl::auto_impl(& mut, Box)] pub trait Handler { /// Type of `CREATE` interrupt. type CreateInterrupt; @@ -117,4 +117,10 @@ pub trait Handler { /// Records some associated `ExternalOperation`. fn record_external_operation(&mut self, op: crate::ExternalOperation) -> Result<(), ExitError>; + + /// Returns `None` if `Cancun` is not enabled. + /// CANCUN hard fork. + /// [EIP-4844]: Shard Blob Transactions + /// [EIP-7516]: BLOBBASEFEE instruction + fn blob_base_fee(&self) -> Option; } diff --git a/src/backend/memory.rs b/src/backend/memory.rs index f37fceda1..5894b7cd6 100644 --- a/src/backend/memory.rs +++ b/src/backend/memory.rs @@ -29,12 +29,18 @@ pub struct MemoryVicinity { /// Environmental block gas limit. pub block_gas_limit: U256, /// Environmental base fee per gas. + /// pub block_base_fee_per_gas: U256, /// Environmental randomness. /// /// In Ethereum, this is the randomness beacon provided by the beacon /// chain and is only enabled post Merge. pub block_randomness: Option, + /// Environmental blob base fee per gas. + /// CANCUN hard fork + /// [EIP-4844]: Shard Blob Transactions + /// [EIP-7516]: BLOBBASEFEE instruction + pub blob_base_fee: Option, } /// Account information of a memory backend. @@ -159,6 +165,9 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> { fn original_storage(&self, address: H160, index: H256) -> Option { Some(self.storage(address, index)) } + fn blob_base_fee(&self) -> Option { + self.vicinity.blob_base_fee + } } impl<'vicinity> ApplyBackend for MemoryBackend<'vicinity> { diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 728b92376..a2531eadc 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -84,6 +84,9 @@ pub trait Backend { fn storage(&self, address: H160, index: H256) -> H256; /// Get original storage value of address at index, if available. fn original_storage(&self, address: H160, index: H256) -> Option; + /// [EIP-4844]: Shard Blob Transactions + /// [EIP-7516]: BLOBBASEFEE instruction + fn blob_base_fee(&self) -> Option; } /// EVM backend that can apply changes. diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index d392e701c..d4a614cb5 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -1463,6 +1463,19 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler fn record_external_operation(&mut self, op: crate::ExternalOperation) -> Result<(), ExitError> { self.state.record_external_operation(op) } + + /// Returns `None` if `Cancun` hard fork is not enabled + /// via `has_blob_base_fee` config. + /// + /// [EIP-4844]: Shard Blob Transactions + /// [EIP-7516]: BLOBBASEFEE instruction + fn blob_base_fee(&self) -> Option { + if self.config.has_blob_base_fee { + self.state.blob_base_fee() + } else { + None + } + } } struct StackExecutorHandle<'inner, 'config, 'precompiles, S, P> { diff --git a/src/executor/stack/memory.rs b/src/executor/stack/memory.rs index 78a5a822c..f981ff16e 100644 --- a/src/executor/stack/memory.rs +++ b/src/executor/stack/memory.rs @@ -485,6 +485,9 @@ impl<'backend, 'config, B: Backend> Backend for MemoryStackState<'backend, 'conf self.backend.original_storage(address, key) } + fn blob_base_fee(&self) -> Option { + self.backend.blob_base_fee() + } } impl<'backend, 'config, B: Backend> StackState<'config> for MemoryStackState<'backend, 'config, B> {