diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index acfa7c92d6c8aefb3c43a615a0c75d9be0e4ebca..3593f0bbd148c054486400cca344b021da346d5a 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -34,6 +34,7 @@ use tezos_evm_logging::{log, Level::*, Verbosity}; use tezos_evm_runtime::runtime::Runtime; use tezos_evm_runtime::safe_storage::SafeStorage; use tezos_smart_rollup::outbox::OutboxQueue; +use tezos_smart_rollup::types::Timestamp; use tezos_smart_rollup_host::path::Path; use tick_model::estimate_remaining_ticks_for_transaction_execution; @@ -245,16 +246,24 @@ enum BlueprintParsing { } #[cfg_attr(feature = "benchmark", inline(never))] +#[allow(clippy::too_many_arguments)] fn next_bip_from_blueprints( host: &mut Host, current_block_number: U256, current_block_parent_hash: H256, + previous_timestamp: Timestamp, tick_counter: &TickCounter, config: &mut Configuration, kernel_upgrade: &Option, minimum_base_fee_per_gas: U256, ) -> Result { - let (blueprint, size) = read_blueprint(host, config, current_block_number)?; + let (blueprint, size) = read_blueprint( + host, + config, + current_block_number, + current_block_parent_hash, + previous_timestamp, + )?; log!(host, Benchmarking, "Size of blueprint: {}", size); match blueprint { Some(blueprint) => { @@ -455,16 +464,24 @@ pub fn produce( let ( current_block_number, current_block_parent_hash, + previous_timestamp, previous_receipts_root, previous_transactions_root, ) = match block_storage::read_current(host) { Ok(block) => ( block.number + 1, block.hash, + block.timestamp, block.receipts_root, block.transactions_root, ), - Err(_) => (U256::zero(), GENESIS_PARENT_HASH, vec![0; 32], vec![0; 32]), + Err(_) => ( + U256::zero(), + GENESIS_PARENT_HASH, + Timestamp::from(0), + vec![0; 32], + vec![0; 32], + ), }; let mut evm_account_storage = init_account_storage().context("Failed to initialize EVM account storage")?; @@ -493,6 +510,7 @@ pub fn produce( safe_host.host, current_block_number, current_block_parent_hash, + previous_timestamp, &tick_counter, config, &kernel_upgrade, diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 0548f72af084bbbd90e864d145fcf0d9cd1ba87b..2f566a4095f3b9acc1a031e9d28842b83a744f1d 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -3,7 +3,6 @@ // // SPDX-License-Identifier: MIT -use crate::block::GENESIS_PARENT_HASH; use crate::block_storage; use crate::blueprint::Blueprint; use crate::configuration::{Configuration, ConfigurationMode}; @@ -14,7 +13,7 @@ use crate::sequencer_blueprint::{ }; use crate::storage::read_last_info_per_level_timestamp; use crate::{delayed_inbox, DelayedInbox}; -use primitive_types::U256; +use primitive_types::{H256, U256}; use rlp::{Decodable, DecoderError, Encodable}; use sha3::{Digest, Keccak256}; use tezos_ethereum::rlp_helpers; @@ -268,6 +267,7 @@ fn fetch_delayed_txs( // wish to refuse such blueprints. pub const DEFAULT_MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: i64 = 300i64; +#[allow(clippy::too_many_arguments)] fn parse_and_validate_blueprint( host: &mut Host, bytes: &[u8], @@ -275,20 +275,16 @@ fn parse_and_validate_blueprint( current_blueprint_size: usize, evm_node_flag: bool, max_blueprint_lookahead_in_seconds: i64, + parent_hash: H256, + head_timestamp: Timestamp, ) -> anyhow::Result<(BlueprintValidity, usize)> { // Decode match rlp::decode::(bytes) { Err(e) => Ok((BlueprintValidity::DecoderError(e), bytes.len())), Ok(blueprint_with_hashes) => { - let head = block_storage::read_current(host); - let (head_hash, head_timestamp) = match head { - Ok(block) => (block.hash, block.timestamp), - Err(_) => (GENESIS_PARENT_HASH, Timestamp::from(0)), - }; - // Validate parent hash #[cfg(not(feature = "benchmark"))] - if head_hash != blueprint_with_hashes.parent_hash { + if parent_hash != blueprint_with_hashes.parent_hash { return Ok((BlueprintValidity::InvalidParentHash, bytes.len())); } @@ -364,6 +360,8 @@ fn read_all_chunks_and_validate( blueprint_path: &OwnedPath, nb_chunks: u16, config: &mut Configuration, + parent_hash: H256, + previous_timestamp: Timestamp, ) -> anyhow::Result<(Option, usize)> { let mut chunks = vec![]; let mut size = 0; @@ -404,6 +402,8 @@ fn read_all_chunks_and_validate( size, *evm_node_flag, *max_blueprint_lookahead_in_seconds, + parent_hash, + previous_timestamp, )?; if let (BlueprintValidity::Valid(blueprint), size_with_delayed_transactions) = validity @@ -427,6 +427,8 @@ pub fn read_blueprint( host: &mut Host, config: &mut Configuration, number: U256, + parent_hash: H256, + previous_timestamp: Timestamp, ) -> anyhow::Result<(Option, usize)> { let blueprint_path = blueprint_path(number)?; let exists = host.store_has(&blueprint_path)?.is_some(); @@ -442,8 +444,14 @@ pub fn read_blueprint( let available_chunks = n_subkeys as u16 - 1; if available_chunks == nb_chunks { // All chunks are available - let (blueprint, size) = - read_all_chunks_and_validate(host, &blueprint_path, nb_chunks, config)?; + let (blueprint, size) = read_all_chunks_and_validate( + host, + &blueprint_path, + nb_chunks, + config, + parent_hash, + previous_timestamp, + )?; Ok((blueprint, size)) } else { if available_chunks > nb_chunks { @@ -473,8 +481,16 @@ pub fn read_next_blueprint( host: &mut Host, config: &mut Configuration, ) -> anyhow::Result<(Option, usize)> { - let number = read_next_blueprint_number(host)?; - read_blueprint(host, config, number) + let (number, parent_hash, previous_timestamp) = + match block_storage::read_current(host) { + Ok(block) => (block.number + 1, block.hash, block.timestamp), + Err(_) => ( + U256::zero(), + crate::block::GENESIS_PARENT_HASH, + Timestamp::from(0), + ), + }; + read_blueprint(host, config, number, parent_hash, previous_timestamp) } pub fn drop_blueprint(host: &mut Host, number: U256) -> Result<(), Error> { @@ -494,6 +510,7 @@ pub fn clear_all_blueprints(host: &mut Host) -> Result<(), Error> mod tests { use super::*; + use crate::block::GENESIS_PARENT_HASH; use crate::configuration::{DalConfiguration, Limits, TezosContracts}; use crate::delayed_inbox::Hash; use crate::storage::store_last_info_per_level_timestamp; @@ -575,6 +592,8 @@ mod tests { 0, false, 500, + GENESIS_PARENT_HASH, + Timestamp::from(0), ) .expect("Should be able to parse blueprint"); assert_eq!( @@ -635,6 +654,8 @@ mod tests { 0, false, 500, + GENESIS_PARENT_HASH, + Timestamp::from(0), ) .expect("Should be able to parse blueprint"); assert_eq!(validity.0, BlueprintValidity::InvalidParentHash); diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index 119b5da0498d7b41c80eedd7ab58c4f1fee0f6ca..eba15df16691ce350f8b756df55fa880793a2c7f 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -226,7 +226,9 @@ mod tests { use crate::{ block_storage::internal_for_tests::store_current_number, - blueprint_storage::read_next_blueprint, dal::tests::*, parsing::RollupType, + blueprint_storage::{read_blueprint, read_next_blueprint}, + dal::tests::*, + parsing::RollupType, }; use super::*; @@ -495,11 +497,16 @@ mod tests { fetch_blueprints(&mut host, DEFAULT_SR_ADDRESS, &mut conf).expect("fetch failed"); // The dummy chunk in the inbox is registered at block 10 - store_current_number(&mut host, U256::from(9)).unwrap(); - if read_next_blueprint(&mut host, &mut conf) - .expect("Blueprint reading shouldn't fail") - .0 - .is_none() + if read_blueprint( + &mut host, + &mut conf, + U256::from(10), + crate::block::GENESIS_PARENT_HASH, + Timestamp::from(0), + ) + .expect("Blueprint reading shouldn't fail") + .0 + .is_none() { panic!("There should be a blueprint") }