diff --git a/bin/reth/src/db.rs b/bin/reth/src/db.rs deleted file mode 100644 index ff555836555a..000000000000 --- a/bin/reth/src/db.rs +++ /dev/null @@ -1,461 +0,0 @@ -use std::{ - //collections::{hash_map::Entry, HashMap}, - str::FromStr, - sync::{Arc, Mutex, MutexGuard}, -}; - -use reth_primitives::{ - revm_primitives::{AccountInfo, Bytecode}, - Address, Bytes, SealedBlockWithSenders, B256, U256, -}; -use reth_provider::{bundle_state::StorageRevertsIter, OriginalValuesKnown}; -use reth_revm::db::{ - states::{PlainStorageChangeset, PlainStorageRevert}, - BundleState, -}; -use rusqlite::Connection; - - -/// Type used to initialize revms bundle state. -// type BundleStateInit = -// HashMap, Option, HashMap)>; - -// /// Types used inside RevertsInit to initialize revms reverts. -// pub(crate) type AccountRevertInit = (Option>, Vec); - -// /// Type used to initialize revms reverts. -// pub(crate) type RevertsInit = HashMap; - -pub(crate) struct Database { - connection: Arc>, -} - -impl Database { - /// Create new database with the provided connection. - pub(crate) fn new(connection: Connection) -> eyre::Result { - let database = Self { connection: Arc::new(Mutex::new(connection)) }; - database.create_tables()?; - Ok(database) - } - - fn connection(&self) -> MutexGuard<'_, Connection> { - self.connection.lock().expect("failed to acquire database lock") - } - - fn create_tables(&self) -> eyre::Result<()> { - self.connection().execute_batch( - "CREATE TABLE IF NOT EXISTS block ( - id INTEGER PRIMARY KEY, - number TEXT UNIQUE, - data TEXT - ); - CREATE TABLE IF NOT EXISTS account ( - id INTEGER PRIMARY KEY, - address TEXT UNIQUE, - data TEXT - ); - CREATE TABLE IF NOT EXISTS account_revert ( - id INTEGER PRIMARY KEY, - block_number TEXT, - address TEXT, - data TEXT, - UNIQUE (block_number, address) - ); - CREATE TABLE IF NOT EXISTS storage ( - id INTEGER PRIMARY KEY, - address TEXT, - key TEXT, - data TEXT, - UNIQUE (address, key) - ); - CREATE TABLE IF NOT EXISTS storage_revert ( - id INTEGER PRIMARY KEY, - block_number TEXT, - address TEXT, - key TEXT, - data TEXT, - UNIQUE (block_number, address, key) - ); - CREATE TABLE IF NOT EXISTS bytecode ( - id INTEGER PRIMARY KEY, - hash TEXT UNIQUE, - data TEXT - );", - )?; - Ok(()) - } - - /// Insert block with bundle into the database. - pub(crate) fn insert_block_with_bundle( - &self, - block: &SealedBlockWithSenders, - bundle: BundleState, - ) -> eyre::Result<()> { - let mut connection = self.connection(); - let tx = connection.transaction()?; - - tx.execute( - "INSERT INTO block (number, data) VALUES (?, ?)", - (block.header.number.to_string(), serde_json::to_string(block)?), - )?; - - let (changeset, reverts) = bundle.into_plain_state_and_reverts(OriginalValuesKnown::Yes); - - for (address, account) in changeset.accounts { - if let Some(account) = account { - tx.execute( - "INSERT INTO account (address, data) VALUES (?, ?) ON CONFLICT(address) DO UPDATE SET data = excluded.data", - (address.to_string(), serde_json::to_string(&account)?), - )?; - } else { - tx.execute("DELETE FROM account WHERE address = ?", (address.to_string(),))?; - } - } - - if reverts.accounts.len() > 1 { - eyre::bail!("too many blocks in account reverts"); - } - if let Some(account_reverts) = reverts.accounts.into_iter().next() { - for (address, account) in account_reverts { - tx.execute( - "INSERT INTO account_revert (block_number, address, data) VALUES (?, ?, ?) ON CONFLICT(block_number, address) DO UPDATE SET data = excluded.data", - (block.header.number.to_string(), address.to_string(), serde_json::to_string(&account)?), - )?; - } - } - - for PlainStorageChangeset { address, wipe_storage, storage } in changeset.storage { - if wipe_storage { - tx.execute("DELETE FROM storage WHERE address = ?", (address.to_string(),))?; - } - - for (key, data) in storage { - tx.execute( - "INSERT INTO storage (address, key, data) VALUES (?, ?, ?) ON CONFLICT(address, key) DO UPDATE SET data = excluded.data", - (address.to_string(), B256::from(key).to_string(), data.to_string()), - )?; - } - } - - if reverts.storage.len() > 1 { - eyre::bail!("too many blocks in storage reverts"); - } - if let Some(storage_reverts) = reverts.storage.into_iter().next() { - for PlainStorageRevert { address, wiped, storage_revert } in storage_reverts { - let storage = storage_revert - .into_iter() - .map(|(k, v)| (B256::new(k.to_be_bytes()), v)) - .collect::>(); - let wiped_storage = if wiped { get_storages(&tx, address)? } else { Vec::new() }; - for (key, data) in StorageRevertsIter::new(storage, wiped_storage) { - tx.execute( - "INSERT INTO storage_revert (block_number, address, key, data) VALUES (?, ?, ?, ?) ON CONFLICT(block_number, address, key) DO UPDATE SET data = excluded.data", - (block.header.number.to_string(), address.to_string(), key.to_string(), data.to_string()), - )?; - } - } - } - - for (hash, bytecode) in changeset.contracts { - tx.execute( - "INSERT INTO bytecode (hash, data) VALUES (?, ?) ON CONFLICT(hash) DO NOTHING", - (hash.to_string(), bytecode.bytecode().to_string()), - )?; - } - - tx.commit()?; - - Ok(()) - } - - /// Reverts the tip block from the database, checking it against the provided block number. - // /// - // /// The code is adapted from - // pub(crate) fn revert_tip_block(&self, block_number: U256) -> eyre::Result<()> { - // let mut connection = self.connection(); - // let tx = connection.transaction()?; - - // let tip_block_number = tx - // .query_row::( - // "SELECT number FROM block ORDER BY number DESC LIMIT 1", - // [], - // |row| row.get(0), - // ) - // .map(|data| U256::from_str(&data))??; - // if block_number != tip_block_number { - // eyre::bail!("Reverts can only be done from the tip. Attempted to revert block {} with tip block {}", block_number, tip_block_number); - // } - - // tx.execute("DELETE FROM block WHERE number = ?", (block_number.to_string(),))?; - - // let mut state = BundleStateInit::new(); - // let mut reverts = RevertsInit::new(); - - // let account_reverts = tx - // .prepare("SELECT address, data FROM account_revert WHERE block_number = ?")? - // .query((block_number.to_string(),))? - // .mapped(|row| { - // Ok(( - // Address::from_str(row.get_ref(0)?.as_str()?), - // serde_json::from_str::>(row.get_ref(1)?.as_str()?), - // )) - // }) - // .map(|result| { - // let (address, data) = result?; - // Ok((address?, data?)) - // }) - // .collect::>>()?; - - // for (address, old_info) in account_reverts { - // // insert old info into reverts - // reverts.entry(address).or_default().0 = Some(old_info.clone()); - - // match state.entry(address) { - // Entry::Vacant(entry) => { - // let new_info = get_account(&tx, address)?; - // entry.insert((old_info, new_info, HashMap::new())); - // } - // Entry::Occupied(mut entry) => { - // // overwrite old account state - // entry.get_mut().0 = old_info; - // } - // } - // } - - // let storage_reverts = tx - // .prepare("SELECT address, key, data FROM storage_revert WHERE block_number = ?")? - // .query((block_number.to_string(),))? - // .mapped(|row| { - // Ok(( - // Address::from_str(row.get_ref(0)?.as_str()?), - // B256::from_str(row.get_ref(1)?.as_str()?), - // U256::from_str(row.get_ref(2)?.as_str()?), - // )) - // }) - // .map(|result| { - // let (address, key, data) = result?; - // Ok((address?, key?, data?)) - // }) - // .collect::>>()?; - - // for (address, key, old_data) in storage_reverts.into_iter().rev() { - // let old_storage = StorageEntry { key, value: old_data }; - - // // insert old info into reverts - // reverts.entry(address).or_default().1.push(old_storage); - - // // get account state or insert from plain state - // let account_state = match state.entry(address) { - // Entry::Vacant(entry) => { - // let present_info = get_account(&tx, address)?; - // entry.insert((present_info.clone(), present_info, HashMap::new())) - // } - // Entry::Occupied(entry) => entry.into_mut(), - // }; - - // // match storage - // match account_state.2.entry(old_storage.key) { - // Entry::Vacant(entry) => { - // let new_value = get_storage(&tx, address, old_storage.key)?.unwrap_or_default(); - // entry.insert((old_storage.value, new_value)); - // } - // Entry::Occupied(mut entry) => { - // entry.get_mut().0 = old_storage.value; - // } - // }; - // } - - // // iterate over local plain state remove all account and all storages - // for (address, (old_account, new_account, storage)) in state { - // // revert account if needed - // if old_account != new_account { - // if let Some(account) = old_account { - // upsert_account(&tx, address, |_| Ok(account))?; - // } else { - // delete_account(&tx, address)?; - // } - // } - - // // revert storages - // for (storage_key, (old_storage_value, _new_storage_value)) in storage { - // // delete previous value - // delete_storage(&tx, address, storage_key)?; - - // // insert value if needed - // if !old_storage_value.is_zero() { - // upsert_storage(&tx, address, storage_key, old_storage_value)?; - // } - // } - // } - - // tx.commit()?; - - // Ok(()) - // } - - /// Get block by number. - pub(crate) fn get_block(&self, number: U256) -> eyre::Result> { - let block = self.connection().query_row::( - "SELECT data FROM block WHERE number = ?", - (number.to_string(),), - |row| row.get(0), - ); - match block { - Ok(data) => Ok(Some(serde_json::from_str(&data)?)), - Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None), - Err(e) => Err(e.into()), - } - } - - // /// Insert new account if it does not exist, update otherwise. The provided closure is called - // /// with the current account, if it exists. - // pub(crate) fn upsert_account( - // &self, - // address: Address, - // f: impl FnOnce(Option) -> eyre::Result, - // ) -> eyre::Result<()> { - // upsert_account(&self.connection(), address, f) - // } - - /// Get account by address. - pub(crate) fn get_account(&self, address: Address) -> eyre::Result> { - get_account(&self.connection(), address) - } -} - -// /// Insert new account if it does not exist, update otherwise. The provided closure is called -// /// with the current account, if it exists. Connection can be either -// /// [rusqlite::Transaction] or [rusqlite::Connection]. -// fn upsert_account( -// connection: &Connection, -// address: Address, -// f: impl FnOnce(Option) -> eyre::Result, -// ) -> eyre::Result<()> { -// let account = get_account(connection, address)?; -// let account = f(account)?; -// connection.execute( -// "INSERT INTO account (address, data) VALUES (?, ?) ON CONFLICT(address) DO UPDATE SET data = excluded.data", -// (address.to_string(), serde_json::to_string(&account)?), -// )?; - -// Ok(()) -// } - -// /// Delete account by address. Connection can be either [rusqlite::Transaction] or -// /// [rusqlite::Connection]. -// fn delete_account(connection: &Connection, address: Address) -> eyre::Result<()> { -// connection.execute("DELETE FROM account WHERE address = ?", (address.to_string(),))?; -// Ok(()) -// } - -/// Get account by address using the database connection. Connection can be either -/// [rusqlite::Transaction] or [rusqlite::Connection]. -fn get_account(connection: &Connection, address: Address) -> eyre::Result> { - match connection.query_row::( - "SELECT data FROM account WHERE address = ?", - (address.to_string(),), - |row| row.get(0), - ) { - Ok(account_info) => Ok(Some(serde_json::from_str(&account_info)?)), - Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None), - Err(e) => Err(e.into()), - } -} - -// /// Insert new storage if it does not exist, update otherwise. Connection can be either -// /// [rusqlite::Transaction] or [rusqlite::Connection]. -// fn upsert_storage( -// connection: &Connection, -// address: Address, -// key: B256, -// data: U256, -// ) -> eyre::Result<()> { -// connection.execute( -// "INSERT INTO storage (address, key, data) VALUES (?, ?, ?) ON CONFLICT(address, key) DO UPDATE SET data = excluded.data", -// (address.to_string(), key.to_string(), data.to_string()), -// )?; -// Ok(()) -// } - -// /// Delete storage by address and key. Connection can be either [rusqlite::Transaction] or -// /// [rusqlite::Connection]. -// fn delete_storage(connection: &Connection, address: Address, key: B256) -> eyre::Result<()> { -// connection.execute( -// "DELETE FROM storage WHERE address = ? AND key = ?", -// (address.to_string(), key.to_string()), -// )?; -// Ok(()) -// } - -/// Get all storages for the provided address using the database connection. Connection can be -/// either [rusqlite::Transaction] or [rusqlite::Connection]. -fn get_storages(connection: &Connection, address: Address) -> eyre::Result> { - connection - .prepare("SELECT key, data FROM storage WHERE address = ?")? - .query((address.to_string(),))? - .mapped(|row| { - Ok(( - B256::from_str(row.get_ref(0)?.as_str()?), - U256::from_str(row.get_ref(1)?.as_str()?), - )) - }) - .map(|result| { - let (key, data) = result?; - Ok((key?, data?)) - }) - .collect() -} - -/// Get storage for the provided address by key using the database connection. Connection can be -/// either [rusqlite::Transaction] or [rusqlite::Connection]. -fn get_storage(connection: &Connection, address: Address, key: B256) -> eyre::Result> { - match connection.query_row::( - "SELECT data FROM storage WHERE address = ? AND key = ?", - (address.to_string(), key.to_string()), - |row| row.get(0), - ) { - Ok(data) => Ok(Some(U256::from_str(&data)?)), - Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None), - Err(e) => Err(e.into()), - } -} - -impl reth_revm::Database for Database { - type Error = eyre::Report; - - fn basic(&mut self, address: Address) -> Result, Self::Error> { - self.get_account(address) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - let bytecode = self.connection().query_row::( - "SELECT data FROM bytecode WHERE hash = ?", - (code_hash.to_string(),), - |row| row.get(0), - ); - match bytecode { - Ok(data) => Ok(Bytecode::new_raw(Bytes::from_str(&data).unwrap())), - Err(rusqlite::Error::QueryReturnedNoRows) => Ok(Bytecode::default()), - Err(err) => Err(err.into()), - } - } - - fn storage(&mut self, address: Address, index: U256) -> Result { - get_storage(&self.connection(), address, index.into()).map(|data| data.unwrap_or_default()) - } - - fn block_hash(&mut self, number: u64) -> Result { - let block_hash = self.connection().query_row::( - "SELECT hash FROM block WHERE number = ?", - (number.to_string(),), - |row| row.get(0), - ); - match block_hash { - Ok(data) => Ok(B256::from_str(&data).unwrap()), - // No special handling for `QueryReturnedNoRows` is needed, because revm does block - // number bound checks on its own. - // See https://github.com/bluealloy/revm/blob/1ca3d39f6a9e9778f8eb0fcb74fe529345a531b4/crates/interpreter/src/instructions/host.rs#L106-L123. - Err(err) => Err(err.into()), - } - } -} diff --git a/bin/reth/src/execution.rs b/bin/reth/src/execution.rs deleted file mode 100644 index 82bebca0816d..000000000000 --- a/bin/reth/src/execution.rs +++ /dev/null @@ -1,485 +0,0 @@ -use crate::{db::Database, RollupContract, CHAIN_ID, CHAIN_SPEC}; -use alloy_consensus::{Blob, SidecarCoder, SimpleCoder}; -use alloy_rlp::Decodable as _; -use eyre::OptionExt; -use reth::transaction_pool::TransactionPool; -use reth_execution_errors::BlockValidationError; -use reth_node_api::{ConfigureEvm, ConfigureEvmEnv}; -use reth_node_ethereum::EthEvmConfig; -use reth_primitives::{ - constants, - eip4844::kzg_to_versioned_hash, - revm_primitives::{CfgEnvWithHandlerCfg, EVMError, ExecutionResult, ResultAndState}, - Address, Block, BlockWithSenders, Bytes, EthereumHardfork, Header, Receipt, TransactionSigned, - TxType, B256, U256, -}; -use reth_revm::{ - db::{states::bundle_state::BundleRetention, BundleState}, primitives::FixedBytes, DBBox, DatabaseCommit, Evm, StateBuilder, StateDBBox -}; -use reth_tracing::tracing::debug; - -/// Execute a rollup block and return (block with recovered senders)[BlockWithSenders], (bundle -/// state)[BundleState] and list of (receipts)[Receipt]. -pub(crate) async fn execute_block( - //db: &mut Database, - pool: &Pool, - tx: &TransactionSigned, - block_metadata: &RollupContract::BlockMetadata, - block_data: Bytes, - //block_data_hash: B256, -) -> eyre::Result<(BlockWithSenders/*, BundleState*/, Vec, Vec)> { - //if header.rollupChainId != U256::from(CHAIN_ID) { - // eyre::bail!("Invalid rollup chain ID") - //} - - // Construct header - let header = construct_header(block_metadata)?; - - // Decode transactions - let transactions = decode_transactions(pool, tx, block_data).await?; - println!("transactions: {:?}", transactions); - - // Configure EVM - let evm_config = EthEvmConfig::default(); - //let mut evm = configure_evm(&evm_config, db, &header); - - // Execute transactions - // let (executed_txs, receipts, results) = execute_transactions(&mut evm, &header, transactions)?; - // println!("executed_txs: {:?}", executed_txs); - - // // Construct block and recover senders - // let block = Block { header, body: executed_txs, ..Default::default() } - // .with_recovered_senders() - // .ok_or_eyre("failed to recover senders")?; - - - let block = BlockWithSenders::default(); - let receipts = Vec::new(); - let results = Vec::new(); - - //let bundle = evm.db_mut().take_bundle(); - - Ok((block/* , bundle*/, receipts, results)) -} - -/// Construct header from the given rollup header. -fn construct_header(meta_data: &RollupContract::BlockMetadata) -> eyre::Result
{ - //let parent_block = db.get_block((meta_data.l2BlockNumber - 1).try_into().unwrap())?; - - let block_number = u64::try_from(meta_data.l2BlockNumber)?; - - // Calculate base fee per gas for EIP-1559 transactions - let base_fee_per_gas = - //if CHAIN_SPEC.fork(EthereumHardfork::London).transitions_at_block(block_number) { - constants::EIP1559_INITIAL_BASE_FEE; - //} else { - // parent_block - // .as_ref() - // .ok_or(eyre::eyre!("parent block not found"))? - // .header - // .next_block_base_fee(CHAIN_SPEC.base_fee_params_at_block(block_number)) - // .ok_or(eyre::eyre!("failed to calculate base fee"))? - //}; - - // Construct header - Ok(Header { - //parent_hash: parent_block.map(|block| block.header.hash()).unwrap_or_default(), - parent_hash: B256::default(), - number: block_number, - gas_limit: u64::try_from(meta_data.gasLimit)?, - timestamp: u64::try_from(meta_data.timestamp)?, - base_fee_per_gas: Some(base_fee_per_gas), - ..Default::default() - }) -} - -/// Configure EVM with the given database and header. -fn configure_evm<'a>( - config: &'a EthEvmConfig, - db: &'a mut Database, - header: &Header, -) -> Evm<'a, (), StateDBBox<'a, eyre::Report>> { - let mut evm = config.evm( - StateBuilder::new_with_database(Box::new(db) as DBBox<'_, eyre::Report>) - .with_bundle_update() - .build(), - ); - evm.db_mut().set_state_clear_flag( - CHAIN_SPEC.fork(EthereumHardfork::SpuriousDragon).active_at_block(header.number), - ); - - let mut cfg = CfgEnvWithHandlerCfg::new_with_spec_id(evm.cfg().clone(), evm.spec_id()); - config.fill_cfg_and_block_env(&mut cfg, evm.block_mut(), &CHAIN_SPEC, header, U256::ZERO); - *evm.cfg_mut() = cfg.cfg_env; - - evm -} - -/// Decode transactions from the block data and recover senders. -/// - If the transaction is a blob-carrying one, decode the blobs either using the local transaction -/// pool, or querying Blobscan. -/// - If the transaction is a regular one, decode the block data directly. -async fn decode_transactions( - pool: &Pool, - tx: &TransactionSigned, - block_data: Bytes, - //block_data_hash: B256, -) -> eyre::Result> { - // Get raw transactions either from the blobs, or directly from the block data - let raw_transactions = if matches!(tx.tx_type(), TxType::Eip4844) { - let blobs: Vec<_> = if let Some(sidecar) = pool.get_blob(tx.hash)? { - // Try to get blobs from the transaction pool - sidecar.blobs.into_iter().zip(sidecar.commitments).collect() - } else { - // If transaction is not found in the pool, try to get blobs from Blobscan - let blobscan_client = foundry_blob_explorers::Client::holesky(); - let sidecar = blobscan_client.transaction(tx.hash).await?.blob_sidecar(); - sidecar - .blobs - .into_iter() - .map(|blob| (*blob).into()) - .zip(sidecar.commitments.into_iter().map(|commitment| (*commitment).into())) - .collect() - }; - - // Decode blob hashes from block data - let blob_hashes = Vec::::decode(&mut block_data.as_ref())?; - - // Filter blobs that are present in the block data - let blobs = blobs - .into_iter() - // Convert blob KZG commitments to versioned hashes - .map(|(blob, commitment)| (blob, kzg_to_versioned_hash(commitment.as_slice()))) - // Filter only blobs that are present in the block data - .filter(|(_, hash)| blob_hashes.contains(hash)) - .map(|(blob, _)| Blob::from(*blob)) - .collect::>(); - if blobs.len() != blob_hashes.len() { - eyre::bail!("some blobs not found") - } - - // Decode blobs and concatenate them to get the raw transactions - let data = SimpleCoder::default() - .decode_all(&blobs) - .ok_or(eyre::eyre!("failed to decode blobs"))? - .concat(); - - data.into() - } else { - block_data - }; - - //let raw_transaction_hash = keccak256(&raw_transactions); - //if raw_transaction_hash != block_data_hash { - // eyre::bail!("block data hash mismatch") - //} - - // Decode block data, filter only transactions with the correct chain ID and recover senders - let transactions = Vec::::decode(&mut raw_transactions.as_ref())? - .into_iter() - .filter(|tx| {println!("chain_id: {:?}", tx.chain_id()); tx.chain_id() == Some(CHAIN_ID) }) - .map(|tx| { - let sender = tx.recover_signer().ok_or(eyre::eyre!("failed to recover signer"))?; - Ok((tx, sender)) - }) - .collect::>()?; - - Ok(transactions) -} - -/// Execute transactions and return the list of executed transactions, receipts and -/// execution results. -fn execute_transactions( - evm: &mut Evm<'_, (), StateDBBox<'_, eyre::Report>>, - header: &Header, - transactions: Vec<(TransactionSigned, Address)>, -) -> eyre::Result<(Vec, Vec, Vec)> { - let mut receipts = Vec::with_capacity(transactions.len()); - let mut executed_txs = Vec::with_capacity(transactions.len()); - let mut results = Vec::with_capacity(transactions.len()); - if !transactions.is_empty() { - let mut cumulative_gas_used = 0; - for (transaction, sender) in transactions { - // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, - // must be no greater than the block’s gasLimit. - let block_available_gas = header.gas_limit - cumulative_gas_used; - if transaction.gas_limit() > block_available_gas { - return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { - transaction_gas_limit: transaction.gas_limit(), - block_available_gas, - } - .into()); - } - // Execute transaction. - // Fill revm structure. - EthEvmConfig::default().fill_tx_env(evm.tx_mut(), &transaction, sender); - - let ResultAndState { result, state } = match evm.transact() { - Ok(result) => result, - Err(err) => { - match err { - EVMError::Transaction(err) => { - // if the transaction is invalid, we can skip it - debug!(%err, ?transaction, "Skipping invalid transaction"); - continue; - } - err => { - // this is an error that we should treat as fatal for this attempt - eyre::bail!(err) - } - } - } - }; - - debug!(?transaction, ?result, ?state, "Executed transaction"); - - evm.db_mut().commit(state); - - // append gas used - cumulative_gas_used += result.gas_used(); - - // Push transaction changeset and calculate header bloom filter for receipt. - #[allow(clippy::needless_update)] // side-effect of optimism fields - receipts.push(Receipt { - tx_type: transaction.tx_type(), - success: result.is_success(), - cumulative_gas_used, - logs: result.logs().iter().cloned().map(Into::into).collect(), - ..Default::default() - }); - - // append transaction to the list of executed transactions - executed_txs.push(transaction); - results.push(result); - } - - evm.db_mut().merge_transitions(BundleRetention::Reverts); - } - - Ok((executed_txs, receipts, results)) -} - -/* -#[cfg(test)] -mod tests { - use std::time::{SystemTime, UNIX_EPOCH}; - - use alloy_consensus::{SidecarBuilder, SimpleCoder}; - use alloy_sol_types::{sol, SolCall}; - use reth::transaction_pool::{ - test_utils::{testing_pool, MockTransaction}, - TransactionOrigin, TransactionPool, - }; - use reth_primitives::{ - bytes, - constants::ETH_TO_WEI, - keccak256, public_key_to_address, - revm_primitives::{AccountInfo, ExecutionResult, Output, TxEnv}, - BlockNumber, Receipt, SealedBlockWithSenders, Transaction, TxEip2930, TxKind, U256, - }; - use reth_revm::Evm; - use reth_testing_utils::generators::{self, sign_tx_with_key_pair}; - use rusqlite::Connection; - use secp256k1::{Keypair, Secp256k1}; - - use crate::{ - db::Database, execute_block, RollupContract::BlockMetadata, CHAIN_ID, - ROLLUP_SUBMITTER_ADDRESS, - }; - - sol!( - WETH, - r#" -[ - { - "constant":true, - "inputs":[ - { - "name":"", - "type":"address" - } - ], - "name":"balanceOf", - "outputs":[ - { - "name":"", - "type":"uint256" - } - ], - "payable":false, - "stateMutability":"view", - "type":"function" - } -] - "# - ); - - #[tokio::test] - async fn test_execute_block() -> eyre::Result<()> { - reth_tracing::init_test_tracing(); - - let mut database = Database::new(Connection::open_in_memory()?)?; - - // Create key pair - let secp = Secp256k1::new(); - let key_pair = Keypair::new(&secp, &mut generators::rng()); - let sender_address = public_key_to_address(key_pair.public_key()); - - // Deposit some ETH to the sender and insert it into database - database.upsert_account(sender_address, |_| { - Ok(AccountInfo { balance: U256::from(ETH_TO_WEI), nonce: 1, ..Default::default() }) - })?; - - // WETH deployment transaction sent using calldata - let (_, _, results) = execute_transaction( - &mut database, - key_pair, - 0, - Transaction::Eip2930(TxEip2930 { - chain_id: CHAIN_ID, - nonce: 1, - gas_limit: 1_500_000, - gas_price: 1_500_000_000, - to: TxKind::Create, - // WETH9 bytecode - input: bytes!("60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029"), - ..Default::default() - }), - BlockDataSource::Calldata - ).await?; - - let weth_address = match results.first() { - Some(ExecutionResult::Success { output: Output::Create(_, Some(address)), .. }) => { - *address - } - _ => eyre::bail!("WETH contract address not found"), - }; - - // WETH deposit transaction sent using blobs - execute_transaction( - &mut database, - key_pair, - 1, - Transaction::Eip2930(TxEip2930 { - chain_id: CHAIN_ID, - nonce: 2, - gas_limit: 50000, - gas_price: 1_500_000_000, - to: TxKind::Call(weth_address), - value: U256::from(0.5 * ETH_TO_WEI as f64), - input: bytes!("d0e30db0"), - ..Default::default() - }), - BlockDataSource::Blobs, - ) - .await?; - - // Verify WETH balance - let mut evm = Evm::builder() - .with_db(&mut database) - .with_tx_env(TxEnv { - caller: sender_address, - gas_limit: 50_000_000, - transact_to: TxKind::Call(weth_address), - data: WETH::balanceOfCall::new((sender_address,)).abi_encode().into(), - ..Default::default() - }) - .build(); - let result = evm.transact().map_err(|err| eyre::eyre!(err))?.result; - assert_eq!( - result.output(), - Some(&U256::from(0.5 * ETH_TO_WEI as f64).to_be_bytes_vec().into()) - ); - drop(evm); - - // Verify nonce - let account = database.get_account(sender_address)?.unwrap(); - assert_eq!(account.nonce, 3); - - // Revert block with WETH deposit transaction - database.revert_tip_block(U256::from(1))?; - - // Verify WETH balance after revert - let mut evm = Evm::builder() - .with_db(&mut database) - .with_tx_env(TxEnv { - caller: sender_address, - gas_limit: 50_000_000, - transact_to: TxKind::Call(weth_address), - data: WETH::balanceOfCall::new((sender_address,)).abi_encode().into(), - ..Default::default() - }) - .build(); - let result = evm.transact().map_err(|err| eyre::eyre!(err))?.result; - assert_eq!(result.output(), Some(&U256::ZERO.to_be_bytes_vec().into())); - drop(evm); - - // Verify nonce after revert - let account = database.get_account(sender_address)?.unwrap(); - assert_eq!(account.nonce, 2); - - Ok(()) - } - - enum BlockDataSource { - Calldata, - Blobs, - } - - async fn execute_transaction( - database: &mut Database, - key_pair: Keypair, - sequence: BlockNumber, - tx: Transaction, - block_data_source: BlockDataSource, - ) -> eyre::Result<(SealedBlockWithSenders, Vec, Vec)> { - // Construct block header - /*let block_header = BlockHeader { - rollupChainId: U256::from(CHAIN_ID), - sequence: U256::from(sequence), - confirmBy: U256::from(SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs()), - gasLimit: U256::from(30_000_000), - rewardAddress: ROLLUP_SUBMITTER_ADDRESS, - };*/ - let encoded_transactions = - alloy_rlp::encode(vec![sign_tx_with_key_pair(key_pair, tx).envelope_encoded()]); - let block_data_hash = keccak256(&encoded_transactions); - - let pool = testing_pool(); - - let (block_data, l1_transaction) = match block_data_source { - BlockDataSource::Calldata => ( - encoded_transactions, - sign_tx_with_key_pair(key_pair, Transaction::Eip2930(TxEip2930::default())), - ), - BlockDataSource::Blobs => { - let sidecar = - SidecarBuilder::::from_slice(&encoded_transactions).build()?; - let blob_hashes = alloy_rlp::encode(sidecar.versioned_hashes().collect::>()); - - let mut mock_transaction = MockTransaction::eip4844_with_sidecar(sidecar); - let transaction = - sign_tx_with_key_pair(key_pair, Transaction::from(mock_transaction.clone())); - mock_transaction.set_hash(transaction.hash); - pool.add_transaction(TransactionOrigin::Local, mock_transaction).await?; - (blob_hashes, transaction) - } - }; - - // Execute block and insert into database - let (block, bundle, receipts, results) = execute_block( - database, - &pool, - &l1_transaction, - &block_header, - block_data.into(), - //block_data_hash, - ) - .await?; - let block = block.seal_slow(); - database.insert_block_with_bundle(&block, bundle)?; - - Ok((block, receipts, results)) - } -} -*/ \ No newline at end of file diff --git a/bin/reth/src/main.rs b/bin/reth/src/main.rs index b4fca0c61d90..93b7b233f532 100644 --- a/bin/reth/src/main.rs +++ b/bin/reth/src/main.rs @@ -30,13 +30,7 @@ fn main() { }*/ use alloy_sol_types::{sol, SolEventInterface, SolInterface}; -use db::Database; -use execution::execute_block; -use eyre::Error; -use network::NetworkTestContext; use node::NodeTestContext; -use once_cell::sync::Lazy; -use payload::PayloadTestContext; use reth::args::{DiscoveryArgs, NetworkArgs, RpcServerArgs}; use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET}; use reth_consensus::Consensus; @@ -48,27 +42,17 @@ use reth_node_api::{FullNodeTypesAdapter, NodeAddOns}; use reth_node_builder::{components::Components, rpc::EthApiBuilderProvider, AddOns, FullNode, Node, NodeAdapter, NodeBuilder, NodeComponentsBuilder, NodeConfig, NodeHandle, RethFullAdapter}; use reth_node_ethereum::{node::EthereumAddOns, EthEvmConfig, EthExecutorProvider, EthereumNode}; use reth_primitives::{address, alloy_primitives, Address, Genesis, SealedBlockWithSenders, TransactionSigned, B256}; -use reth_provider::{providers::BlockchainProvider, CanonStateSubscriptions}; +use reth_provider::providers::BlockchainProvider; use reth_rpc_api::{eth::{helpers::AddDevSigners, FullEthApiServer}, EngineApiClient}; use reth_tasks::TaskManager; -use reth_tracing::tracing::{error, info}; use reth_transaction_pool::{blobstore::DiskFileBlobStore, CoinbaseTipOrdering, EthPooledTransaction, EthTransactionValidator, Pool, TransactionValidationTaskExecutor}; -use rpc::RpcTestContext; -use rusqlite::Connection; -use transaction::TransactionTestContext; -use wallet::Wallet; use std::{future::Future, marker::PhantomData, pin::Pin, sync::Arc}; use alloy_rlp::Decodable; -//use alloy_primitives::{Address, B256}; use reth::rpc::types::engine::PayloadAttributes; -//use reth_e2e_test_utils::NodeHelperType; -//use reth_node_ethereum::{node::EthereumAddOns, EthereumNode}; use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; -mod db; -mod execution; mod network; mod payload; mod rpc; @@ -78,10 +62,6 @@ mod wallet; mod engine_api; mod traits; - -/// Ethereum Node Helper type -//pub(crate) type EthNode = NodeHelperType; - /// Helper function to create a new eth payload attributes pub(crate) fn eth_payload_attributes(timestamp: u64, transactions: Vec) -> EthPayloadBuilderAttributes { let attributes = PayloadAttributes { @@ -98,19 +78,8 @@ pub(crate) fn eth_payload_attributes(timestamp: u64, transactions: Vec> = Lazy::new(|| { - Arc::new( - ChainSpecBuilder::default() - .chain(CHAIN_ID.into()) - .genesis(Genesis::clique_genesis(CHAIN_ID, ROLLUP_SUBMITTER_ADDRESS)) - .shanghai_activated() - .build(), - ) -}); pub fn decode_transactions(tx_list: &[u8]) -> Vec { #[allow(clippy::useless_asref)] @@ -155,22 +124,6 @@ impl Rollup { let events = decode_chain_into_rollup_events(chain); println!("Found {:?} events", events.len()); - - // let (mut nodes, _tasks, _wallet) = setup::( - // 1, - // Arc::new( - // ChainSpecBuilder::default() - // .chain(MAINNET.chain) - // .genesis(serde_json::from_str(include_str!("../../../crates/ethereum/node/tests/assets/genesis.json")).unwrap()) - // .cancun_activated() - // .build(), - // ), - // false, - // ) - // .await?; - - // let node = nodes.pop().unwrap(); - for (_, tx, event) in events { match event { // A new block is submitted to the rollup contract. @@ -210,47 +163,7 @@ impl Rollup { self.node.assert_new_block(transactions[0].hash(), block_hash, block_number) }) }); - println!("assert_new_block done: {:?}", res); - - /*if let RollupContractCalls::submitBlock(RollupContract::submitBlockCall { - header, - blockData, - .. - }) = call - {*/ - match execute_block( - //&mut self.db, - self.ctx.pool(), - tx, - &block_metadata, - tx_list, - //blockDataHash, - ) - .await - { - Ok((block/*, bundle*/, _, _)) => { - let block = block.seal_slow(); - //self.db.insert_block_with_bundle(&block, bundle)?; - info!( - tx_hash = %tx.recalculate_hash(), - chain_id = %CHAIN_ID, - sequence = %block_metadata.l2BlockNumber, - transactions = block.body.len(), - "Block submitted, executed and inserted into database" - ); - } - Err(err) => { - error!( - %err, - tx_hash = %tx.recalculate_hash(), - chain_id = %CHAIN_ID, - sequence = %block_metadata.l2BlockNumber, - "Failed to execute block" - ); - } - } - //} } _ => (), } @@ -288,35 +201,6 @@ impl Rollup { ); } } - // The deposit is subtracted from the recipient's balance. - RollupContractEvents::Enter(RollupContract::Enter { - rollupChainId, - token, - rollupRecipient, - amount, - }) => { - if rollupChainId != U256::from(CHAIN_ID) { - error!(tx_hash = %tx.recalculate_hash(), "Invalid rollup chain ID"); - continue; - } - if token != Address::ZERO { - error!(tx_hash = %tx.recalculate_hash(), "Only ETH deposits are supported"); - continue; - } - - self.db.upsert_account(rollupRecipient, |account| { - let mut account = account.ok_or(eyre::eyre!("account not found"))?; - account.balance -= amount; - Ok(account) - })?; - - info!( - tx_hash = %tx.recalculate_hash(), - %amount, - recipient = %rollupRecipient, - "Deposit reverted", - ); - } _ => (), } }*/ @@ -375,35 +259,29 @@ type TestNodeContext = NodeTestContext = NodeTestContext, AO>; -/// Creates the initial setup with `num_nodes` started and interconnected. -pub async fn setup( - num_nodes: usize, - chain_spec: Arc, - is_dev: bool, -) -> eyre::Result<(Vec>, TaskManager, Wallet)> -where - N: Default + Node>, - >>::EthApi: - FullEthApiServer + AddDevSigners + EthApiBuilderProvider>, -{ - let tasks = TaskManager::current(); - let exec = tasks.executor(); - - let network_config = NetworkArgs { - discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() }, - ..NetworkArgs::default() - }; +fn main() -> eyre::Result<()> { + reth::cli::Cli::parse_args().run(|builder, _| async move { + // Create the L2 node + let tasks = TaskManager::current(); + let exec = tasks.executor(); - // Create nodes and peer them - let mut nodes: Vec> = Vec::with_capacity(num_nodes); + let network_config = NetworkArgs { + discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() }, + ..NetworkArgs::default() + }; + + let chain_spec = ChainSpecBuilder::default() + .chain(CHAIN_ID.into()) + .genesis(serde_json::from_str(include_str!("../../../crates/ethereum/node/tests/assets/genesis.json")).unwrap()) + .cancun_activated() + .build(); - for idx in 0..num_nodes { let node_config = NodeConfig::test() .with_chain(chain_spec.clone()) .with_network(network_config.clone()) .with_unused_ports() .with_rpc(RpcServerArgs::default().with_unused_ports().with_http()) - .set_dev(is_dev); + .set_dev(true); let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) .testing_node(exec.clone()) @@ -411,157 +289,11 @@ where .launch() .await?; - //node.state_by_block_id(block_id) - - let mut node = NodeTestContext::new(node).await?; - - // Connect each node in a chain. - if let Some(previous_node) = nodes.last_mut() { - previous_node.connect(&mut node).await; - } - - // Connect last node with the first if there are more than two - if idx + 1 == num_nodes && num_nodes > 2 { - if let Some(first_node) = nodes.first_mut() { - node.connect(first_node).await; - } - } - - nodes.push(node); - } - - Ok((nodes, tasks, Wallet::default().with_chain_id(chain_spec.chain().into()))) -} - -fn main() -> eyre::Result<()> { - println!("Brecht"); - reth::cli::Cli::parse_args().run(|builder, _| async move { - - // let (mut nodes, _tasks, _wallet) = setup::( - // 1, - // Arc::new( - // ChainSpecBuilder::default() - // .chain(MAINNET.chain) - // .genesis(serde_json::from_str(include_str!("../../../crates/ethereum/node/tests/assets/genesis.json")).unwrap()) - // .cancun_activated() - // .build(), - // ), - // false, - // ) - // .await?; - - // let node = nodes.pop().unwrap(); - - let tasks = TaskManager::current(); - let exec = tasks.executor(); - - let network_config = NetworkArgs { - discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() }, - ..NetworkArgs::default() - }; - - let chain_spec = ChainSpecBuilder::default() - .chain(CHAIN_ID.into()) - .genesis(serde_json::from_str(include_str!("../../../crates/ethereum/node/tests/assets/genesis.json")).unwrap()) - .cancun_activated() - .build(); - - let node_config = NodeConfig::test() - .with_chain(chain_spec.clone()) - .with_network(network_config.clone()) - .with_unused_ports() - .with_rpc(RpcServerArgs::default().with_unused_ports().with_http()) - .set_dev(true); - - let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) - .testing_node(exec.clone()) - .node(Default::default()) - .launch() - .await?; - - //node.state_by_block_id(block_id) - - let node = NodeTestContext::new(node).await?; + let node = NodeTestContext::new(node).await?; let handle = builder .node(EthereumNode::default()) .install_exex("Rollup", move |ctx| async { - //let connection = Connection::open(DATABASE_PATH)?; - - // let network_config = NetworkArgs { - // discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() }, - // ..NetworkArgs::default() - // }; - - // //let tasks = TaskManager::current(); - // let exec = tasks.executor(); - - // let node_config = NodeConfig::test() - // .with_chain(CHAIN_SPEC.clone()) - // .with_network(network_config.clone()) - // .with_unused_ports() - // .with_rpc(RpcServerArgs::default().with_unused_ports().with_http()) - // .set_dev(true); - - // let node_handle: = NodeBuilder::new(node_config.clone()) - // .testing_node(exec.clone()) - // .node(Default::default()) - // .launch() - // .await?; - - // let mut node = NodeTestContext::new(node_handle.node).await?; - - - - //Ok((nodes, tasks, Wallet::default().with_chain_id(chain_spec.chain().into()))) - - // let wallet = Wallet::default(); - // let raw_tx = TransactionTestContext::transfer_tx_bytes(1, wallet.inner).await; - - // // make the node advance - // let tx_hash = node.rpc.inject_tx(raw_tx).await?; - - // // make the node advance - // let (payload, _): (EthBuiltPayload, _) = node.advance_block(vec![], eth_payload_attributes).await?; - - // let block_hash = payload.block().hash(); - // let block_number = payload.block().number; - - // // assert the block has been committed to the blockchain - // node.assert_new_block(tx_hash, block_hash, block_number).await?; - - - // let wallet = Wallet::default(); - // let raw_tx = TransactionTestContext::transfer_tx_bytes(1, wallet.inner).await; - - // // make the node advance - // let tx_hash = node.rpc.inject_tx(raw_tx).await?; - - // // make the node advance - // let (payload, _) = node.advance_block(vec![], eth_payload_attributes).await?; - - // let block_hash = payload.block().hash(); - // let block_number = payload.block().number; - - // // assert the block has been committed to the blockchain - // node.assert_new_block(tx_hash, block_hash, block_number).await?; - - // // setup payload for submission - // let envelope_v3: ::ExecutionPayloadV3 = payload.into(); - - // // submit payload to engine api - // let submission = EngineApiClient::::new_payload_v3( - // &self.engine_api_client, - // envelope_v3.execution_payload(), - // versioned_hashes, - // payload_builder_attributes.parent_beacon_block_root().unwrap(), - // ) - // .await?; - - //let f: Pin> + Send>> = - // Box::pin(Rollup::new(ctx, connection, node)?.start()); - //f - Ok(Rollup::new(ctx, node)?.start()) }) .launch()