From 40948ec917ffa2e69719199fe90816631a0febaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gr=C3=BCner?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:49:05 -0300 Subject: [PATCH 01/88] feat(l2): pay base fee to coinbase --- crates/vm/levm/src/hooks/l2_hook.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 3da32ee6882..b90772cc6d8 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -107,7 +107,19 @@ impl Hook for L2Hook { ctx_result: &mut ContextResult, ) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { - return DefaultHook.finalize_execution(vm, ctx_result); + if !ctx_result.is_success() { + default_hook::undo_value_transfer(vm)?; + } + + let gas_refunded: u64 = default_hook::compute_gas_refunded(vm, ctx_result)?; + let actual_gas_used = + default_hook::compute_actual_gas_used(vm, gas_refunded, ctx_result.gas_used)?; + default_hook::refund_sender(vm, ctx_result, gas_refunded, actual_gas_used)?; + + // Different from L1, the base fee is not burned + pay_coinbase_with_base_fee(vm, actual_gas_used)?; + + default_hook::delete_self_destruct_accounts(vm)?; } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { @@ -121,3 +133,16 @@ impl Hook for L2Hook { Ok(()) } } + +pub fn pay_coinbase_with_base_fee( + vm: &mut VM<'_>, + gas_to_pay: u64, +) -> Result<(), crate::errors::VMError> { + let coinbase_fee = U256::from(gas_to_pay) + .checked_mul(vm.env.gas_price) + .ok_or(InternalError::Overflow)?; + + vm.increase_account_balance(vm.env.coinbase, coinbase_fee)?; + + Ok(()) +} From 875ed1b63cbd93d5a2cf821c8e21a1af84b132c6 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Sep 2025 17:07:58 -0300 Subject: [PATCH 02/88] Revert "feat(l2): pay base fee to coinbase" This reverts commit 40948ec917ffa2e69719199fe90816631a0febaa. --- crates/vm/levm/src/hooks/l2_hook.rs | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index b90772cc6d8..3da32ee6882 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -107,19 +107,7 @@ impl Hook for L2Hook { ctx_result: &mut ContextResult, ) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { - if !ctx_result.is_success() { - default_hook::undo_value_transfer(vm)?; - } - - let gas_refunded: u64 = default_hook::compute_gas_refunded(vm, ctx_result)?; - let actual_gas_used = - default_hook::compute_actual_gas_used(vm, gas_refunded, ctx_result.gas_used)?; - default_hook::refund_sender(vm, ctx_result, gas_refunded, actual_gas_used)?; - - // Different from L1, the base fee is not burned - pay_coinbase_with_base_fee(vm, actual_gas_used)?; - - default_hook::delete_self_destruct_accounts(vm)?; + return DefaultHook.finalize_execution(vm, ctx_result); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { @@ -133,16 +121,3 @@ impl Hook for L2Hook { Ok(()) } } - -pub fn pay_coinbase_with_base_fee( - vm: &mut VM<'_>, - gas_to_pay: u64, -) -> Result<(), crate::errors::VMError> { - let coinbase_fee = U256::from(gas_to_pay) - .checked_mul(vm.env.gas_price) - .ok_or(InternalError::Overflow)?; - - vm.increase_account_balance(vm.env.coinbase, coinbase_fee)?; - - Ok(()) -} From 2f11290c3b59cc2040a537c8de0af152b750b589 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Sep 2025 17:36:23 -0300 Subject: [PATCH 03/88] feat(l2): pay base_fee to fee_vault --- crates/vm/levm/src/environment.rs | 4 +++- crates/vm/levm/src/hooks/l2_hook.rs | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/vm/levm/src/environment.rs b/crates/vm/levm/src/environment.rs index b1bc1818fab..5765d5e9fb4 100644 --- a/crates/vm/levm/src/environment.rs +++ b/crates/vm/levm/src/environment.rs @@ -21,8 +21,10 @@ pub struct Environment { pub gas_limit: u64, pub config: EVMConfig, pub block_number: U256, - /// Coinbase is the block's beneficiary - the address that receives the block rewards and fees. + /// Coinbase is the block's beneficiary - the address that receives the block rewards (priority fees). pub coinbase: Address, + /// Fee vault is the address that receives the base fee in L2. + pub fee_vault: Option
, pub timestamp: U256, pub prev_randao: Option, pub difficulty: U256, diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 3da32ee6882..b3083613116 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -107,7 +107,9 @@ impl Hook for L2Hook { ctx_result: &mut ContextResult, ) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { - return DefaultHook.finalize_execution(vm, ctx_result); + DefaultHook.finalize_execution(vm, ctx_result)?; + // Different from L1, the base fee is not burned + return pay_to_fee_vault(vm, ctx_result.gas_used); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { @@ -121,3 +123,15 @@ impl Hook for L2Hook { Ok(()) } } + +fn pay_to_fee_vault(vm: &mut VM<'_>, gas_to_pay: u64) -> Result<(), crate::errors::VMError> { + let base_fee = U256::from(gas_to_pay) + .checked_mul(vm.env.base_fee_per_gas) + .ok_or(InternalError::Overflow)?; + let Some(fee_vault) = vm.env.fee_vault else { + // No fee vault configured, base fee is effectively burned + return Ok(()); + }; + vm.increase_account_balance(fee_vault, base_fee)?; + Ok(()) +} From a99d587cffe33bbfa31e8da16504a0e167669789 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 22 Sep 2025 19:10:32 -0300 Subject: [PATCH 04/88] Add fee_vault to blockchain --- cmd/ethrex_replay/src/cli.rs | 7 ++- crates/blockchain/blockchain.rs | 20 ++++++-- crates/blockchain/payload.rs | 7 ++- crates/blockchain/tracing.rs | 13 ++++-- .../prover/src/guest_program/src/execution.rs | 19 ++++++-- .../l2/prover/src/guest_program/src/input.rs | 9 +++- crates/l2/sequencer/block_producer.rs | 4 ++ .../block_producer/payload_builder.rs | 4 +- crates/l2/sequencer/configs.rs | 1 + crates/vm/backends/levm/mod.rs | 16 +++++-- crates/vm/backends/levm/tracing.rs | 6 ++- crates/vm/backends/mod.rs | 46 +++++++++++++++---- crates/vm/backends/revm/helpers.rs | 2 + crates/vm/backends/revm/mod.rs | 4 +- crates/vm/backends/revm/tracing.rs | 2 + crates/vm/levm/src/environment.rs | 2 +- crates/vm/tracing.rs | 18 ++++++-- tooling/ef_tests/state/runner/levm_runner.rs | 1 + 18 files changed, 143 insertions(+), 38 deletions(-) diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index e7ec7b0550a..40df96fe63d 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -653,7 +653,12 @@ pub async fn replay_custom_l1_blocks( store_inner }; - let blockchain = Arc::new(Blockchain::new(store.clone(), BlockchainType::L1, false)); + let blockchain = Arc::new(Blockchain::new( + store.clone(), + BlockchainType::L1, + false, + None, + )); let blocks = produce_l1_blocks( blockchain.clone(), diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 078c47f853e..fb976576eef 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -73,6 +73,8 @@ pub struct Blockchain { /// Mapping from a payload id to either a complete payload or a payload build task /// We need to keep completed payloads around in case consensus requests them twice pub payloads: Arc>>, + /// Address that receives the base fees in L2 + pub fee_vault: Option
, } #[derive(Debug, Clone)] @@ -94,7 +96,12 @@ fn log_batch_progress(batch_size: u32, current_block: u32) { } impl Blockchain { - pub fn new(store: Store, blockchain_type: BlockchainType, perf_logs_enabled: bool) -> Self { + pub fn new( + store: Store, + blockchain_type: BlockchainType, + perf_logs_enabled: bool, + fee_vault: Option
, + ) -> Self { Self { storage: store, mempool: Mempool::new(), @@ -102,6 +109,7 @@ impl Blockchain { r#type: blockchain_type, payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled, + fee_vault, } } @@ -113,6 +121,7 @@ impl Blockchain { r#type: BlockchainType::default(), payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled: false, + fee_vault: None, } } @@ -120,6 +129,7 @@ impl Blockchain { async fn execute_block( &self, block: &Block, + fee_vault: Option
, ) -> Result<(BlockExecutionResult, Vec), ChainError> { // Validate if it can be the new head and find the parent let Ok(parent_header) = find_parent_header(&block.header, &self.storage) else { @@ -136,7 +146,7 @@ impl Blockchain { let vm_db = StoreVmDatabase::new(self.storage.clone(), block.header.parent_hash); let mut vm = self.new_evm(vm_db)?; - let execution_result = vm.execute_block(block)?; + let execution_result = vm.execute_block(block, fee_vault)?; let account_updates = vm.get_state_transitions()?; // Validate execution went alright @@ -157,7 +167,7 @@ impl Blockchain { ) -> Result { // Validate the block pre-execution validate_block(block, parent_header, chain_config, ELASTICITY_MULTIPLIER)?; - let execution_result = vm.execute_block(block)?; + let execution_result = vm.execute_block(block, None)?; // Validate execution went alright validate_gas_used(&execution_result.receipts, &block.header)?; validate_receipts_root(&block.header, &execution_result.receipts)?; @@ -210,7 +220,7 @@ impl Blockchain { }; // Re-execute block with logger - vm.execute_block(block)?; + vm.execute_block(block, self.fee_vault)?; // Gather account updates let account_updates = vm.get_state_transitions()?; @@ -408,7 +418,7 @@ impl Blockchain { pub async fn add_block(&self, block: &Block) -> Result<(), ChainError> { let since = Instant::now(); - let (res, updates) = self.execute_block(block).await?; + let (res, updates) = self.execute_block(block, self.fee_vault).await?; let executed = Instant::now(); // Apply the account updates over the last block's state and compute the new state root diff --git a/crates/blockchain/payload.rs b/crates/blockchain/payload.rs index 44abde2cf68..f69f945f639 100644 --- a/crates/blockchain/payload.rs +++ b/crates/blockchain/payload.rs @@ -211,6 +211,7 @@ pub struct PayloadBuildContext { pub store: Store, pub vm: Evm, pub account_updates: Vec, + pub fee_vault: Option
, } impl PayloadBuildContext { @@ -218,6 +219,7 @@ impl PayloadBuildContext { payload: Block, storage: &Store, blockchain_type: BlockchainType, + fee_vault: Option
, ) -> Result { let config = storage .get_chain_config() @@ -249,6 +251,7 @@ impl PayloadBuildContext { store: storage.clone(), vm, account_updates: Vec::new(), + fee_vault, }) } @@ -386,7 +389,8 @@ impl Blockchain { debug!("Building payload"); let base_fee = payload.header.base_fee_per_gas.unwrap_or_default(); - let mut context = PayloadBuildContext::new(payload, &self.storage, self.r#type.clone())?; + let mut context = + PayloadBuildContext::new(payload, &self.storage, self.r#type.clone(), None)?; if let BlockchainType::L1 = self.r#type { self.apply_system_operations(&mut context)?; @@ -664,6 +668,7 @@ pub fn apply_plain_transaction( &context.payload.header, &mut context.remaining_gas, head.tx.sender(), + context.fee_vault, )?; context.block_value += U256::from(gas_used) * head.tip; Ok(report) diff --git a/crates/blockchain/tracing.rs b/crates/blockchain/tracing.rs index b10e94533d7..7639793232f 100644 --- a/crates/blockchain/tracing.rs +++ b/crates/blockchain/tracing.rs @@ -34,11 +34,13 @@ impl Blockchain { let mut vm = self .rebuild_parent_state(block.header.parent_hash, reexec) .await?; + let fee_vault = self.fee_vault; // Run the block until the transaction we want to trace - vm.rerun_block(&block, Some(tx_index))?; + vm.rerun_block(&block, Some(tx_index), fee_vault)?; + // Trace the transaction timeout_trace_operation(timeout, move || { - vm.trace_tx_calls(&block, tx_index, only_top_call, with_log) + vm.trace_tx_calls(&block, tx_index, only_top_call, with_log, fee_vault) }) .await } @@ -59,8 +61,9 @@ impl Blockchain { let mut vm = self .rebuild_parent_state(block.header.parent_hash, reexec) .await?; + let fee_vault = self.fee_vault; // Run anything necessary before executing the block's transactions (system calls, etc) - vm.rerun_block(&block, Some(0))?; + vm.rerun_block(&block, Some(0), fee_vault)?; // Trace each transaction // We need to do this in order to pass ownership of block & evm to a blocking process without cloning let vm = Arc::new(Mutex::new(vm)); @@ -74,7 +77,7 @@ impl Blockchain { let call_trace = timeout_trace_operation(timeout, move || { vm.lock() .map_err(|_| EvmError::Custom("Unexpected Runtime Error".to_string()))? - .trace_tx_calls(block.as_ref(), index, only_top_call, with_log) + .trace_tx_calls(block.as_ref(), index, only_top_call, with_log, fee_vault) }) .await?; call_traces.push((tx_hash, call_trace)); @@ -110,7 +113,7 @@ impl Blockchain { let mut vm = self.new_evm(vm_db)?; // Run parents to rebuild pre-state for block in blocks_to_re_execute.iter().rev() { - vm.rerun_block(block, None)?; + vm.rerun_block(block, None, self.fee_vault)?; } Ok(vm) } diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 13a7385b741..0275f5c0a23 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -100,6 +100,7 @@ pub fn execution_program(input: ProgramInput) -> Result Result, chain_id: u64, ) -> Result { let StatelessResult { @@ -135,7 +144,7 @@ pub fn stateless_validation_l1( last_block_hash, non_privileged_count, .. - } = execute_stateless(blocks, execution_witness, elasticity_multiplier)?; + } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_vault)?; Ok(ProgramOutput { initial_state_hash, @@ -157,6 +166,7 @@ pub fn stateless_validation_l2( blocks: &[Block], execution_witness: ExecutionWitness, elasticity_multiplier: u64, + fee_vault: Option
, blob_commitment: Commitment, blob_proof: Proof, chain_id: u64, @@ -174,7 +184,7 @@ pub fn stateless_validation_l2( nodes_hashed, codes_hashed, parent_block_header, - } = execute_stateless(blocks, execution_witness, elasticity_multiplier)?; + } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_vault)?; let (l1messages, privileged_transactions) = get_batch_l1messages_and_privileged_transactions(blocks, &receipts)?; @@ -258,6 +268,7 @@ fn execute_stateless( blocks: &[Block], execution_witness: ExecutionWitness, elasticity_multiplier: u64, + fee_vault: Option
, ) -> Result { let guest_program_state: GuestProgramState = execution_witness .try_into() @@ -327,7 +338,7 @@ fn execute_stateless( #[cfg(not(feature = "l2"))] let mut vm = Evm::new_for_l1(wrapped_db.clone()); let result = vm - .execute_block(block) + .execute_block(block, fee_vault) .map_err(StatelessExecutionError::EvmError)?; let receipts = result.receipts; let account_updates = vm diff --git a/crates/l2/prover/src/guest_program/src/input.rs b/crates/l2/prover/src/guest_program/src/input.rs index 79f5b485b06..144b09ab970 100644 --- a/crates/l2/prover/src/guest_program/src/input.rs +++ b/crates/l2/prover/src/guest_program/src/input.rs @@ -1,4 +1,7 @@ -use ethrex_common::types::{Block, block_execution_witness::ExecutionWitness}; +use ethrex_common::{ + Address, + types::{Block, block_execution_witness::ExecutionWitness}, +}; use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -16,6 +19,9 @@ pub struct ProgramInput { pub execution_witness: ExecutionWitness, /// value used to calculate base fee pub elasticity_multiplier: u64, + /// Address where collected fees are sent. If None, fees are burned. + #[rkyv(with=crate::rkyv_utils::H160Wrapper)] + pub fee_vault: Option
, #[cfg(feature = "l2")] /// KZG commitment to the blob data #[serde_as(as = "[_; 48]")] @@ -32,6 +38,7 @@ impl Default for ProgramInput { blocks: Default::default(), execution_witness: ExecutionWitness::default(), elasticity_multiplier: Default::default(), + fee_vault: None, #[cfg(feature = "l2")] blob_commitment: [0; 48], #[cfg(feature = "l2")] diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 6d31b95a24a..8511a816e39 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -56,6 +56,7 @@ pub struct BlockProducer { sequencer_state: SequencerState, block_time_ms: u64, coinbase_address: Address, + fee_vault_address: Address, elasticity_multiplier: u64, rollup_store: StoreRollup, // Needed to ensure privileged tx nonces are sequential @@ -82,6 +83,7 @@ impl BlockProducer { let BlockProducerConfig { block_time_ms, coinbase_address, + fee_vault_address, elasticity_multiplier, block_gas_limit, } = config; @@ -91,6 +93,7 @@ impl BlockProducer { sequencer_state, block_time_ms: *block_time_ms, coinbase_address: *coinbase_address, + fee_vault_address: *fee_vault_address, elasticity_multiplier: *elasticity_multiplier, rollup_store, // FIXME: Initialize properly to the last privileged nonce in the chain @@ -159,6 +162,7 @@ impl BlockProducer { &self.store, &mut self.last_privileged_nonce, self.block_gas_limit, + self.fee_vault_address, ) .await?; info!( diff --git a/crates/l2/sequencer/block_producer/payload_builder.rs b/crates/l2/sequencer/block_producer/payload_builder.rs index 984fcbfc093..f11ff869783 100644 --- a/crates/l2/sequencer/block_producer/payload_builder.rs +++ b/crates/l2/sequencer/block_producer/payload_builder.rs @@ -40,12 +40,14 @@ pub async fn build_payload( store: &Store, last_privileged_nonce: &mut Option, block_gas_limit: u64, + fee_vault: Address, ) -> Result { let since = Instant::now(); let gas_limit = payload.header.gas_limit; debug!("Building payload"); - let mut context = PayloadBuildContext::new(payload, store, blockchain.r#type.clone())?; + let mut context = + PayloadBuildContext::new(payload, store, blockchain.r#type.clone(), Some(fee_vault))?; fill_transactions( blockchain.clone(), diff --git a/crates/l2/sequencer/configs.rs b/crates/l2/sequencer/configs.rs index a8a08afd1e1..6359632e8d4 100644 --- a/crates/l2/sequencer/configs.rs +++ b/crates/l2/sequencer/configs.rs @@ -23,6 +23,7 @@ pub struct SequencerConfig { pub struct BlockProducerConfig { pub block_time_ms: u64, pub coinbase_address: Address, + pub fee_vault_address: Address, pub elasticity_multiplier: u64, pub block_gas_limit: u64, } diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 9dd7ebb0fbd..e059d470ee6 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -42,6 +42,7 @@ impl LEVM { block: &Block, db: &mut GeneralizedDatabase, vm_type: VMType, + fee_vault: Option
, ) -> Result { Self::prepare_block(block, db, vm_type)?; @@ -51,7 +52,7 @@ impl LEVM { for (tx, tx_sender) in block.body.get_transactions_with_sender().map_err(|error| { EvmError::Transaction(format!("Couldn't recover addresses with error: {error}")) })? { - let report = Self::execute_tx(tx, tx_sender, &block.header, db, vm_type)?; + let report = Self::execute_tx(tx, tx_sender, &block.header, db, vm_type, fee_vault)?; cumulative_gas_used += report.gas_used; let receipt = Receipt::new( @@ -84,6 +85,7 @@ impl LEVM { tx_sender: Address, block_header: &BlockHeader, db: &mut GeneralizedDatabase, + fee_vault: Option
, ) -> Result { let chain_config = db.store.get_chain_config()?; let gas_price: U256 = tx @@ -100,6 +102,7 @@ impl LEVM { config, block_number: block_header.number.into(), coinbase: block_header.coinbase, + fee_vault, timestamp: block_header.timestamp.into(), prev_randao: Some(block_header.prev_randao), chain_id: chain_config.chain_id.into(), @@ -129,8 +132,9 @@ impl LEVM { block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, + fee_vault: Option
, ) -> Result { - let env = Self::setup_env(tx, tx_sender, block_header, db)?; + let env = Self::setup_env(tx, tx_sender, block_header, db, fee_vault)?; let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?; vm.execute().map_err(VMError::into) @@ -148,8 +152,9 @@ impl LEVM { block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, + fee_vault: Option
, ) -> Result { - let mut env = env_from_generic(tx, block_header, db)?; + let mut env = env_from_generic(tx, block_header, db, fee_vault)?; env.block_gas_limit = u64::MAX; // disable block gas limit @@ -298,8 +303,9 @@ impl LEVM { header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, + fee_vault: Option
, ) -> Result<(ExecutionResult, AccessList), VMError> { - let mut env = env_from_generic(&tx, header, db)?; + let mut env = env_from_generic(&tx, header, db, fee_vault)?; adjust_disabled_base_fee(&mut env); @@ -482,6 +488,7 @@ fn env_from_generic( tx: &GenericTransaction, header: &BlockHeader, db: &GeneralizedDatabase, + fee_vault: Option
, ) -> Result { let chain_config = db.store.get_chain_config()?; let gas_price = calculate_gas_price(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); @@ -492,6 +499,7 @@ fn env_from_generic( config, block_number: header.number.into(), coinbase: header.coinbase, + fee_vault, timestamp: header.timestamp.into(), prev_randao: Some(header.prev_randao), chain_id: chain_config.chain_id.into(), diff --git a/crates/vm/backends/levm/tracing.rs b/crates/vm/backends/levm/tracing.rs index b6b95228c6b..8b0b01a75bf 100644 --- a/crates/vm/backends/levm/tracing.rs +++ b/crates/vm/backends/levm/tracing.rs @@ -1,3 +1,4 @@ +use ethrex_common::Address; use ethrex_common::types::{Block, Transaction}; use ethrex_common::{tracing::CallTrace, types::BlockHeader}; use ethrex_levm::vm::VMType; @@ -13,6 +14,7 @@ impl LEVM { block: &Block, stop_index: Option, vm_type: VMType, + fee_vault: Option
, ) -> Result<(), EvmError> { Self::prepare_block(block, db, vm_type)?; @@ -28,7 +30,7 @@ impl LEVM { break; } - Self::execute_tx(tx, sender, &block.header, db, vm_type)?; + Self::execute_tx(tx, sender, &block.header, db, vm_type, fee_vault)?; } // Process withdrawals only if the whole block has been executed. @@ -49,6 +51,7 @@ impl LEVM { only_top_call: bool, with_log: bool, vm_type: VMType, + fee_vault: Option
, ) -> Result { let env = Self::setup_env( tx, @@ -57,6 +60,7 @@ impl LEVM { })?, block_header, db, + fee_vault, )?; let mut vm = VM::new( env, diff --git a/crates/vm/backends/mod.rs b/crates/vm/backends/mod.rs index 70c53587c56..125449847cc 100644 --- a/crates/vm/backends/mod.rs +++ b/crates/vm/backends/mod.rs @@ -118,15 +118,19 @@ impl Evm { } #[instrument(level = "trace", name = "Block execution", skip_all)] - pub fn execute_block(&mut self, block: &Block) -> Result { + pub fn execute_block( + &mut self, + block: &Block, + fee_vault: Option
, + ) -> Result { #[cfg(feature = "revm")] { - REVM::execute_block(block, &mut self.state) + REVM::execute_block(block, &mut self.state, fee_vault) } #[cfg(not(feature = "revm"))] { - LEVM::execute_block(block, &mut self.db, self.vm_type) + LEVM::execute_block(block, &mut self.db, self.vm_type, fee_vault) } } @@ -139,6 +143,7 @@ impl Evm { block_header: &BlockHeader, remaining_gas: &mut u64, sender: Address, + fee_vault: Option
, ) -> Result<(Receipt, u64), EvmError> { #[cfg(feature = "revm")] { @@ -149,6 +154,7 @@ impl Evm { &mut self.state, spec_id(&chain_config, block_header.timestamp), sender, + fee_vault, )?; *remaining_gas = remaining_gas.saturating_sub(execution_result.gas_used()); @@ -165,8 +171,14 @@ impl Evm { #[cfg(not(feature = "revm"))] { - let execution_report = - LEVM::execute_tx(tx, sender, block_header, &mut self.db, self.vm_type)?; + let execution_report = LEVM::execute_tx( + tx, + sender, + block_header, + &mut self.db, + self.vm_type, + fee_vault, + )?; *remaining_gas = remaining_gas.saturating_sub(execution_report.gas_used); @@ -288,16 +300,23 @@ impl Evm { tx: &GenericTransaction, header: &BlockHeader, _fork: Fork, + fee_vault: Option
, ) -> Result { #[cfg(feature = "revm")] { let spec_id = fork_to_spec_id(_fork); - self::revm::helpers::simulate_tx_from_generic(tx, header, &mut self.state, spec_id) + self::revm::helpers::simulate_tx_from_generic( + tx, + header, + &mut self.state, + spec_id, + fee_vault, + ) } #[cfg(not(feature = "revm"))] { - LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type) + LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type, fee_vault) } } @@ -306,15 +325,24 @@ impl Evm { tx: &GenericTransaction, header: &BlockHeader, _fork: Fork, + fee_vault: Option
, ) -> Result<(u64, AccessList, Option), EvmError> { #[cfg(feature = "revm")] let result = { let spec_id = fork_to_spec_id(_fork); - self::revm::helpers::create_access_list(tx, header, &mut self.state, spec_id)? + self::revm::helpers::create_access_list( + tx, + header, + &mut self.state, + spec_id, + fee_vault, + )? }; #[cfg(not(feature = "revm"))] - let result = { LEVM::create_access_list(tx.clone(), header, &mut self.db, self.vm_type)? }; + let result = { + LEVM::create_access_list(tx.clone(), header, &mut self.db, self.vm_type, fee_vault)? + }; match result { ( diff --git a/crates/vm/backends/revm/helpers.rs b/crates/vm/backends/revm/helpers.rs index a4f87673881..efe57ce2e05 100644 --- a/crates/vm/backends/revm/helpers.rs +++ b/crates/vm/backends/revm/helpers.rs @@ -21,6 +21,7 @@ pub fn simulate_tx_from_generic( header: &BlockHeader, state: &mut EvmState, spec_id: SpecId, + _fee_vault: Option
, ) -> Result { let block_env = block_env(header, spec_id); let tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); @@ -33,6 +34,7 @@ pub fn create_access_list( header: &BlockHeader, state: &mut EvmState, spec_id: SpecId, + _fee_vault: Option
, ) -> Result<(ExecutionResult, AccessList), EvmError> { let mut tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); let block_env = block_env(header, spec_id); diff --git a/crates/vm/backends/revm/mod.rs b/crates/vm/backends/revm/mod.rs index 98b53948686..3c15deadb65 100644 --- a/crates/vm/backends/revm/mod.rs +++ b/crates/vm/backends/revm/mod.rs @@ -53,6 +53,7 @@ impl REVM { pub fn execute_block( block: &Block, state: &mut EvmState, + fee_vault: Option
, ) -> Result { let block_header = &block.header; let spec_id: SpecId = spec_id( @@ -75,7 +76,7 @@ impl REVM { for (tx, sender) in block.body.get_transactions_with_sender().map_err(|error| { EvmError::Transaction(format!("Couldn't recover addresses with error: {error}")) })? { - let result = Self::execute_tx(tx, block_header, state, spec_id, sender)?; + let result = Self::execute_tx(tx, block_header, state, spec_id, sender, fee_vault)?; cumulative_gas_used += result.gas_used(); let receipt = Receipt::new( tx.tx_type(), @@ -102,6 +103,7 @@ impl REVM { state: &mut EvmState, spec_id: SpecId, sender: Address, + _fee_vault: Option
, ) -> Result { let block_env = block_env(header, spec_id); let tx_env = tx_env(tx, sender); diff --git a/crates/vm/backends/revm/tracing.rs b/crates/vm/backends/revm/tracing.rs index 55b10a55eaa..e3c3327a772 100644 --- a/crates/vm/backends/revm/tracing.rs +++ b/crates/vm/backends/revm/tracing.rs @@ -27,6 +27,7 @@ impl REVM { state: &mut EvmState, only_top_call: bool, with_log: bool, + _fee_vault: Option
, ) -> Result { let spec_id: SpecId = spec_id(&state.chain_config()?, block_header.timestamp); let block_env = block_env(block_header, spec_id); @@ -47,6 +48,7 @@ impl REVM { block: &Block, state: &mut EvmState, stop_index: Option, + _fee_vault: Option
, ) -> Result<(), EvmError> { let spec_id: SpecId = spec_id(&state.chain_config()?, block.header.timestamp); let block_env = block_env(&block.header, spec_id); diff --git a/crates/vm/levm/src/environment.rs b/crates/vm/levm/src/environment.rs index 5765d5e9fb4..d9a57128138 100644 --- a/crates/vm/levm/src/environment.rs +++ b/crates/vm/levm/src/environment.rs @@ -23,7 +23,7 @@ pub struct Environment { pub block_number: U256, /// Coinbase is the block's beneficiary - the address that receives the block rewards (priority fees). pub coinbase: Address, - /// Fee vault is the address that receives the base fee in L2. + /// Fee vault is the address that receives the base fees in L2. pub fee_vault: Option
, pub timestamp: U256, pub prev_randao: Option, diff --git a/crates/vm/tracing.rs b/crates/vm/tracing.rs index 26298f4f604..e654bc281fc 100644 --- a/crates/vm/tracing.rs +++ b/crates/vm/tracing.rs @@ -1,5 +1,5 @@ -use ethrex_common::tracing::CallTrace; use ethrex_common::types::Block; +use ethrex_common::{Address, tracing::CallTrace}; #[cfg(not(feature = "revm"))] use crate::backends::levm::LEVM; @@ -19,6 +19,7 @@ impl Evm { tx_index: usize, only_top_call: bool, with_log: bool, + fee_vault: Option
, ) -> Result { let tx = block .body @@ -30,7 +31,14 @@ impl Evm { #[cfg(feature = "revm")] { - REVM::trace_tx_calls(&block.header, tx, &mut self.state, only_top_call, with_log) + REVM::trace_tx_calls( + &block.header, + tx, + &mut self.state, + only_top_call, + with_log, + fee_vault, + ) } #[cfg(not(feature = "revm"))] @@ -42,6 +50,7 @@ impl Evm { only_top_call, with_log, self.vm_type, + fee_vault, ) } } @@ -54,15 +63,16 @@ impl Evm { &mut self, block: &Block, stop_index: Option, + fee_vault: Option
, ) -> Result<(), EvmError> { #[cfg(feature = "revm")] { - REVM::rerun_block(block, &mut self.state, stop_index) + REVM::rerun_block(block, &mut self.state, stop_index, fee_vault) } #[cfg(not(feature = "revm"))] { - LEVM::rerun_block(&mut self.db, block, stop_index, self.vm_type) + LEVM::rerun_block(&mut self.db, block, stop_index, self.vm_type, fee_vault) } } } diff --git a/tooling/ef_tests/state/runner/levm_runner.rs b/tooling/ef_tests/state/runner/levm_runner.rs index d5084f967d9..a9ce56d3ff5 100644 --- a/tooling/ef_tests/state/runner/levm_runner.rs +++ b/tooling/ef_tests/state/runner/levm_runner.rs @@ -216,6 +216,7 @@ pub fn prepare_vm_for_tx<'a>( config, block_number: test.env.current_number, coinbase: test.env.current_coinbase, + fee_vault: None, timestamp: test.env.current_timestamp, prev_randao: test.env.current_random, difficulty: test.env.current_difficulty, From d6a85711534078de2c3b4be41a9f71ccd64a1a98 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 23 Sep 2025 16:15:59 -0300 Subject: [PATCH 05/88] Update modules to use fee_vault --- cmd/ethrex/initializers.rs | 1 + cmd/ethrex/l2/initializers.rs | 3 +++ cmd/ethrex/l2/options.rs | 10 ++++++++++ crates/blockchain/blockchain.rs | 16 ++++------------ crates/blockchain/tracing.rs | 13 +++++++------ crates/common/rkyv_utils.rs | 17 +++++++++++++++++ crates/l2/based/block_fetcher.rs | 2 +- crates/l2/networking/rpc/rpc.rs | 2 ++ crates/l2/prover/src/guest_program/src/input.rs | 2 +- crates/l2/prover/src/prover.rs | 1 + crates/l2/sequencer/block_producer.rs | 2 +- .../sequencer/block_producer/payload_builder.rs | 4 ++-- crates/l2/sequencer/configs.rs | 2 +- crates/l2/sequencer/l1_committer.rs | 6 +++++- crates/l2/sequencer/proof_coordinator.rs | 6 +++++- .../networking/rpc/debug/execution_witness.rs | 2 +- crates/networking/rpc/eth/transaction.rs | 11 ++++++++--- crates/networking/rpc/rpc.rs | 4 ++++ crates/networking/rpc/tracing.rs | 2 ++ crates/networking/rpc/utils.rs | 2 ++ fixtures/genesis/l2.json | 17 +++++++++++------ tooling/ef_tests/state_v2/src/modules/runner.rs | 1 + 22 files changed, 90 insertions(+), 36 deletions(-) diff --git a/cmd/ethrex/initializers.rs b/cmd/ethrex/initializers.rs index 9f30d834906..146d0dc4b39 100644 --- a/cmd/ethrex/initializers.rs +++ b/cmd/ethrex/initializers.rs @@ -164,6 +164,7 @@ pub async fn init_rpc_api( get_client_version(), log_filter_handler, gas_ceil, + None, ); tracker.spawn(rpc_api); diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index fa6580a4d15..3db27cb91d0 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -49,6 +49,7 @@ async fn init_rpc_api( rollup_store: StoreRollup, log_filter_handler: Option>, gas_ceil: Option, + fee_vault: Option
, ) { let peer_handler = PeerHandler::new(peer_table); @@ -79,6 +80,7 @@ async fn init_rpc_api( rollup_store, log_filter_handler, gas_ceil.unwrap_or(DEFAULT_BUILDER_GAS_CEIL), + fee_vault, ); tracker.spawn(rpc_api); @@ -200,6 +202,7 @@ pub async fn init_l2( rollup_store.clone(), log_filter_handler, Some(opts.sequencer_opts.block_producer_opts.block_gas_limit), + opts.sequencer_opts.block_producer_opts.fee_vault_address, ) .await; diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 80644ec3896..01bae8170a1 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -160,6 +160,7 @@ impl TryFrom for SequencerConfig { .block_producer_opts .coinbase_address .ok_or(SequencerOptionsError::NoCoinbaseAddress)?, + fee_vault_address: opts.block_producer_opts.fee_vault_address, elasticity_multiplier: opts.block_producer_opts.elasticity_multiplier, block_gas_limit: opts.block_producer_opts.block_gas_limit, }, @@ -386,6 +387,14 @@ pub struct BlockProducerOptions { required_unless_present = "dev" )] pub coinbase_address: Option
, + #[arg( + long = "block-producer.fee-vault-address", + value_name = "ADDRESS", + env = "ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS", + help_heading = "Block producer options", + required_unless_present = "dev" + )] + pub fee_vault_address: Option
, #[arg( long, default_value = "2", @@ -414,6 +423,7 @@ impl Default for BlockProducerOptions { .parse() .unwrap(), ), + fee_vault_address: None, elasticity_multiplier: 2, block_gas_limit: DEFAULT_BUILDER_GAS_CEIL, } diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index fb976576eef..69272998b38 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -73,8 +73,6 @@ pub struct Blockchain { /// Mapping from a payload id to either a complete payload or a payload build task /// We need to keep completed payloads around in case consensus requests them twice pub payloads: Arc>>, - /// Address that receives the base fees in L2 - pub fee_vault: Option
, } #[derive(Debug, Clone)] @@ -96,12 +94,7 @@ fn log_batch_progress(batch_size: u32, current_block: u32) { } impl Blockchain { - pub fn new( - store: Store, - blockchain_type: BlockchainType, - perf_logs_enabled: bool, - fee_vault: Option
, - ) -> Self { + pub fn new(store: Store, blockchain_type: BlockchainType, perf_logs_enabled: bool) -> Self { Self { storage: store, mempool: Mempool::new(), @@ -109,7 +102,6 @@ impl Blockchain { r#type: blockchain_type, payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled, - fee_vault, } } @@ -121,7 +113,6 @@ impl Blockchain { r#type: BlockchainType::default(), payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled: false, - fee_vault: None, } } @@ -179,6 +170,7 @@ impl Blockchain { pub async fn generate_witness_for_blocks( &self, blocks: &[Block], + fee_vault: Option
, ) -> Result { let first_block_header = blocks .first() @@ -220,7 +212,7 @@ impl Blockchain { }; // Re-execute block with logger - vm.execute_block(block, self.fee_vault)?; + vm.execute_block(block, fee_vault)?; // Gather account updates let account_updates = vm.get_state_transitions()?; @@ -418,7 +410,7 @@ impl Blockchain { pub async fn add_block(&self, block: &Block) -> Result<(), ChainError> { let since = Instant::now(); - let (res, updates) = self.execute_block(block, self.fee_vault).await?; + let (res, updates) = self.execute_block(block, None).await?; let executed = Instant::now(); // Apply the account updates over the last block's state and compute the new state root diff --git a/crates/blockchain/tracing.rs b/crates/blockchain/tracing.rs index 7639793232f..54f87bd8b05 100644 --- a/crates/blockchain/tracing.rs +++ b/crates/blockchain/tracing.rs @@ -3,7 +3,7 @@ use std::{ time::Duration, }; -use ethrex_common::{H256, tracing::CallTrace, types::Block}; +use ethrex_common::{Address, H256, tracing::CallTrace, types::Block}; use ethrex_storage::Store; use ethrex_vm::{Evm, EvmError}; @@ -19,6 +19,7 @@ impl Blockchain { timeout: Duration, only_top_call: bool, with_log: bool, + fee_vault: Option
, ) -> Result { // Fetch the transaction's location and the block it is contained in let Some((_, block_hash, tx_index)) = @@ -32,9 +33,8 @@ impl Blockchain { }; // Obtain the block's parent state let mut vm = self - .rebuild_parent_state(block.header.parent_hash, reexec) + .rebuild_parent_state(block.header.parent_hash, reexec, fee_vault) .await?; - let fee_vault = self.fee_vault; // Run the block until the transaction we want to trace vm.rerun_block(&block, Some(tx_index), fee_vault)?; @@ -56,12 +56,12 @@ impl Blockchain { timeout: Duration, only_top_call: bool, with_log: bool, + fee_vault: Option
, ) -> Result, ChainError> { // Obtain the block's parent state let mut vm = self - .rebuild_parent_state(block.header.parent_hash, reexec) + .rebuild_parent_state(block.header.parent_hash, reexec, fee_vault) .await?; - let fee_vault = self.fee_vault; // Run anything necessary before executing the block's transactions (system calls, etc) vm.rerun_block(&block, Some(0), fee_vault)?; // Trace each transaction @@ -91,6 +91,7 @@ impl Blockchain { &self, parent_hash: H256, reexec: u32, + fee_vault: Option
, ) -> Result { // Check if we need to re-execute parent blocks let blocks_to_re_execute = @@ -113,7 +114,7 @@ impl Blockchain { let mut vm = self.new_evm(vm_db)?; // Run parents to rebuild pre-state for block in blocks_to_re_execute.iter().rev() { - vm.rerun_block(block, None, self.fee_vault)?; + vm.rerun_block(block, None, fee_vault)?; } Ok(vm) } diff --git a/crates/common/rkyv_utils.rs b/crates/common/rkyv_utils.rs index 447a7b3f5ba..e873663b181 100644 --- a/crates/common/rkyv_utils.rs +++ b/crates/common/rkyv_utils.rs @@ -63,6 +63,23 @@ impl Hash for ArchivedH160Wrapper { } } +#[derive(Archive, Serialize, Deserialize)] +#[rkyv(remote = Option)] +pub enum OptionH160Wrapper { + Some(#[rkyv(with = H160Wrapper)] H160), + None, +} + +impl From for Option { + fn from(value: OptionH160Wrapper) -> Self { + if let OptionH160Wrapper::Some(x) = value { + Some(x) + } else { + None + } + } +} + #[derive( Archive, Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, )] diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 1a493cd258d..7e5f6088192 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -359,7 +359,7 @@ impl BlockFetcher { for block in batch { let vm_db = StoreVmDatabase::new(self.store.clone(), block.header.parent_hash); let mut vm = self.blockchain.new_evm(vm_db)?; - vm.execute_block(block) + vm.execute_block(block, None) .map_err(BlockFetcherError::EvmError)?; let account_updates = vm .get_state_transitions() diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index 66f472f29a4..46e13a44f29 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -79,6 +79,7 @@ pub async fn start_api( rollup_store: StoreRollup, log_filter_handler: Option>, gas_ceil: u64, + fee_vault: Option
, ) -> Result<(), RpcErr> { // TODO: Refactor how filters are handled, // filters are used by the filters endpoints (eth_newFilter, eth_getFilterChanges, ...etc) @@ -99,6 +100,7 @@ pub async fn start_api( gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler, gas_ceil, + fee_vault, }, valid_delegation_addresses, sponsor_pk, diff --git a/crates/l2/prover/src/guest_program/src/input.rs b/crates/l2/prover/src/guest_program/src/input.rs index 144b09ab970..1241dd3dc52 100644 --- a/crates/l2/prover/src/guest_program/src/input.rs +++ b/crates/l2/prover/src/guest_program/src/input.rs @@ -20,7 +20,7 @@ pub struct ProgramInput { /// value used to calculate base fee pub elasticity_multiplier: u64, /// Address where collected fees are sent. If None, fees are burned. - #[rkyv(with=crate::rkyv_utils::H160Wrapper)] + #[rkyv(with=ethrex_common::rkyv_utils::OptionH160Wrapper)] pub fee_vault: Option
, #[cfg(feature = "l2")] /// KZG commitment to the blob data diff --git a/crates/l2/prover/src/prover.rs b/crates/l2/prover/src/prover.rs index 1667a957295..7175a517bd7 100644 --- a/crates/l2/prover/src/prover.rs +++ b/crates/l2/prover/src/prover.rs @@ -120,6 +120,7 @@ impl Prover { blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, + fee_vault: input.fee_vault, }, })) } diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 8511a816e39..cdab794aac6 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -56,7 +56,7 @@ pub struct BlockProducer { sequencer_state: SequencerState, block_time_ms: u64, coinbase_address: Address, - fee_vault_address: Address, + fee_vault_address: Option
, elasticity_multiplier: u64, rollup_store: StoreRollup, // Needed to ensure privileged tx nonces are sequential diff --git a/crates/l2/sequencer/block_producer/payload_builder.rs b/crates/l2/sequencer/block_producer/payload_builder.rs index f11ff869783..dca43886833 100644 --- a/crates/l2/sequencer/block_producer/payload_builder.rs +++ b/crates/l2/sequencer/block_producer/payload_builder.rs @@ -40,14 +40,14 @@ pub async fn build_payload( store: &Store, last_privileged_nonce: &mut Option, block_gas_limit: u64, - fee_vault: Address, + fee_vault: Option
, ) -> Result { let since = Instant::now(); let gas_limit = payload.header.gas_limit; debug!("Building payload"); let mut context = - PayloadBuildContext::new(payload, store, blockchain.r#type.clone(), Some(fee_vault))?; + PayloadBuildContext::new(payload, store, blockchain.r#type.clone(), fee_vault)?; fill_transactions( blockchain.clone(), diff --git a/crates/l2/sequencer/configs.rs b/crates/l2/sequencer/configs.rs index 6359632e8d4..3656099408d 100644 --- a/crates/l2/sequencer/configs.rs +++ b/crates/l2/sequencer/configs.rs @@ -23,7 +23,7 @@ pub struct SequencerConfig { pub struct BlockProducerConfig { pub block_time_ms: u64, pub coinbase_address: Address, - pub fee_vault_address: Address, + pub fee_vault_address: Option
, pub elasticity_multiplier: u64, pub block_gas_limit: u64, } diff --git a/crates/l2/sequencer/l1_committer.rs b/crates/l2/sequencer/l1_committer.rs index 11dd0275c9e..1170500fb34 100644 --- a/crates/l2/sequencer/l1_committer.rs +++ b/crates/l2/sequencer/l1_committer.rs @@ -104,6 +104,7 @@ pub struct L1Committer { last_committed_batch: u64, /// Cancellation token for the next inbound InMessage::Commit cancellation_token: Option, + fee_vault: Option
, } #[derive(Clone, Serialize)] @@ -132,6 +133,7 @@ impl L1Committer { rollup_store: StoreRollup, based: bool, sequencer_state: SequencerState, + fee_vault: Option
, ) -> Result { let eth_client = EthClient::new_with_config( eth_config.rpc_url.iter().map(AsRef::as_ref).collect(), @@ -164,6 +166,7 @@ impl L1Committer { last_committed_batch_timestamp: 0, last_committed_batch, cancellation_token: None, + fee_vault, }) } @@ -182,6 +185,7 @@ impl L1Committer { rollup_store.clone(), cfg.based.enabled, sequencer_state, + cfg.block_producer.fee_vault_address, ) .await?; // NOTE: we spawn as blocking due to `generate_blobs_bundle` and @@ -406,7 +410,7 @@ impl L1Committer { let vm_db = StoreVmDatabase::new(self.store.clone(), block_to_commit.header.parent_hash); let mut vm = self.blockchain.new_evm(vm_db)?; - vm.execute_block(&block_to_commit)?; + vm.execute_block(&block_to_commit, self.fee_vault)?; vm.get_state_transitions()? }; diff --git a/crates/l2/sequencer/proof_coordinator.rs b/crates/l2/sequencer/proof_coordinator.rs index ed8af713494..7d57b88649c 100644 --- a/crates/l2/sequencer/proof_coordinator.rs +++ b/crates/l2/sequencer/proof_coordinator.rs @@ -49,6 +49,7 @@ pub struct ProverInputData { #[cfg(feature = "l2")] #[serde_as(as = "[_; 48]")] pub blob_proof: blobs_bundle::Proof, + pub fee_vault: Option
, } /// Enum for the ProverServer <--> ProverClient Communication Protocol. @@ -183,6 +184,7 @@ pub struct ProofCoordinator { commit_hash: String, #[cfg(feature = "metrics")] request_timestamp: Arc>>, + fee_vault: Option
, } impl ProofCoordinator { @@ -232,6 +234,7 @@ impl ProofCoordinator { commit_hash: get_commit_hash(), #[cfg(feature = "metrics")] request_timestamp: Arc::new(Mutex::new(HashMap::new())), + fee_vault: proposer_config.fee_vault_address, }) } @@ -467,7 +470,7 @@ impl ProofCoordinator { let witness = self .blockchain - .generate_witness_for_blocks(&blocks) + .generate_witness_for_blocks(&blocks, self.fee_vault) .await .map_err(ProofCoordinatorError::from)?; @@ -501,6 +504,7 @@ impl ProofCoordinator { blob_commitment, #[cfg(feature = "l2")] blob_proof, + fee_vault: self.fee_vault, }) } diff --git a/crates/networking/rpc/debug/execution_witness.rs b/crates/networking/rpc/debug/execution_witness.rs index 16b626fa73f..2c587b09fbb 100644 --- a/crates/networking/rpc/debug/execution_witness.rs +++ b/crates/networking/rpc/debug/execution_witness.rs @@ -156,7 +156,7 @@ impl RpcHandler for ExecutionWitnessRequest { let execution_witness = context .blockchain - .generate_witness_for_blocks(&blocks) + .generate_witness_for_blocks(&blocks, context.fee_vault) .await .map_err(|e| RpcErr::Internal(format!("Failed to build execution witness {e}")))?; diff --git a/crates/networking/rpc/eth/transaction.rs b/crates/networking/rpc/eth/transaction.rs index 9ad0be23ad5..2c839af5c23 100644 --- a/crates/networking/rpc/eth/transaction.rs +++ b/crates/networking/rpc/eth/transaction.rs @@ -11,7 +11,7 @@ use crate::{ }; use ethrex_blockchain::{Blockchain, vm::StoreVmDatabase}; use ethrex_common::{ - H256, U256, + Address, H256, U256, types::{ AccessListEntry, BlockHash, BlockHeader, BlockNumber, Fork, GenericTransaction, TxKind, }, @@ -117,6 +117,7 @@ impl RpcHandler for CallRequest { context.storage, context.blockchain, fork, + context.fee_vault, )?; serde_json::to_value(format!("0x{:#x}", result.output())) .map_err(|error| RpcErr::Internal(error.to_string())) @@ -354,7 +355,7 @@ impl RpcHandler for CreateAccessListRequest { // Run transaction and obtain access list let (gas_used, access_list, error) = - vm.create_access_list(&self.transaction, &header, fork)?; + vm.create_access_list(&self.transaction, &header, fork, context.fee_vault)?; let result = AccessListResult { access_list: access_list .into_iter() @@ -475,6 +476,7 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, + context.fee_vault, ); if let Ok(ExecutionResult::Success { .. }) = result { return serde_json::to_value(format!("{TRANSACTION_GAS:#x}")) @@ -508,6 +510,7 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, + context.fee_vault, )?; let gas_used = result.gas_used(); @@ -537,6 +540,7 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, + context.fee_vault, ); if let Ok(ExecutionResult::Success { .. }) = result { highest_gas_limit = middle_gas_limit; @@ -573,11 +577,12 @@ fn simulate_tx( storage: Store, blockchain: Arc, fork: Fork, + fee_vault: Option
, ) -> Result { let vm_db = StoreVmDatabase::new(storage.clone(), block_header.hash()); let mut vm = blockchain.new_evm(vm_db)?; - match vm.simulate_tx_from_generic(transaction, block_header, fork)? { + match vm.simulate_tx_from_generic(transaction, block_header, fork, fee_vault)? { ExecutionResult::Revert { gas_used: _, output, diff --git a/crates/networking/rpc/rpc.rs b/crates/networking/rpc/rpc.rs index 66f925b78c1..fd49700da15 100644 --- a/crates/networking/rpc/rpc.rs +++ b/crates/networking/rpc/rpc.rs @@ -49,6 +49,7 @@ use axum_extra::{ }; use bytes::Bytes; use ethrex_blockchain::Blockchain; +use ethrex_common::Address; use ethrex_common::types::DEFAULT_BUILDER_GAS_CEIL; use ethrex_p2p::peer_handler::PeerHandler; use ethrex_p2p::sync_manager::SyncManager; @@ -87,6 +88,7 @@ pub struct RpcApiContext { pub gas_tip_estimator: Arc>, pub log_filter_handler: Option>, pub gas_ceil: u64, + pub fee_vault: Option
, } #[derive(Debug, Clone)] @@ -131,6 +133,7 @@ pub async fn start_api( client_version: String, log_filter_handler: Option>, gas_ceil: Option, + fee_vault: Option
, ) -> Result<(), RpcErr> { // TODO: Refactor how filters are handled, // filters are used by the filters endpoints (eth_newFilter, eth_getFilterChanges, ...etc) @@ -150,6 +153,7 @@ pub async fn start_api( gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler, gas_ceil: gas_ceil.unwrap_or(DEFAULT_BUILDER_GAS_CEIL), + fee_vault, }; // Periodically clean up the active filters for the filters endpoints. diff --git a/crates/networking/rpc/tracing.rs b/crates/networking/rpc/tracing.rs index dc7d8258033..d2b826eae4c 100644 --- a/crates/networking/rpc/tracing.rs +++ b/crates/networking/rpc/tracing.rs @@ -113,6 +113,7 @@ impl RpcHandler for TraceTransactionRequest { timeout, config.only_top_call, config.with_log, + context.fee_vault, ) .await .map_err(|err| RpcErr::Internal(err.to_string()))?; @@ -170,6 +171,7 @@ impl RpcHandler for TraceBlockByNumberRequest { timeout, config.only_top_call, config.with_log, + context.fee_vault, ) .await .map_err(|err| RpcErr::Internal(err.to_string()))?; diff --git a/crates/networking/rpc/utils.rs b/crates/networking/rpc/utils.rs index 652e654835f..609274a4d65 100644 --- a/crates/networking/rpc/utils.rs +++ b/crates/networking/rpc/utils.rs @@ -395,6 +395,7 @@ pub mod test_utils { "ethrex/test".to_string(), None, None, + None, ) .await .unwrap(); @@ -418,6 +419,7 @@ pub mod test_utils { gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler: None, gas_ceil: DEFAULT_BUILDER_GAS_CEIL, + fee_vault: None, } } } diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 4049027d1f6..1a91cbf831d 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -28,6 +28,11 @@ "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 + }, + "osaka": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 } }, "mergeNetsplitBlock": 0, @@ -42,28 +47,28 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea2646970667358221220f417f158a03b2b3bbbca2d811bbb8b98132e02af20d18fc2012348e22c45060264736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea2646970667358221220dc4f949444d70310a11d0d6407ad07ca66d4c9b241decf68f359ed2d1194d9fb64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220bae1cba53d7390dd7424e36030c945f1c5041e5bfeec3f55e716522cbb5b379764736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea26469706673582212205c7ab8433e7f0ec8c19d076ef9cf134d22d778534ad6950d23f65a369fe3eddb64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122000127cc8c7439f51f583dce682ebe3dea6543792fdf187f2e50906b08ee9783664736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212209f9ae91d9582b7ef69b4e94035ceaa30dd184c4caa9a8ca3bf2b53c348a0b34464736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122000127cc8c7439f51f583dce682ebe3dea6543792fdf187f2e50906b08ee9783664736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212209f9ae91d9582b7ef69b4e94035ceaa30dd184c4caa9a8ca3bf2b53c348a0b34464736f6c634300081d0033", "storage": { "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" diff --git a/tooling/ef_tests/state_v2/src/modules/runner.rs b/tooling/ef_tests/state_v2/src/modules/runner.rs index 73fc0ec1671..91d60b3a120 100644 --- a/tooling/ef_tests/state_v2/src/modules/runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/runner.rs @@ -134,6 +134,7 @@ pub fn get_vm_env_for_test( config, block_number: test_env.current_number, coinbase: test_env.current_coinbase, + fee_vault: None, timestamp: test_env.current_timestamp, prev_randao: test_env.current_random, difficulty: test_env.current_difficulty, From 107336d744be2b6b71ce22b3c8220422e94a4309 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 23 Sep 2025 18:20:21 -0300 Subject: [PATCH 06/88] Impplement feeVault endpoint --- cmd/ethrex_replay/src/cli.rs | 13 +++++------ crates/blockchain/blockchain.rs | 8 +++++-- crates/l2/networking/rpc/clients.rs | 13 +++++++++++ crates/l2/networking/rpc/l2/fee_vault.rs | 22 +++++++++++++++++++ crates/l2/networking/rpc/l2/mod.rs | 1 + crates/l2/networking/rpc/rpc.rs | 1 + .../prover/src/guest_program/src/execution.rs | 4 ++-- fixtures/genesis/l2.json | 10 ++++----- 8 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 crates/l2/networking/rpc/l2/fee_vault.rs diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index ace13d0fa9b..c2ef71211bd 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -827,12 +827,7 @@ pub async fn replay_custom_l1_blocks( store_inner }; - let blockchain = Arc::new(Blockchain::new( - store.clone(), - BlockchainType::L1, - false, - None, - )); + let blockchain = Arc::new(Blockchain::new(store.clone(), BlockchainType::L1, false)); let blocks = produce_l1_blocks( blockchain.clone(), @@ -843,7 +838,9 @@ pub async fn replay_custom_l1_blocks( ) .await?; - let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; + let execution_witness = blockchain + .generate_witness_for_blocks(&blocks, None) + .await?; let network = Network::try_from(execution_witness.chain_config.chain_id).map_err(|e| { eyre::Error::msg(format!("Failed to determine network from chain ID: {}", e)) @@ -930,7 +927,7 @@ pub async fn produce_l1_block( err => ethrex_rpc::RpcErr::Internal(err.to_string()), })?; - blockchain.add_block(&block).await?; + blockchain.add_block(&block, None).await?; let new_block_hash = block.hash(); diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 712eccd94bd..16e56d0bee6 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -408,9 +408,13 @@ impl Blockchain { .map_err(|e| e.into()) } - pub async fn add_block(&self, block: &Block) -> Result<(), ChainError> { + pub async fn add_block( + &self, + block: &Block, + fee_vault: Option
, + ) -> Result<(), ChainError> { let since = Instant::now(); - let (res, updates) = self.execute_block(block, None).await?; + let (res, updates) = self.execute_block(block, fee_vault).await?; let executed = Instant::now(); // Apply the account updates over the last block's state and compute the new state root diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 914e5eb1651..ac0ce3f134f 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -47,3 +47,16 @@ pub async fn get_batch_by_number( } } } + +pub async fn get_fee_vault_address(client: &EthClient) -> Result, EthClientError> { + let request = RpcRequest::new("ethrex_getFeeVaultAddress", None); + + match client.send_request(request).await? { + RpcResponse::Success(result) => serde_json::from_value(result.result) + .map_err(GetFeeVaultAddressError::SerdeJSONError) + .map_err(EthClientError::from), + RpcResponse::Error(error_response) => { + Err(GetFeeVaultAddressError::RPCError(error_response.error.message).into()) + } + } +} diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/fee_vault.rs new file mode 100644 index 00000000000..cb6e1182014 --- /dev/null +++ b/crates/l2/networking/rpc/l2/fee_vault.rs @@ -0,0 +1,22 @@ +use crate::rpc::RpcHandler; + +pub struct GetFeeVaultAddress; + +impl RpcHandler for GetFeeVaultAddress { + fn parse(_params: &Option>) -> Result { + Ok(GetFeeVaultAddress) + } + + async fn handle( + &self, + context: ethrex_rpc::RpcApiContext, + ) -> Result { + let fee_vault_address = context + .l1_ctx + .fee_vault_address + .map(|addr| format!("{:#x}", addr)); + Ok(serde_json::to_value(fee_vault_address).map_err(|e| { + ethrex_rpc::RpcErr::Internal(format!("Failed to serialize fee vault address: {}", e)) + })?) + } +} diff --git a/crates/l2/networking/rpc/l2/mod.rs b/crates/l2/networking/rpc/l2/mod.rs index 2e128754499..7b3394e5d57 100644 --- a/crates/l2/networking/rpc/l2/mod.rs +++ b/crates/l2/networking/rpc/l2/mod.rs @@ -1,3 +1,4 @@ pub mod batch; +pub mod fee_vault; pub mod l1_message; pub mod transaction; diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index 46e13a44f29..fbb2bdac560 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -217,6 +217,7 @@ pub async fn map_l2_requests(req: &RpcRequest, context: RpcApiContext) -> Result "ethrex_getMessageProof" => GetL1MessageProof::call(req, context).await, "ethrex_batchNumber" => BatchNumberRequest::call(req, context).await, "ethrex_getBatchByNumber" => GetBatchByBatchNumberRequest::call(req, context).await, + "ethrex_getFeeVaultAddress" => GetFeeVaultAddress::call(req, context).await, unknown_ethrex_l2_method => { Err(ethrex_rpc::RpcErr::MethodNotFound(unknown_ethrex_l2_method.to_owned()).into()) } diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 0275f5c0a23..8a26d3f8a3d 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -135,7 +135,7 @@ pub fn stateless_validation_l1( blocks: &[Block], execution_witness: ExecutionWitness, elasticity_multiplier: u64, - fee_vault: Option
, + _fee_vault: Option
, chain_id: u64, ) -> Result { let StatelessResult { @@ -144,7 +144,7 @@ pub fn stateless_validation_l1( last_block_hash, non_privileged_count, .. - } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_vault)?; + } = execute_stateless(blocks, execution_witness, elasticity_multiplier, None)?; Ok(ProgramOutput { initial_state_hash, diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index e2aa70cd484..eb9ecbd74b0 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -47,19 +47,19 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea26469706673582212204396f246249f52e780861cf7c8e99ebc34211e11586f573a735d1178cc6f3e8664736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea264697066735822122062e3ee9344e32a3092478d16f69b9a464ebf27955eb832798df1ea9d4ad76e2364736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220ba047060ba3574875cd782f062d08240871ba803894074a664b4df16b994741164736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea264697066735822122038b42f312318b95343bd39529d5ae43fd4b5cf130d94305d19c1386761c4340364736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212205085245e305b782b83b7254aba6d60343bf038b0c74437ee496802a22f93ee2564736f6c634300081d0033", "storage": { "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" @@ -68,7 +68,7 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212205085245e305b782b83b7254aba6d60343bf038b0c74437ee496802a22f93ee2564736f6c634300081d0033", "storage": { "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" @@ -77,7 +77,7 @@ "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea26469706673582212203dcabd569808849d0e409a052e5e7d1fa1624dd221cdb5cd5d9cbed0d5bd521b64736f6c634300081d0033a2646970667358221220c9ee82b3796a8b1e888ae9b0f1244e703b889a0a49a1fc2f76e48ff4436c7a1564736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122053e1cd3ed516d50e33c9e4998dbe10aeda0147fbf383465899e87973062cffd664736f6c634300081d0033a2646970667358221220d821642e3aab6408db6ebb650cf70371deba32d4a31ca34edb627dfd75751da864736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" From c562dd2ed75605a16bb09bd279f59f842c598712 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 11:32:32 -0300 Subject: [PATCH 07/88] Update replay to use fee_vault --- cmd/ethrex/bench/build_block_benchmark.rs | 2 +- cmd/ethrex/cli.rs | 2 +- cmd/ethrex_replay/src/cache.rs | 2 + cmd/ethrex_replay/src/cli.rs | 62 ++++++++++++++++--- cmd/ethrex_replay/src/fetcher.rs | 6 +- cmd/ethrex_replay/src/rpc/db.rs | 8 ++- cmd/ethrex_replay/src/run.rs | 9 ++- crates/blockchain/smoke_test.rs | 26 ++++---- crates/l2/based/block_fetcher.rs | 2 +- crates/l2/networking/rpc/clients.rs | 3 +- crates/l2/networking/rpc/l2/fee_vault.rs | 19 +++--- crates/l2/networking/rpc/rpc.rs | 1 + .../networking/p2p/rlpx/l2/l2_connection.rs | 2 +- crates/networking/p2p/sync.rs | 2 +- crates/networking/rpc/clients/eth/errors.rs | 10 +++ crates/networking/rpc/engine/payload.rs | 2 +- .../state_v2/src/modules/block_runner.rs | 2 +- 17 files changed, 116 insertions(+), 44 deletions(-) diff --git a/cmd/ethrex/bench/build_block_benchmark.rs b/cmd/ethrex/bench/build_block_benchmark.rs index ffcb72241b6..52668afa37b 100644 --- a/cmd/ethrex/bench/build_block_benchmark.rs +++ b/cmd/ethrex/bench/build_block_benchmark.rs @@ -201,7 +201,7 @@ pub async fn bench_payload(input: &(Arc, Block, &Store)) -> (Duratio // 3. engine_newPayload is called, this eventually calls Blockchain::add_block // which takes transactions from the mempool and fills the block with them. let since = Instant::now(); - blockchain.add_block(&block).await.unwrap(); + blockchain.add_block(&block, None).await.unwrap(); let executed = Instant::now(); // EXTRA: Sanity check to not benchmark n empty block. let hash = &block.hash(); diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index 066fe5dd819..c9ba42dd9be 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -435,7 +435,7 @@ pub async fn import_blocks( } blockchain - .add_block(block) + .add_block(block, None) .await .inspect_err(|err| match err { // Block number 1's parent not found, the chain must not belong to the same network as the genesis file diff --git a/cmd/ethrex_replay/src/cache.rs b/cmd/ethrex_replay/src/cache.rs index 54ae636a2d7..e40860feb5c 100644 --- a/cmd/ethrex_replay/src/cache.rs +++ b/cmd/ethrex_replay/src/cache.rs @@ -1,3 +1,4 @@ +use ethrex_common::Address; use ethrex_common::types::Block; use ethrex_common::types::ChainConfig; use ethrex_common::types::blobs_bundle; @@ -19,6 +20,7 @@ pub struct L2Fields { pub blob_commitment: blobs_bundle::Commitment, #[serde_as(as = "[_; 48]")] pub blob_proof: blobs_bundle::Proof, + pub fee_vault: Option
, } /// Structure holding input data needed to execute or prove blocks. /// Optional fields are included only when relevant (e.g. L2 or custom chain). diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index c2ef71211bd..3dd95d42013 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -11,6 +11,8 @@ use ethrex_common::{ ELASTICITY_MULTIPLIER, Receipt, block_execution_witness::GuestProgramState, }, }; +#[cfg(feature = "l2")] +use ethrex_l2_rpc::clients::get_fee_vault_address; use ethrex_prover_lib::backend::Backend; use ethrex_rlp::{decode::RLPDecode, encode::RLPEncode}; use ethrex_rpc::{ @@ -213,6 +215,8 @@ pub struct BatchOptions { pub struct CustomBlockOptions { #[arg(long, help = "Whether to prove the block instead of executing it.")] prove: bool, + #[arg(long, help = "Fee vault address to use in L2 blocks.")] + fee_vault: Option
, } #[derive(Parser)] @@ -221,6 +225,8 @@ pub struct CustomBatchOptions { n_blocks: u64, #[arg(long, help = "Whether to prove the batch instead of executing it.")] prove: bool, + #[arg(long, help = "Fee vault address to use in L2 blocks.")] + fee_vault: Option
, } impl EthrexReplayCommand { @@ -262,7 +268,7 @@ impl EthrexReplayCommand { let block_identifier = or_latest(block)?; - get_blockdata(eth_client, network.clone(), block_identifier).await?; + get_blockdata(eth_client, network.clone(), block_identifier, None).await?; if let Some(block_number) = block { info!("Block {block_number} data cached successfully."); @@ -286,6 +292,7 @@ impl EthrexReplayCommand { eth_client.clone(), network.clone(), BlockIdentifier::Number(block_number), + None, ) .await?; } @@ -293,11 +300,12 @@ impl EthrexReplayCommand { info!("Blocks data cached successfully."); } #[cfg(not(feature = "l2"))] - Self::Custom(CustomSubcommand::Block(CustomBlockOptions { prove })) => { + Self::Custom(CustomSubcommand::Block(CustomBlockOptions { prove, fee_vault })) => { Box::pin(async move { Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks: 1, prove, + fee_vault, })) .run() .await @@ -305,7 +313,11 @@ impl EthrexReplayCommand { .await?; } #[cfg(not(feature = "l2"))] - Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks, prove })) => { + Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { + n_blocks, + prove, + fee_vault: _, + })) => { let opts = EthrexReplayOptions { execute: !prove, prove, @@ -364,7 +376,12 @@ impl EthrexReplayCommand { let (eth_client, network) = setup(&opts).await?; - let cache = get_batchdata(eth_client, network, batch).await?; + #[cfg(not(feature = "l2"))] + let fee_vault = None; + #[cfg(feature = "l2")] + let fee_vault = get_fee_vault_address(ð_client).await?; + + let cache = get_batchdata(eth_client, network, batch, fee_vault).await?; run_and_measure(replay(cache, &opts), opts.bench).await?; } @@ -373,10 +390,15 @@ impl EthrexReplayCommand { #[cfg(feature = "l2")] Self::L2(L2Subcommand::Custom(CustomSubcommand::Block(CustomBlockOptions { prove, + fee_vault, }))) => { Box::pin(async move { Self::L2(L2Subcommand::Custom(CustomSubcommand::Batch( - CustomBatchOptions { n_blocks: 1, prove }, + CustomBatchOptions { + n_blocks: 1, + prove, + fee_vault, + }, ))) .run() .await @@ -387,6 +409,7 @@ impl EthrexReplayCommand { Self::L2(L2Subcommand::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks, prove, + fee_vault, }))) => { let opts = EthrexReplayOptions { execute: !prove, @@ -398,7 +421,7 @@ impl EthrexReplayCommand { cache_level: CacheLevel::default(), }; - let elapsed = replay_custom_l2_blocks(max(1, n_blocks), &opts).await?; + let elapsed = replay_custom_l2_blocks(max(1, n_blocks), fee_vault, &opts).await?; if prove { println!("Successfully proved L2 batch in {elapsed:.2} seconds."); @@ -570,7 +593,9 @@ async fn replay_no_zkvm(cache: Cache, opts: &EthrexReplayOptions) -> eyre::Resul info!("Executing block {} on {}", block.header.number, network); let start_time = Instant::now(); - blockchain.add_block(&block).await?; + blockchain + .add_block(&block, cache.l2_fields.and_then(|f| f.fee_vault)) + .await?; let duration = start_time.elapsed(); info!("add_block execution time: {:.2?}", duration); @@ -592,10 +617,16 @@ async fn replay_transaction(tx_opts: TransactionOpts) -> eyre::Result<()> { .await? .ok_or(eyre::Error::msg("error fetching transaction"))?; + #[cfg(not(feature = "l2"))] + let fee_vault = None; + #[cfg(feature = "l2")] + let fee_vault = get_fee_vault_address(ð_client).await?; + let cache = get_blockdata( eth_client, network, BlockIdentifier::Number(tx.block_number.as_u64()), + fee_vault, ) .await?; @@ -628,7 +659,12 @@ async fn replay_block(block_opts: BlockOptions) -> eyre::Result<()> { )); } - let cache = get_blockdata(eth_client, network.clone(), or_latest(block)?).await?; + #[cfg(not(feature = "l2"))] + let fee_vault = None; + #[cfg(feature = "l2")] + let fee_vault = get_fee_vault_address(ð_client).await?; + + let cache = get_blockdata(eth_client, network.clone(), or_latest(block)?, fee_vault).await?; // Always write the cache after fetching from RPC. // It will be deleted later if not needed. @@ -950,6 +986,7 @@ use ethrex_vm::BlockExecutionResult; #[cfg(feature = "l2")] pub async fn replay_custom_l2_blocks( n_blocks: u64, + fee_vault: Option
, opts: &EthrexReplayOptions, ) -> eyre::Result { let network = Network::LocalDevnetL2; @@ -985,10 +1022,13 @@ pub async fn replay_custom_l2_blocks( genesis_hash, genesis.timestamp + 1, n_blocks, + fee_vault, ) .await?; - let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; + let execution_witness = blockchain + .generate_witness_for_blocks(&blocks, fee_vault) + .await?; let network = Network::try_from(execution_witness.chain_config.chain_id).map_err(|e| { eyre::Error::msg(format!("Failed to determine network from chain ID: {}", e)) @@ -1003,6 +1043,7 @@ pub async fn replay_custom_l2_blocks( cache.l2_fields = Some(L2Fields { blob_commitment: [0_u8; 48], blob_proof: [0_u8; 48], + fee_vault, }); let start = SystemTime::now(); @@ -1022,6 +1063,7 @@ pub async fn produce_custom_l2_blocks( head_block_hash: H256, initial_timestamp: u64, n_blocks: u64, + fee_vault: Option
, ) -> eyre::Result> { let mut blocks = Vec::new(); let mut current_parent_hash = head_block_hash; @@ -1034,6 +1076,7 @@ pub async fn produce_custom_l2_blocks( rollup_store, current_parent_hash, current_timestamp, + fee_vault, ) .await?; current_parent_hash = block.hash(); @@ -1051,6 +1094,7 @@ pub async fn produce_custom_l2_block( rollup_store: &StoreRollup, head_block_hash: H256, timestamp: u64, + fee_vault: Option
, ) -> eyre::Result { let build_payload_args = BuildPayloadArgs { parent: head_block_hash, diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index 3511aa6a088..4cad96fdb59 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -1,5 +1,6 @@ use std::time::{Duration, SystemTime}; +use ethrex_common::Address; use ethrex_common::types::ChainConfig; use ethrex_config::networks::Network; use ethrex_levm::vm::VMType; @@ -25,6 +26,7 @@ pub async fn get_blockdata( eth_client: EthClient, network: Network, block_number: BlockIdentifier, + fee_vault: Option
, ) -> eyre::Result { let latest_block_number = eth_client.get_block_number().await?.as_u64(); @@ -117,7 +119,7 @@ pub async fn get_blockdata( requested_block_number - 1 ); let rpc_db = rpc_db - .to_execution_witness(&block) + .to_execution_witness(&block, fee_vault) .wrap_err("failed to build execution db")?; info!( "Finished building execution witness for block {}", @@ -250,6 +252,7 @@ pub async fn get_batchdata( rollup_client: EthClient, network: Network, batch_number: u64, + fee_vault: Option
, ) -> eyre::Result { use ethrex_l2_rpc::clients::get_batch_by_number; @@ -284,6 +287,7 @@ pub async fn get_batchdata( .proofs .first() .unwrap_or(&[0_u8; 48]), + fee_vault, }); cache.write_cache(&file_name)?; diff --git a/cmd/ethrex_replay/src/rpc/db.rs b/cmd/ethrex_replay/src/rpc/db.rs index b78798c00ac..ec5524bd45f 100644 --- a/cmd/ethrex_replay/src/rpc/db.rs +++ b/cmd/ethrex_replay/src/rpc/db.rs @@ -310,11 +310,15 @@ impl RpcDB { /// 1. Pre-executes the block to capture all state changes /// 2. Gathers account and storage proofs for both initial and final states /// 3. Collects potential child nodes for deleted account and storage entries - pub fn to_execution_witness(&self, block: &Block) -> eyre::Result { + pub fn to_execution_witness( + &self, + block: &Block, + fee_vault: Option
, + ) -> eyre::Result { let mut db = GeneralizedDatabase::new(Arc::new(self.clone())); // pre-execute and get all state changes - let _ = LEVM::execute_block(block, &mut db, self.vm_type).map_err(Box::new)?; + let _ = LEVM::execute_block(block, &mut db, self.vm_type, fee_vault).map_err(Box::new)?; let execution_updates = LEVM::get_state_transitions(&mut db).map_err(Box::new)?; info!( diff --git a/cmd/ethrex_replay/src/run.rs b/cmd/ethrex_replay/src/run.rs index 2d24e3a8e1f..f3025c08b27 100644 --- a/cmd/ethrex_replay/src/run.rs +++ b/cmd/ethrex_replay/src/run.rs @@ -116,7 +116,13 @@ pub async fn run_tx(cache: Cache, tx_hash: H256) -> eyre::Result<(Receipt, Vec eyre::Result { elasticity_multiplier: ELASTICITY_MULTIPLIER, blob_commitment: l2_fields.blob_commitment, blob_proof: l2_fields.blob_proof, + fee_vault: l2_fields.fee_vault, }) } diff --git a/crates/blockchain/smoke_test.rs b/crates/blockchain/smoke_test.rs index 8f8b508cfe1..0bfa7421da1 100644 --- a/crates/blockchain/smoke_test.rs +++ b/crates/blockchain/smoke_test.rs @@ -29,7 +29,7 @@ mod blockchain_integration_test { // Add first block. We'll make it canonical. let block_1a = new_block(&store, &genesis_header).await; let hash_1a = block_1a.hash(); - blockchain.add_block(&block_1a).await.unwrap(); + blockchain.add_block(&block_1a, None).await.unwrap(); store .forkchoice_update(None, 1, hash_1a, None, None) .await @@ -43,7 +43,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_1b = block_1b.hash(); blockchain - .add_block(&block_1b) + .add_block(&block_1b, None) .await .expect("Could not add block 1b."); let retrieved_1b = store.get_block_header_by_hash(hash_1b).unwrap().unwrap(); @@ -55,7 +55,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1b.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2) + .add_block(&block_2, None) .await .expect("Could not add block 2."); let retrieved_2 = store.get_block_header_by_hash(hash_2).unwrap(); @@ -91,7 +91,7 @@ mod blockchain_integration_test { // Build a single valid block. let block_1 = new_block(&store, &genesis_header).await; let hash_1 = block_1.hash(); - blockchain.add_block(&block_1).await.unwrap(); + blockchain.add_block(&block_1, None).await.unwrap(); apply_fork_choice(&store, hash_1, H256::zero(), H256::zero()) .await .unwrap(); @@ -100,7 +100,7 @@ mod blockchain_integration_test { let mut block_2 = new_block(&store, &block_1.header).await; block_2.header.parent_hash = H256::random(); let hash_2 = block_2.hash(); - let result = blockchain.add_block(&block_2).await; + let result = blockchain.add_block(&block_2, None).await; assert!(matches!(result, Err(ChainError::ParentNotFound))); // block 2 should now be pending. @@ -126,7 +126,7 @@ mod blockchain_integration_test { // Add first block. Not canonical. let block_1a = new_block(&store, &genesis_header).await; let hash_1a = block_1a.hash(); - blockchain.add_block(&block_1a).await.unwrap(); + blockchain.add_block(&block_1a, None).await.unwrap(); let retrieved_1a = store.get_block_header_by_hash(hash_1a).unwrap().unwrap(); assert!(!is_canonical(&store, 1, hash_1a).await.unwrap()); @@ -135,7 +135,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_1b = block_1b.hash(); blockchain - .add_block(&block_1b) + .add_block(&block_1b, None) .await .expect("Could not add block 1b."); apply_fork_choice(&store, hash_1b, genesis_hash, genesis_hash) @@ -152,7 +152,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1b.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2) + .add_block(&block_2, None) .await .expect("Could not add block 2."); apply_fork_choice(&store, hash_2, genesis_hash, genesis_hash) @@ -199,7 +199,7 @@ mod blockchain_integration_test { let block_1 = new_block(&store, &genesis_header).await; let hash_1 = block_1.hash(); blockchain - .add_block(&block_1) + .add_block(&block_1, None) .await .expect("Could not add block 1b."); @@ -207,7 +207,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2) + .add_block(&block_2, None) .await .expect("Could not add block 2."); @@ -251,7 +251,7 @@ mod blockchain_integration_test { // Add block at height 1. let block_1 = new_block(&store, &genesis_header).await; blockchain - .add_block(&block_1) + .add_block(&block_1, None) .await .expect("Could not add block 1b."); @@ -259,7 +259,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2) + .add_block(&block_2, None) .await .expect("Could not add block 2."); @@ -279,7 +279,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_b = block_1b.hash(); blockchain - .add_block(&block_1b) + .add_block(&block_1b, None) .await .expect("Could not add block b."); diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 7e5f6088192..7ee8a9b64d8 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -269,7 +269,7 @@ impl BlockFetcher { async fn store_batch(&mut self, batch: &[Block]) -> Result<(), BlockFetcherError> { for block in batch.iter() { - self.blockchain.add_block(block).await?; + self.blockchain.add_block(block, None).await?; let block_hash = block.hash(); diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index ac0ce3f134f..b621c991521 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -1,4 +1,5 @@ use crate::l2::batch::RpcBatch; +use ethrex_common::Address; use ethrex_l2_common::l1_messages::L1MessageProof; use ethrex_rpc::{ EthClient, @@ -6,7 +7,7 @@ use ethrex_rpc::{ EthClientError, eth::{ RpcResponse, - errors::{GetBatchByNumberError, GetMessageProofError}, + errors::{GetBatchByNumberError, GetFeeVaultAddressError, GetMessageProofError}, }, }, utils::RpcRequest, diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/fee_vault.rs index cb6e1182014..a25d23a0802 100644 --- a/crates/l2/networking/rpc/l2/fee_vault.rs +++ b/crates/l2/networking/rpc/l2/fee_vault.rs @@ -1,20 +1,19 @@ -use crate::rpc::RpcHandler; +use serde_json::Value; + +use crate::{ + rpc::{RpcApiContext, RpcHandler}, + utils::RpcErr, +}; pub struct GetFeeVaultAddress; impl RpcHandler for GetFeeVaultAddress { - fn parse(_params: &Option>) -> Result { + fn parse(_params: &Option>) -> Result { Ok(GetFeeVaultAddress) } - async fn handle( - &self, - context: ethrex_rpc::RpcApiContext, - ) -> Result { - let fee_vault_address = context - .l1_ctx - .fee_vault_address - .map(|addr| format!("{:#x}", addr)); + async fn handle(&self, context: RpcApiContext) -> Result { + let fee_vault_address = context.l1_ctx.fee_vault.map(|addr| format!("{:#x}", addr)); Ok(serde_json::to_value(fee_vault_address).map_err(|e| { ethrex_rpc::RpcErr::Internal(format!("Failed to serialize fee vault address: {}", e)) })?) diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index fbb2bdac560..fefe3db04c4 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -1,4 +1,5 @@ use crate::l2::batch::{BatchNumberRequest, GetBatchByBatchNumberRequest}; +use crate::l2::fee_vault::GetFeeVaultAddress; use crate::l2::l1_message::GetL1MessageProof; use crate::utils::{RpcErr, RpcNamespace, resolve_namespace}; use axum::extract::State; diff --git a/crates/networking/p2p/rlpx/l2/l2_connection.rs b/crates/networking/p2p/rlpx/l2/l2_connection.rs index 5129dd4e36a..baff7edbe18 100644 --- a/crates/networking/p2p/rlpx/l2/l2_connection.rs +++ b/crates/networking/p2p/rlpx/l2/l2_connection.rs @@ -364,7 +364,7 @@ async fn process_new_block(established: &mut Established, msg: &NewBlock) -> Res } established .blockchain - .add_block(&block) + .add_block(&block, None) .await .inspect_err(|e| { log_peer_error( diff --git a/crates/networking/p2p/sync.rs b/crates/networking/p2p/sync.rs index 1e038583836..8808cc4819d 100644 --- a/crates/networking/p2p/sync.rs +++ b/crates/networking/p2p/sync.rs @@ -440,7 +440,7 @@ impl Syncer { if sync_head_found { let mut last_valid_hash = H256::default(); for block in blocks { - blockchain.add_block(&block).await.map_err(|e| { + blockchain.add_block(&block, None).await.map_err(|e| { ( e, Some(BatchBlockProcessingFailure { diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index f51ea3eb0b5..52d92b8c33f 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -69,6 +69,8 @@ pub enum EthClientError { GenericTransactionError(#[from] GenericTransactionError), #[error("Failed to parse hex string: {0}")] FromStrRadixError(#[from] FromStrRadixErr), + #[error("ethrex_getFeeVaultAddress request error: {0}")] + GetFeeVaultAddressError(#[from] GetFeeVaultAddressError), } #[derive(Debug, thiserror::Error)] @@ -302,3 +304,11 @@ pub enum GetBatchByNumberError { #[error("{0}")] RPCError(String), } + +#[derive(Debug, thiserror::Error)] +pub enum GetFeeVaultAddressError { + #[error("{0}")] + SerdeJSONError(#[from] serde_json::Error), + #[error("{0}")] + RPCError(String), +} diff --git a/crates/networking/rpc/engine/payload.rs b/crates/networking/rpc/engine/payload.rs index 66f8cd9a632..e94d09f4261 100644 --- a/crates/networking/rpc/engine/payload.rs +++ b/crates/networking/rpc/engine/payload.rs @@ -637,7 +637,7 @@ async fn try_execute_payload( // Execute and store the block info!(%block_hash, %block_number, "Executing payload"); - match context.blockchain.add_block(block).await { + match context.blockchain.add_block(block, None).await { Err(ChainError::ParentNotFound) => { // Start sync context.syncer.sync_to_head(block_hash); diff --git a/tooling/ef_tests/state_v2/src/modules/block_runner.rs b/tooling/ef_tests/state_v2/src/modules/block_runner.rs index dc63679a529..255ba22bb11 100644 --- a/tooling/ef_tests/state_v2/src/modules/block_runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/block_runner.rs @@ -146,7 +146,7 @@ pub async fn run_test(test: &Test, test_case: &TestCase) -> Result<(), RunnerErr let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false); - let result = blockchain.add_block(&block).await; + let result = blockchain.add_block(&block, None).await; if result.is_err() && test_case.post.expected_exceptions.is_none() { return Err(RunnerError::Custom( From c51c603c9b7a0e0014fc9fa854af9ce2ccf59ccb Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 12:01:56 -0300 Subject: [PATCH 08/88] Fix tdx --- crates/l2/tee/quote-gen/Cargo.lock | 1 + crates/l2/tee/quote-gen/src/sender.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/l2/tee/quote-gen/Cargo.lock b/crates/l2/tee/quote-gen/Cargo.lock index a3631f96bbd..eaf2cb41570 100644 --- a/crates/l2/tee/quote-gen/Cargo.lock +++ b/crates/l2/tee/quote-gen/Cargo.lock @@ -2107,6 +2107,7 @@ name = "ethrex-l2" version = "0.1.0" dependencies = [ "aligned-sdk", + "axum", "bincode", "bytes", "cfg-if 1.0.3", diff --git a/crates/l2/tee/quote-gen/src/sender.rs b/crates/l2/tee/quote-gen/src/sender.rs index c67f503664e..699dd5ca5e3 100644 --- a/crates/l2/tee/quote-gen/src/sender.rs +++ b/crates/l2/tee/quote-gen/src/sender.rs @@ -33,6 +33,7 @@ pub async fn get_batch(commit_hash: String) -> Result<(u64, ProgramInput), Strin blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, + fee_vault: input.fee_vault, }, )), _ => Err("No blocks to prove.".to_owned()), From 002f1519ff22841c27ad7fad81ad93abbfd13871 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 12:06:28 -0300 Subject: [PATCH 09/88] Rename fee vault to coinbase in tests --- crates/l2/tests/tests.rs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index a988e2542aa..b21103ef92e 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -99,8 +99,8 @@ async fn l2_integration_test() -> Result<(), Box> { // Not thread-safe (fee vault and bridge balance checks). test_deposit(&l1_client, &l2_client, &private_keys.pop().unwrap()).await?; - let fee_vault_balance_before_tests = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_before_tests = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let mut set = JoinSet::new(); @@ -181,15 +181,15 @@ async fn l2_integration_test() -> Result<(), Box> { recoverable_fees += fee; } - let fee_vault_balance_after_tests = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_after_tests = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; println!("Checking fee vault balance"); assert_eq!( - fee_vault_balance_after_tests, - fee_vault_balance_before_tests + recoverable_fees, + coinbase_balance_after_tests, + coinbase_balance_before_tests + recoverable_fees, "Fee vault is not correct after tests" ); @@ -999,8 +999,8 @@ async fn test_deposit( .get_balance(bridge_address()?, BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_before_deposit = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_before_deposit = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; println!("test_deposit: Depositing funds from L1 to L2"); @@ -1061,12 +1061,12 @@ async fn test_deposit( "Deposit recipient L2 balance didn't increase as expected after deposit" ); - let fee_vault_balance_after_deposit = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_after_deposit = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; assert_eq!( - fee_vault_balance_after_deposit, fee_vault_balance_before_deposit, + coinbase_balance_after_deposit, coinbase_balance_before_deposit, "Fee vault balance should not change after deposit" ); @@ -1409,8 +1409,8 @@ async fn test_n_withdraws( .get_balance(withdrawer_address, BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_before_withdrawal = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_before_withdrawal = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; println!("test_n_withdraws: Withdrawing funds from L2 to L1"); @@ -1474,8 +1474,8 @@ async fn test_n_withdraws( "Withdrawer L1 balance should not change after withdrawal" ); - let fee_vault_balance_after_withdrawal = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let coinbase_balance_after_withdrawal = l2_client + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let mut recoverable_fees = U256::zero(); @@ -1486,8 +1486,8 @@ async fn test_n_withdraws( } assert_eq!( - fee_vault_balance_after_withdrawal, - fee_vault_balance_before_withdrawal + recoverable_fees, + coinbase_balance_after_withdrawal, + coinbase_balance_before_withdrawal + recoverable_fees, "Fee vault balance didn't increase as expected after withdrawal" ); @@ -1574,7 +1574,7 @@ async fn test_total_eth_l2( .expect("Failed to get rich accounts balance"); let coinbase_balance = l2_client - .get_balance(fees_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; println!("Coinbase balance: {coinbase_balance}"); @@ -1809,7 +1809,7 @@ fn l2_client() -> EthClient { .unwrap() } -fn fees_vault() -> Address { +fn coinbase() -> Address { std::env::var("INTEGRATION_TEST_PROPOSER_COINBASE_ADDRESS") .map(|address| address.parse().expect("Invalid proposer coinbase address")) .unwrap_or(DEFAULT_PROPOSER_COINBASE_ADDRESS) From 605f14a2f89c581c085a89f755429fc85b85150a Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 12:23:13 -0300 Subject: [PATCH 10/88] Fix linter --- tooling/ef_tests/blockchain/test_runner.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tooling/ef_tests/blockchain/test_runner.rs b/tooling/ef_tests/blockchain/test_runner.rs index 1fbc2753e2c..040562d9efd 100644 --- a/tooling/ef_tests/blockchain/test_runner.rs +++ b/tooling/ef_tests/blockchain/test_runner.rs @@ -141,7 +141,7 @@ async fn run( let hash = block.hash(); // Attempt to add the block as the head of the chain - let chain_result = blockchain.add_block(&block).await; + let chain_result = blockchain.add_block(&block, None).await; match chain_result { Err(error) => { @@ -453,7 +453,7 @@ async fn re_run_stateless( let test_should_fail = test.blocks.iter().any(|t| t.expect_exception.is_some()); - let witness = blockchain.generate_witness_for_blocks(&blocks).await; + let witness = blockchain.generate_witness_for_blocks(&blocks, None).await; if test_should_fail && witness.is_err() { // We can't generate witness for a test that should fail. return Ok(()); From bb68f7f746bf3ea24749241b6310fce2979a748c Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 16:03:02 -0300 Subject: [PATCH 11/88] Update tests --- .github/workflows/main_prover.yaml | 1 + .github/workflows/pr-main_l2.yaml | 5 +- cmd/ethrex/build.rs | 2 +- crates/l2/Makefile | 1 + .../l2/docker-compose-l2-store.overrides.yaml | 1 + crates/l2/docker-compose-l2-web3signer.yaml | 1 + crates/l2/docker-compose.yaml | 1 + crates/l2/sdk/build.rs | 2 +- crates/l2/tests/tests.rs | 153 +++++++++++------- docs/l2/architecture/aligned_mode.md | 2 +- fixtures/genesis/l2.json | 10 +- fixtures/keys/private_keys.txt | 1 - fixtures/keys/private_keys_l1.txt | 1 - 13 files changed, 116 insertions(+), 65 deletions(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 1987cebed4d..906280a6b13 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -79,6 +79,7 @@ jobs: ETHREX_PROPOSER_BLOCK_TIME=12000 \ ETHREX_COMMITTER_COMMIT_TIME=30000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ + ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 docker compose up --build --detach --no-deps ethrex_l2 - name: Run test diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index a553cececdc..0e297c28583 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -159,6 +159,7 @@ jobs: ETHREX_WATCHER_BLOCK_DELAY=0 \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ + ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 - name: Run test @@ -260,7 +261,8 @@ jobs: cd crates/l2 RUST_LOG=info,ethrex_prover_lib=debug make init-prover & docker logs --follow ethrex_l2 & - PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d cargo test l2 --release -- --nocapture --test-threads=1 + PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ + cargo test l2 --release -- --nocapture --test-threads=1 killall ethrex -s SIGINT integration-test-tdx: @@ -336,6 +338,7 @@ jobs: ETHREX_WATCHER_BLOCK_DELAY=0 \ PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ + ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_PROOF_COORDINATOR_TDX_PRIVATE_KEY=0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d \ make init-l2 & sleep 30 diff --git a/cmd/ethrex/build.rs b/cmd/ethrex/build.rs index 9dcae2b8e65..4b4eb70b8fe 100644 --- a/cmd/ethrex/build.rs +++ b/cmd/ethrex/build.rs @@ -224,7 +224,7 @@ fn download_contract_deps(contracts_path: &Path) { &contracts_path .join("lib/openzeppelin-contracts-upgradeable") .to_string_lossy(), - None, + Some("release-v5.4"), true, ) .expect("Failed to clone openzeppelin-contracts-upgradeable"); diff --git a/crates/l2/Makefile b/crates/l2/Makefile index f3a86a843b8..f1fd5cb719c 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -132,6 +132,7 @@ init-l2: ## 🚀 Initializes an L2 Lambda ethrex Client --l1.on-chain-proposer-address ${DEFAULT_ON_CHAIN_PROPOSER_ADDRESS} \ --eth.rpc-url ${L1_RPC_URL} \ --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d \ + --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 \ --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d \ --proof-coordinator.addr ${PROOF_COORDINATOR_ADDRESS} diff --git a/crates/l2/docker-compose-l2-store.overrides.yaml b/crates/l2/docker-compose-l2-store.overrides.yaml index bd9394510bc..bcb73385549 100644 --- a/crates/l2/docker-compose-l2-store.overrides.yaml +++ b/crates/l2/docker-compose-l2-store.overrides.yaml @@ -12,6 +12,7 @@ services: --datadir /store --proof-coordinator.addr 0.0.0.0 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d + --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --no-monitor diff --git a/crates/l2/docker-compose-l2-web3signer.yaml b/crates/l2/docker-compose-l2-web3signer.yaml index 876cb5ce610..1f6ddf5a74d 100644 --- a/crates/l2/docker-compose-l2-web3signer.yaml +++ b/crates/l2/docker-compose-l2-web3signer.yaml @@ -19,6 +19,7 @@ services: --authrpc.port 8552 --proof-coordinator.addr 0.0.0.0 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d + --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.remote-signer-url http://web3signer:9000 --committer.remote-signer-public-key 02eadbea0cdb17fda8d56fc9c51df8a6158c2ab157aabf2ca57c3a32cd69f98bbc --proof-coordinator.remote-signer-url http://web3signer:9000 diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index 0c0565d192c..77a1ef570a9 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -73,6 +73,7 @@ services: - ETHREX_DEPLOYER_PICO_DEPLOY_VERIFIER=${ETHREX_DEPLOYER_PICO_DEPLOY_VERIFIER:-false} - ETHREX_WATCHER_BLOCK_DELAY=${ETHREX_WATCHER_BLOCK_DELAY:-0} - ETHREX_BASED=${ETHREX_BASED:-false} + - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS - ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=${ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY:-0x0000000000000000000000000000000000000000} - ETHREX_COMMITTER_COMMIT_TIME=${ETHREX_COMMITTER_COMMIT_TIME:-60000} - ETHREX_WATCHER_WATCH_INTERVAL=${ETHREX_WATCHER_WATCH_INTERVAL:-12000} diff --git a/crates/l2/sdk/build.rs b/crates/l2/sdk/build.rs index 0d23ae57da0..cf71e1ebc74 100644 --- a/crates/l2/sdk/build.rs +++ b/crates/l2/sdk/build.rs @@ -30,7 +30,7 @@ fn main() { .join("lib/openzeppelin-contracts-upgradeable") .to_str() .expect("Failed to convert path to str"), - None, + Some("release-v5.4"), true, ) .unwrap(); diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index b21103ef92e..46fe5b62639 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -30,6 +30,7 @@ use ethrex_rpc::{ use hex::FromHexError; use keccak_hash::keccak; use secp256k1::SecretKey; +use std::ops::{Add, AddAssign}; use std::{ fs::{File, read_to_string}, io::{BufRead, BufReader}, @@ -56,6 +57,7 @@ use tokio::task::JoinSet; /// Contract addresses: /// ETHREX_WATCHER_BRIDGE_ADDRESS: The address of the l1 bridge contract /// INTEGRATION_TEST_PROPOSER_COINBASE_ADDRESS: The address of the l2 coinbase +/// INTEGRATION_TEST_PROPOSER_FEE_VAULT_ADDRESS: The address of the l2 fee_vault /// /// Test parameters: /// @@ -79,6 +81,12 @@ const DEFAULT_PROPOSER_COINBASE_ADDRESS: Address = H160([ 0xad, 0x62, 0x0c, 0x8d, ]); +// 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 +const DEFAULT_PROPOSER_FEE_VAULT_ADDRESS: Address = H160([ + 0x00, 0x0c, 0x0d, 0x6b, 0x7c, 0x45, 0x16, 0xa5, 0xb2, 0x74, 0xc5, 0x1e, 0xa3, 0x31, 0xa9, 0x41, + 0x0f, 0xe6, 0x91, 0x27, +]); + const L2_GAS_COST_MAX_DELTA: U256 = U256([100_000_000_000_000, 0, 0, 0]); const DEFAULT_RICH_KEYS_FILE_PATH: &str = "../../fixtures/keys/private_keys_l1.txt"; @@ -96,12 +104,15 @@ async fn l2_integration_test() -> Result<(), Box> { .map(|amount| amount.parse().expect("Invalid withdrawal amount value")) .unwrap_or(5); - // Not thread-safe (fee vault and bridge balance checks). + // Not thread-safe (coinbase and bridge balance checks). test_deposit(&l1_client, &l2_client, &private_keys.pop().unwrap()).await?; let coinbase_balance_before_tests = l2_client .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let fee_vault_balance_before_tests = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; let mut set = JoinSet::new(); @@ -175,25 +186,37 @@ async fn l2_integration_test() -> Result<(), Box> { private_keys.pop().unwrap(), )); - let mut recoverable_fees = U256::zero(); + let mut acc_priority_fees = U256::zero(); + let mut acc_base_fees = U256::zero(); while let Some(res) = set.join_next().await { - let fee = res??; - recoverable_fees += fee; + let fees_details = res??; + acc_priority_fees += fees_details.total_fees - fees_details.base_fees; + acc_base_fees += fees_details.base_fees; } let coinbase_balance_after_tests = l2_client .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - println!("Checking fee vault balance"); + let fee_vault_balance_after_tests = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + println!("Checking coinbase and fee vault balances"); assert_eq!( coinbase_balance_after_tests, - coinbase_balance_before_tests + recoverable_fees, + coinbase_balance_before_tests + acc_priority_fees, + "Coinbase is not correct after tests" + ); + + assert_eq!( + fee_vault_balance_after_tests, + fee_vault_balance_before_tests + acc_base_fees, "Fee vault is not correct after tests" ); - // Not thread-safe (fee vault and bridge balance checks) + // Not thread-safe (coinbase and bridge balance checks) test_n_withdraws( &l1_client, &l2_client, @@ -217,7 +240,7 @@ async fn l2_integration_test() -> Result<(), Box> { /// 2. Deploys the new implementation on L2 /// 3. Calls the upgrade function on the L1 bridge contract /// 4. Checks that the implementation address has changed -async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result { +async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result { println!("Testing upgrade"); let bridge_owner_private_key = bridge_owner_private_key(); @@ -243,7 +266,7 @@ async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result Result {final_impl:#x}"); assert_ne!(initial_impl, final_impl); - Ok(deploy_recoverable_fees) + Ok(deploy_base_fees) } /// In this test we deploy a contract on L2 and call it from L1 using the CommonBridge contract. @@ -301,7 +324,7 @@ async fn test_privileged_tx_with_contract_call( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { // pragma solidity ^0.8.27; // contract Test { // event NumberSet(uint256 indexed number); @@ -315,7 +338,7 @@ async fn test_privileged_tx_with_contract_call( println!("ptx_with_contract_call: Deploying contract on L2"); - let (deployed_contract_address, recoverable_fees) = test_deploy( + let (deployed_contract_address, base_fees) = test_deploy( &l2_client, &init_code, &rich_wallet_private_key, @@ -390,7 +413,7 @@ async fn test_privileged_tx_with_contract_call( "ptx_with_contract_call: Event emitted with wrong value. Expected 424242, got {number_emitted}" ); - Ok(recoverable_fees) + Ok(base_fees) } /// Test the deployment of a contract on L2 and call it from L1 using the CommonBridge contract. @@ -399,7 +422,7 @@ async fn test_privileged_tx_with_contract_call_revert( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { // pragma solidity ^0.8.27; // contract RevertTest { // function revert_call() public { @@ -412,7 +435,7 @@ async fn test_privileged_tx_with_contract_call_revert( println!("ptx_with_contract_call_revert: Deploying contract on L2"); - let (deployed_contract_address, recoverable_fees) = test_deploy( + let (deployed_contract_address, base_fees) = test_deploy( &l2_client, &init_code, &rich_wallet_private_key, @@ -434,7 +457,7 @@ async fn test_privileged_tx_with_contract_call_revert( ) .await?; - Ok(recoverable_fees) + Ok(base_fees) } async fn find_withdrawal_with_widget( @@ -464,7 +487,7 @@ async fn test_erc20_roundtrip( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { let token_amount: U256 = U256::from(100); let rich_wallet_signer: Signer = LocalSigner::new(rich_wallet_private_key).into(); @@ -658,7 +681,7 @@ async fn test_erc20_roundtrip( let l2_final_balance = test_balance_of(&l2_client, token_l2, rich_address).await; assert_eq!(initial_balance, l1_final_balance); assert!(l2_final_balance.is_zero()); - Ok(deploy_fees + approve_fees.recoverable_fees + withdraw_fees.recoverable_fees) + Ok(deploy_fees + approve_fees + withdraw_fees) } /// Tests that the aliasing is done correctly when calling from L1 to L2 @@ -669,7 +692,7 @@ async fn test_aliasing( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { println!("Testing aliasing"); let init_code_l1 = hex::decode(std::fs::read("../../fixtures/contracts/caller/Caller.bin")?)?; let caller_l1 = test_deploy_l1(&l1_client, &init_code_l1, &rich_wallet_private_key).await?; @@ -708,7 +731,7 @@ async fn test_aliasing( receipt_l2.tx_info.from ); assert_eq!(receipt_l2.tx_info.from, get_address_alias(caller_l1)); - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Tests that a failed deposit can be withdrawn back to L1 @@ -719,7 +742,7 @@ async fn test_erc20_failed_deposit( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { let token_amount: U256 = U256::from(100); let rich_wallet_signer: Signer = LocalSigner::new(rich_wallet_private_key).into(); @@ -799,7 +822,7 @@ async fn test_erc20_failed_deposit( wait_for_transaction_receipt(withdraw_claim_tx, &l1_client, 5).await?; let l1_final_balance = test_balance_of(&l1_client, token_l1, rich_address).await; assert_eq!(initial_balance, l1_final_balance); - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Tests that a withdrawal can be triggered by a privileged transaction @@ -808,7 +831,7 @@ async fn test_forced_withdrawal( l1_client: EthClient, l2_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { println!("forced_withdrawal: Testing forced withdrawal"); let rich_address = get_address_from_secret_key(&rich_wallet_private_key).expect("Failed to get address"); @@ -922,7 +945,7 @@ async fn test_forced_withdrawal( l1_final_balance ); assert_eq!(l2_initial_balance - transfer_value, l2_final_balance); - Ok(U256::zero()) + Ok(FeesDetails::default()) } async fn test_balance_of(client: &EthClient, token: Address, user: Address) -> U256 { @@ -966,7 +989,7 @@ async fn test_send( } /// Test depositing ETH from L1 to L2 -/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and fee vault on L2. +/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and coinbase on L2. /// 2. Perform deposit from L1 to L2 /// 3. Check final balances. async fn test_deposit( @@ -1067,7 +1090,7 @@ async fn test_deposit( assert_eq!( coinbase_balance_after_deposit, coinbase_balance_before_deposit, - "Fee vault balance should not change after deposit" + "Coinbase balance should not change after deposit" ); Ok(()) @@ -1076,7 +1099,7 @@ async fn test_deposit( async fn test_privileged_spammer( l1_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { let init_code_l1 = hex::decode(std::fs::read( "../../fixtures/contracts/deposit_spammer/DepositSpammer.bin", )?)?; @@ -1092,7 +1115,7 @@ async fn test_privileged_spammer( ) .await?; } - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Test transferring ETH on L2 @@ -1104,7 +1127,7 @@ async fn test_transfer( l2_client: EthClient, transferer_private_key: SecretKey, returnerer_private_key: SecretKey, -) -> Result { +) -> Result { println!("test_transfer: Transferring funds on L2"); let transferer_address = get_address_from_secret_key(&transferer_private_key).unwrap(); let returner_address = get_address_from_secret_key(&returnerer_private_key).unwrap(); @@ -1113,7 +1136,7 @@ async fn test_transfer( "test_transfer: Performing transfer from {transferer_address:#x} to {returner_address:#x}" ); - let mut recoverable_fees = perform_transfer( + let mut base_fees = perform_transfer( &l2_client, &transferer_private_key, returner_address, @@ -1127,7 +1150,7 @@ async fn test_transfer( "test_transfer: Performing return transfer from {returner_address:#x} to {transferer_address:#x} with amount {return_amount}" ); - recoverable_fees += perform_transfer( + base_fees += perform_transfer( &l2_client, &returnerer_private_key, transferer_address, @@ -1135,7 +1158,7 @@ async fn test_transfer( ) .await?; - Ok(recoverable_fees) + Ok(base_fees) } /// Test transferring ETH on L2 through a privileged transaction (deposit from L1) @@ -1147,7 +1170,7 @@ async fn test_transfer_with_privileged_tx( l2_client: EthClient, transferer_private_key: SecretKey, receiver_private_key: SecretKey, -) -> Result { +) -> Result { println!("transfer_with_ptx: Transferring funds on L2 through a deposit"); let transferer_address = get_address_from_secret_key(&transferer_private_key).unwrap(); let receiver_address = get_address_from_secret_key(&receiver_private_key).unwrap(); @@ -1195,7 +1218,7 @@ async fn test_transfer_with_privileged_tx( receiver_balance_after, receiver_balance_before + transfer_value() ); - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Test that gas is burned from the L1 account when making a deposit with a specified L2 gas limit. @@ -1204,7 +1227,7 @@ async fn test_transfer_with_privileged_tx( async fn test_gas_burning( l1_client: EthClient, rich_wallet_private_key: SecretKey, -) -> Result { +) -> Result { println!("test_gas_burning: Transferring funds on L2 through a deposit"); let rich_address = get_address_from_secret_key(&rich_wallet_private_key).unwrap(); let l2_gas_limit = 2_000_000; @@ -1228,7 +1251,7 @@ async fn test_gas_burning( assert!(l1_to_l2_tx_receipt.receipt.status); assert!(l1_to_l2_tx_receipt.tx_info.gas_used > l2_gas_limit); assert!(l1_to_l2_tx_receipt.tx_info.gas_used < l2_gas_limit + l1_extra_gas_limit); - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Test transferring ETH on L2 through a privileged transaction (deposit from L1) with insufficient balance @@ -1240,7 +1263,7 @@ async fn test_privileged_tx_not_enough_balance( l2_client: EthClient, rich_wallet_private_key: SecretKey, receiver_private_key: SecretKey, -) -> Result { +) -> Result { println!( "ptx_not_enough_balance: Starting test for privileged transaction with insufficient balance" ); @@ -1292,7 +1315,7 @@ async fn test_privileged_tx_not_enough_balance( .get_balance(receiver_address, BlockIdentifier::Tag(BlockTag::Latest)) .await?; assert_eq!(balance_after, balance_before); - Ok(U256::zero()) + Ok(FeesDetails::default()) } /// Test helper @@ -1304,7 +1327,7 @@ async fn perform_transfer( transferer_private_key: &SecretKey, transfer_recipient_address: Address, transfer_value: U256, -) -> Result { +) -> Result { let transferer_address = get_address_from_secret_key(transferer_private_key).unwrap(); let transferer_initial_l2_balance = l2_client @@ -1370,7 +1393,7 @@ async fn perform_transfer( let transfer_fees = get_fees_details_l2(&transfer_tx_receipt, l2_client).await; - Ok(transfer_fees.recoverable_fees) + Ok(transfer_fees) } async fn test_n_withdraws( @@ -1478,17 +1501,15 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let mut recoverable_fees = U256::zero(); + let mut base_fees = U256::zero(); for receipt in receipts { - recoverable_fees += get_fees_details_l2(&receipt, l2_client) - .await - .recoverable_fees; + base_fees += get_fees_details_l2(&receipt, l2_client).await.base_fees; } assert_eq!( coinbase_balance_after_withdrawal, - coinbase_balance_before_withdrawal + recoverable_fees, - "Fee vault balance didn't increase as expected after withdrawal" + coinbase_balance_before_withdrawal + base_fees, + "Coinbase balance didn't increase as expected after withdrawal" ); // We need to wait for all the txs to be included in some batch @@ -1609,7 +1630,7 @@ async fn test_deploy( init_code: &[u8], deployer_private_key: &SecretKey, test_name: &str, -) -> Result<(Address, U256)> { +) -> Result<(Address, FeesDetails)> { println!("{test_name}: Deploying contract on L2"); let deployer: Signer = LocalSigner::new(*deployer_private_key).into(); @@ -1655,7 +1676,7 @@ async fn test_deploy( "{test_name}: Deployed contract balance should be zero after deploy" ); - Ok((contract_address, deploy_fees.recoverable_fees)) + Ok((contract_address, deploy_fees)) } async fn test_deploy_l1( @@ -1678,7 +1699,7 @@ async fn test_deploy_l1( Ok(contract_address) } -/// Fee vault must be 0 +/// Coinbase must be 0 async fn test_call_to_contract_with_deposit( l1_client: &EthClient, l2_client: &EthClient, @@ -1767,10 +1788,28 @@ fn bridge_owner_private_key() -> SecretKey { SecretKey::from_slice(l1_rich_wallet_pk.as_bytes()).unwrap() } -#[derive(Debug)] +#[derive(Debug, Default)] struct FeesDetails { total_fees: U256, - recoverable_fees: U256, + base_fees: U256, +} + +impl Add for FeesDetails { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self { + total_fees: self.total_fees + other.total_fees, + base_fees: self.base_fees + other.base_fees, + } + } +} + +impl AddAssign for FeesDetails { + fn add_assign(&mut self, other: Self) { + self.total_fees += other.total_fees; + self.base_fees += other.base_fees; + } } async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> FeesDetails { @@ -1791,11 +1830,11 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> let max_priority_fee_per_gas_transfer: U256 = (effective_gas_price - base_fee_per_gas).into(); - let recoverable_fees = max_priority_fee_per_gas_transfer.mul(tx_receipt.tx_info.gas_used); + let base_fees = max_priority_fee_per_gas_transfer.mul(tx_receipt.tx_info.gas_used); FeesDetails { total_fees, - recoverable_fees, + base_fees, } } @@ -1815,6 +1854,12 @@ fn coinbase() -> Address { .unwrap_or(DEFAULT_PROPOSER_COINBASE_ADDRESS) } +fn fee_vault() -> Address { + std::env::var("INTEGRATION_TEST_PROPOSER_FEE_VAULT_ADDRESS") + .map(|address| address.parse().expect("Invalid proposer coinbase address")) + .unwrap_or(DEFAULT_PROPOSER_FEE_VAULT_ADDRESS) +} + async fn wait_for_l2_deposit_receipt( rpc_receipt: &RpcReceipt, l1_client: &EthClient, @@ -1954,7 +1999,7 @@ fn get_contract_dependencies(contracts_path: &Path) { .join("lib/openzeppelin-contracts-upgradeable") .to_str() .expect("Failed to convert path to str"), - None, + Some("release-v5.4"), true, ) .unwrap(); diff --git a/docs/l2/architecture/aligned_mode.md b/docs/l2/architecture/aligned_mode.md index a1f921e95ac..d85fb399024 100644 --- a/docs/l2/architecture/aligned_mode.md +++ b/docs/l2/architecture/aligned_mode.md @@ -221,7 +221,7 @@ cargo run deposit-to-batcher \ ``` cd ethrex/crates/l2 -cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf +cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf ``` > [!IMPORTANT] diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index c56536c24d2..cd22058ad5f 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -47,19 +47,19 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea264697066735822122062e3ee9344e32a3092478d16f69b9a464ebf27955eb832798df1ea9d4ad76e2364736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea2646970667358221220b0e039ea8c0311676e13d7889418046ff983762f1c8fada745b0308bb50975cc64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea264697066735822122038b42f312318b95343bd39529d5ae43fd4b5cf130d94305d19c1386761c4340364736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea26469706673582212205654c9aa2fc1a4b39f95f9565a0f7356614a926922f0d3c487423782bd5a6d3c64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212205085245e305b782b83b7254aba6d60343bf038b0c74437ee496802a22f93ee2564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212201f2f6efd6e0788ac52f20eb3b14e6a226bc32de18166247e9ba91c0379feae2964736f6c634300081d0033", "storage": { "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" @@ -68,7 +68,7 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea26469706673582212205085245e305b782b83b7254aba6d60343bf038b0c74437ee496802a22f93ee2564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212201f2f6efd6e0788ac52f20eb3b14e6a226bc32de18166247e9ba91c0379feae2964736f6c634300081d0033", "storage": { "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" @@ -77,7 +77,7 @@ "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122053e1cd3ed516d50e33c9e4998dbe10aeda0147fbf383465899e87973062cffd664736f6c634300081d0033a2646970667358221220d821642e3aab6408db6ebb650cf70371deba32d4a31ca34edb627dfd75751da864736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122047ad886fd01ebeb21075f7771acc89d9e74f348f7818d59230d8b85c2c3ba3c464736f6c634300081d0033a264697066735822122040f4e73e9c45a622caf25d8479203e048de3af10862bc51e071ab44eb21a327364736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" diff --git a/fixtures/keys/private_keys.txt b/fixtures/keys/private_keys.txt index 890bd315a9d..ac8e9738ec7 100644 --- a/fixtures/keys/private_keys.txt +++ b/fixtures/keys/private_keys.txt @@ -12,7 +12,6 @@ 0x556a4c63c314bf2a1734f34bcc2c45941b41afe3e4827d205092f3cc8d3ab11b 0x658edfde371c42f7dbdafdb73b9d28b87fff929753f74eb7c9888c2f25b02ea6 0xabea088cc1a18dda221851da62d00bdc3724368e47ae0a2516727871554859bd -0xe9ea73e0ca433882aa9d4e2311ecc4e17286121e6bd8e600e5d25d4243b2baa3 0x0ae566c7c3db3611107b876eff2dd4a27e6513642bcd4fab418a7595a14240e4 0x31950b39d586c6d3e37bc37233880ab3266505165be34c628fe5ee6746a3afec 0x547ba217be53dfe01f7d6a4af1452f8e0ba7755ca43ba8bad731d3da77fe1de7 diff --git a/fixtures/keys/private_keys_l1.txt b/fixtures/keys/private_keys_l1.txt index 92353befb95..e183ff2e202 100644 --- a/fixtures/keys/private_keys_l1.txt +++ b/fixtures/keys/private_keys_l1.txt @@ -179,7 +179,6 @@ 0xe556d12479cde2e345ba952bdae2a47f6179f4f03a491ecda414970bab5c8005 0xe76b962fc2d87e124bba333e6ff90a258760260f24f8a3c4fbceaeac68157f6e 0xe88d9382e5e4914469a23dcc27271e05aa7715ddeaee66b857a455c1fd51104a -0xe9ea73e0ca433882aa9d4e2311ecc4e17286121e6bd8e600e5d25d4243b2baa3 0xea016edc3a0dda43660a83cd7dddddfed87f34fe2849ab5c4339e9b8660e9553 0xeaa700570abf8ad30abc2c4d922f4a76475e0bf37bdc9b434faff602bfe3847b 0xeac93dc1957553f0816bc3a26d62f5ec475ecf2f02ee2a92bf9ff0214fc1fdd9 From 33930eea683915c15d3ed065e2d248f9f5edde59 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 16:10:40 -0300 Subject: [PATCH 12/88] Fix workflow --- .github/workflows/main_prover.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 906280a6b13..dd38cfdacf7 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -79,7 +79,7 @@ jobs: ETHREX_PROPOSER_BLOCK_TIME=12000 \ ETHREX_COMMITTER_COMMIT_TIME=30000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 + ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ docker compose up --build --detach --no-deps ethrex_l2 - name: Run test From 57e8526ab4d2ea28bf94e88d93520d6e55c23e40 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 17:50:58 -0300 Subject: [PATCH 13/88] Fix integration tests --- crates/l2/tests/tests.rs | 68 +++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 46fe5b62639..50f22732cbd 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -190,8 +190,8 @@ async fn l2_integration_test() -> Result<(), Box> { let mut acc_base_fees = U256::zero(); while let Some(res) = set.join_next().await { let fees_details = res??; - acc_priority_fees += fees_details.total_fees - fees_details.base_fees; - acc_base_fees += fees_details.base_fees; + acc_priority_fees += fees_details.priority_fees; + acc_base_fees += fees_details.total_fees - fees_details.priority_fees; } let coinbase_balance_after_tests = l2_client @@ -210,11 +210,13 @@ async fn l2_integration_test() -> Result<(), Box> { "Coinbase is not correct after tests" ); - assert_eq!( - fee_vault_balance_after_tests, - fee_vault_balance_before_tests + acc_base_fees, - "Fee vault is not correct after tests" - ); + if std::env::var("INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK").is_err() { + assert_eq!( + fee_vault_balance_after_tests, + fee_vault_balance_before_tests + acc_base_fees, + "Fee vault is not correct after tests" + ); + } // Not thread-safe (coinbase and bridge balance checks) test_n_withdraws( @@ -338,7 +340,7 @@ async fn test_privileged_tx_with_contract_call( println!("ptx_with_contract_call: Deploying contract on L2"); - let (deployed_contract_address, base_fees) = test_deploy( + let (deployed_contract_address, fees_details) = test_deploy( &l2_client, &init_code, &rich_wallet_private_key, @@ -413,7 +415,7 @@ async fn test_privileged_tx_with_contract_call( "ptx_with_contract_call: Event emitted with wrong value. Expected 424242, got {number_emitted}" ); - Ok(base_fees) + Ok(fees_details) } /// Test the deployment of a contract on L2 and call it from L1 using the CommonBridge contract. @@ -435,7 +437,7 @@ async fn test_privileged_tx_with_contract_call_revert( println!("ptx_with_contract_call_revert: Deploying contract on L2"); - let (deployed_contract_address, base_fees) = test_deploy( + let (deployed_contract_address, fees_details) = test_deploy( &l2_client, &init_code, &rich_wallet_private_key, @@ -457,7 +459,7 @@ async fn test_privileged_tx_with_contract_call_revert( ) .await?; - Ok(base_fees) + Ok(fees_details) } async fn find_withdrawal_with_widget( @@ -1136,7 +1138,7 @@ async fn test_transfer( "test_transfer: Performing transfer from {transferer_address:#x} to {returner_address:#x}" ); - let mut base_fees = perform_transfer( + let mut fees_details = perform_transfer( &l2_client, &transferer_private_key, returner_address, @@ -1150,7 +1152,7 @@ async fn test_transfer( "test_transfer: Performing return transfer from {returner_address:#x} to {transferer_address:#x} with amount {return_amount}" ); - base_fees += perform_transfer( + fees_details += perform_transfer( &l2_client, &returnerer_private_key, transferer_address, @@ -1158,7 +1160,7 @@ async fn test_transfer( ) .await?; - Ok(base_fees) + Ok(fees_details) } /// Test transferring ETH on L2 through a privileged transaction (deposit from L1) @@ -1503,7 +1505,7 @@ async fn test_n_withdraws( let mut base_fees = U256::zero(); for receipt in receipts { - base_fees += get_fees_details_l2(&receipt, l2_client).await.base_fees; + base_fees += get_fees_details_l2(&receipt, l2_client).await.priority_fees; } assert_eq!( @@ -1600,10 +1602,17 @@ async fn test_total_eth_l2( println!("Coinbase balance: {coinbase_balance}"); - let total_eth_on_l2 = rich_accounts_balance + coinbase_balance; + let fee_vault_balance = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + println!("Fee vault balance: {fee_vault_balance}"); - println!("Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} = {total_eth_on_l2}"); + let total_eth_on_l2 = rich_accounts_balance + coinbase_balance + fee_vault_balance; + println!( + "Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} + {fee_vault_balance} = {total_eth_on_l2}" + ); println!("Checking locked ETH on CommonBridge"); let bridge_address = bridge_address()?; @@ -1613,10 +1622,17 @@ async fn test_total_eth_l2( println!("Bridge locked ETH: {bridge_locked_eth}"); - assert!( - total_eth_on_l2 <= bridge_locked_eth, - "Total ETH on L2 ({total_eth_on_l2}) is greater than bridge locked ETH ({bridge_locked_eth})" - ); + if std::env::var("INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK").is_err() { + assert!( + total_eth_on_l2 == bridge_locked_eth, + "Total ETH on L2 ({total_eth_on_l2}) differs from bridge locked ETH ({bridge_locked_eth})" + ); + } else { + assert!( + total_eth_on_l2 < bridge_locked_eth, + "Total ETH on L2 ({total_eth_on_l2}) is greater than bridge locked ETH ({bridge_locked_eth})" + ); + } Ok(()) } @@ -1791,7 +1807,7 @@ fn bridge_owner_private_key() -> SecretKey { #[derive(Debug, Default)] struct FeesDetails { total_fees: U256, - base_fees: U256, + priority_fees: U256, } impl Add for FeesDetails { @@ -1800,7 +1816,7 @@ impl Add for FeesDetails { fn add(self, other: Self) -> Self { Self { total_fees: self.total_fees + other.total_fees, - base_fees: self.base_fees + other.base_fees, + priority_fees: self.priority_fees + other.priority_fees, } } } @@ -1808,7 +1824,7 @@ impl Add for FeesDetails { impl AddAssign for FeesDetails { fn add_assign(&mut self, other: Self) { self.total_fees += other.total_fees; - self.base_fees += other.base_fees; + self.priority_fees += other.priority_fees; } } @@ -1830,11 +1846,11 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> let max_priority_fee_per_gas_transfer: U256 = (effective_gas_price - base_fee_per_gas).into(); - let base_fees = max_priority_fee_per_gas_transfer.mul(tx_receipt.tx_info.gas_used); + let priority_fees = max_priority_fee_per_gas_transfer.mul(tx_receipt.tx_info.gas_used); FeesDetails { total_fees, - base_fees, + priority_fees, } } From 818eb12ad6a8446b296a2c27e81184890ab36c75 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 18:25:37 -0300 Subject: [PATCH 14/88] Fix based workflow --- .github/workflows/pr-main_l2.yaml | 1 + cmd/ethrex/l2/options.rs | 3 +-- docs/l2/architecture/aligned_mode.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 0e297c28583..554d2e6c420 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -262,6 +262,7 @@ jobs: RUST_LOG=info,ethrex_prover_lib=debug make init-prover & docker logs --follow ethrex_l2 & PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ + INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true \ cargo test l2 --release -- --nocapture --test-threads=1 killall ethrex -s SIGINT diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 01bae8170a1..191b5371b5d 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -391,8 +391,7 @@ pub struct BlockProducerOptions { long = "block-producer.fee-vault-address", value_name = "ADDRESS", env = "ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS", - help_heading = "Block producer options", - required_unless_present = "dev" + help_heading = "Block producer options" )] pub fee_vault_address: Option
, #[arg( diff --git a/docs/l2/architecture/aligned_mode.md b/docs/l2/architecture/aligned_mode.md index d85fb399024..6690ed88965 100644 --- a/docs/l2/architecture/aligned_mode.md +++ b/docs/l2/architecture/aligned_mode.md @@ -221,7 +221,7 @@ cargo run deposit-to-batcher \ ``` cd ethrex/crates/l2 -cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf +cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf ``` > [!IMPORTANT] From d7b02b98e3e47cec138a5029d6d01678785e1ff1 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 18:47:06 -0300 Subject: [PATCH 15/88] Remove fee_Vault from add_block --- cmd/ethrex/bench/build_block_benchmark.rs | 2 +- cmd/ethrex/cli.rs | 2 +- cmd/ethrex_replay/src/cli.rs | 9 ++----- crates/blockchain/blockchain.rs | 8 ++---- crates/blockchain/smoke_test.rs | 26 +++++++++---------- crates/l2/based/block_fetcher.rs | 2 +- .../networking/p2p/rlpx/l2/l2_connection.rs | 2 +- crates/networking/p2p/sync.rs | 2 +- crates/networking/rpc/engine/payload.rs | 2 +- fixtures/genesis/l2.json | 14 +++++----- tooling/ef_tests/blockchain/test_runner.rs | 2 +- .../state_v2/src/modules/block_runner.rs | 2 +- 12 files changed, 32 insertions(+), 41 deletions(-) diff --git a/cmd/ethrex/bench/build_block_benchmark.rs b/cmd/ethrex/bench/build_block_benchmark.rs index 52668afa37b..ffcb72241b6 100644 --- a/cmd/ethrex/bench/build_block_benchmark.rs +++ b/cmd/ethrex/bench/build_block_benchmark.rs @@ -201,7 +201,7 @@ pub async fn bench_payload(input: &(Arc, Block, &Store)) -> (Duratio // 3. engine_newPayload is called, this eventually calls Blockchain::add_block // which takes transactions from the mempool and fills the block with them. let since = Instant::now(); - blockchain.add_block(&block, None).await.unwrap(); + blockchain.add_block(&block).await.unwrap(); let executed = Instant::now(); // EXTRA: Sanity check to not benchmark n empty block. let hash = &block.hash(); diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index c9ba42dd9be..066fe5dd819 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -435,7 +435,7 @@ pub async fn import_blocks( } blockchain - .add_block(block, None) + .add_block(block) .await .inspect_err(|err| match err { // Block number 1's parent not found, the chain must not belong to the same network as the genesis file diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index fc7f7b7f46d..0f1df006380 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -382,9 +382,6 @@ impl EthrexReplayCommand { let (eth_client, network) = setup(&opts).await?; - #[cfg(not(feature = "l2"))] - let fee_vault = None; - #[cfg(feature = "l2")] let fee_vault = get_fee_vault_address(ð_client).await?; let cache = get_batchdata(eth_client, network, batch, fee_vault).await?; @@ -600,9 +597,7 @@ async fn replay_no_zkvm(cache: Cache, opts: &EthrexReplayOptions) -> eyre::Resul info!("Executing block {} on {}", block.header.number, network); let start_time = Instant::now(); - blockchain - .add_block(&block, cache.l2_fields.and_then(|f| f.fee_vault)) - .await?; + blockchain.add_block(&block).await?; let duration = start_time.elapsed(); info!("add_block execution time: {:.2?}", duration); @@ -962,7 +957,7 @@ pub async fn produce_l1_block( err => ethrex_rpc::RpcErr::Internal(err.to_string()), })?; - blockchain.add_block(&block, None).await?; + blockchain.add_block(&block).await?; let new_block_hash = block.hash(); diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 16e56d0bee6..712eccd94bd 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -408,13 +408,9 @@ impl Blockchain { .map_err(|e| e.into()) } - pub async fn add_block( - &self, - block: &Block, - fee_vault: Option
, - ) -> Result<(), ChainError> { + pub async fn add_block(&self, block: &Block) -> Result<(), ChainError> { let since = Instant::now(); - let (res, updates) = self.execute_block(block, fee_vault).await?; + let (res, updates) = self.execute_block(block, None).await?; let executed = Instant::now(); // Apply the account updates over the last block's state and compute the new state root diff --git a/crates/blockchain/smoke_test.rs b/crates/blockchain/smoke_test.rs index 0bfa7421da1..8f8b508cfe1 100644 --- a/crates/blockchain/smoke_test.rs +++ b/crates/blockchain/smoke_test.rs @@ -29,7 +29,7 @@ mod blockchain_integration_test { // Add first block. We'll make it canonical. let block_1a = new_block(&store, &genesis_header).await; let hash_1a = block_1a.hash(); - blockchain.add_block(&block_1a, None).await.unwrap(); + blockchain.add_block(&block_1a).await.unwrap(); store .forkchoice_update(None, 1, hash_1a, None, None) .await @@ -43,7 +43,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_1b = block_1b.hash(); blockchain - .add_block(&block_1b, None) + .add_block(&block_1b) .await .expect("Could not add block 1b."); let retrieved_1b = store.get_block_header_by_hash(hash_1b).unwrap().unwrap(); @@ -55,7 +55,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1b.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2, None) + .add_block(&block_2) .await .expect("Could not add block 2."); let retrieved_2 = store.get_block_header_by_hash(hash_2).unwrap(); @@ -91,7 +91,7 @@ mod blockchain_integration_test { // Build a single valid block. let block_1 = new_block(&store, &genesis_header).await; let hash_1 = block_1.hash(); - blockchain.add_block(&block_1, None).await.unwrap(); + blockchain.add_block(&block_1).await.unwrap(); apply_fork_choice(&store, hash_1, H256::zero(), H256::zero()) .await .unwrap(); @@ -100,7 +100,7 @@ mod blockchain_integration_test { let mut block_2 = new_block(&store, &block_1.header).await; block_2.header.parent_hash = H256::random(); let hash_2 = block_2.hash(); - let result = blockchain.add_block(&block_2, None).await; + let result = blockchain.add_block(&block_2).await; assert!(matches!(result, Err(ChainError::ParentNotFound))); // block 2 should now be pending. @@ -126,7 +126,7 @@ mod blockchain_integration_test { // Add first block. Not canonical. let block_1a = new_block(&store, &genesis_header).await; let hash_1a = block_1a.hash(); - blockchain.add_block(&block_1a, None).await.unwrap(); + blockchain.add_block(&block_1a).await.unwrap(); let retrieved_1a = store.get_block_header_by_hash(hash_1a).unwrap().unwrap(); assert!(!is_canonical(&store, 1, hash_1a).await.unwrap()); @@ -135,7 +135,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_1b = block_1b.hash(); blockchain - .add_block(&block_1b, None) + .add_block(&block_1b) .await .expect("Could not add block 1b."); apply_fork_choice(&store, hash_1b, genesis_hash, genesis_hash) @@ -152,7 +152,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1b.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2, None) + .add_block(&block_2) .await .expect("Could not add block 2."); apply_fork_choice(&store, hash_2, genesis_hash, genesis_hash) @@ -199,7 +199,7 @@ mod blockchain_integration_test { let block_1 = new_block(&store, &genesis_header).await; let hash_1 = block_1.hash(); blockchain - .add_block(&block_1, None) + .add_block(&block_1) .await .expect("Could not add block 1b."); @@ -207,7 +207,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2, None) + .add_block(&block_2) .await .expect("Could not add block 2."); @@ -251,7 +251,7 @@ mod blockchain_integration_test { // Add block at height 1. let block_1 = new_block(&store, &genesis_header).await; blockchain - .add_block(&block_1, None) + .add_block(&block_1) .await .expect("Could not add block 1b."); @@ -259,7 +259,7 @@ mod blockchain_integration_test { let block_2 = new_block(&store, &block_1.header).await; let hash_2 = block_2.hash(); blockchain - .add_block(&block_2, None) + .add_block(&block_2) .await .expect("Could not add block 2."); @@ -279,7 +279,7 @@ mod blockchain_integration_test { let block_1b = new_block(&store, &genesis_header).await; let hash_b = block_1b.hash(); blockchain - .add_block(&block_1b, None) + .add_block(&block_1b) .await .expect("Could not add block b."); diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 7ee8a9b64d8..7e5f6088192 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -269,7 +269,7 @@ impl BlockFetcher { async fn store_batch(&mut self, batch: &[Block]) -> Result<(), BlockFetcherError> { for block in batch.iter() { - self.blockchain.add_block(block, None).await?; + self.blockchain.add_block(block).await?; let block_hash = block.hash(); diff --git a/crates/networking/p2p/rlpx/l2/l2_connection.rs b/crates/networking/p2p/rlpx/l2/l2_connection.rs index baff7edbe18..5129dd4e36a 100644 --- a/crates/networking/p2p/rlpx/l2/l2_connection.rs +++ b/crates/networking/p2p/rlpx/l2/l2_connection.rs @@ -364,7 +364,7 @@ async fn process_new_block(established: &mut Established, msg: &NewBlock) -> Res } established .blockchain - .add_block(&block, None) + .add_block(&block) .await .inspect_err(|e| { log_peer_error( diff --git a/crates/networking/p2p/sync.rs b/crates/networking/p2p/sync.rs index 8808cc4819d..1e038583836 100644 --- a/crates/networking/p2p/sync.rs +++ b/crates/networking/p2p/sync.rs @@ -440,7 +440,7 @@ impl Syncer { if sync_head_found { let mut last_valid_hash = H256::default(); for block in blocks { - blockchain.add_block(&block, None).await.map_err(|e| { + blockchain.add_block(&block).await.map_err(|e| { ( e, Some(BatchBlockProcessingFailure { diff --git a/crates/networking/rpc/engine/payload.rs b/crates/networking/rpc/engine/payload.rs index e94d09f4261..66f8cd9a632 100644 --- a/crates/networking/rpc/engine/payload.rs +++ b/crates/networking/rpc/engine/payload.rs @@ -637,7 +637,7 @@ async fn try_execute_payload( // Execute and store the block info!(%block_hash, %block_number, "Executing payload"); - match context.blockchain.add_block(block, None).await { + match context.blockchain.add_block(block).await { Err(ChainError::ParentNotFound) => { // Start sync context.syncer.sync_to_head(block_hash); diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index cd22058ad5f..b964f23e120 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -47,19 +47,19 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea2646970667358221220b0e039ea8c0311676e13d7889418046ff983762f1c8fada745b0308bb50975cc64736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea264697066735822122062e3ee9344e32a3092478d16f69b9a464ebf27955eb832798df1ea9d4ad76e2364736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea26469706673582212205654c9aa2fc1a4b39f95f9565a0f7356614a926922f0d3c487423782bd5a6d3c64736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea264697066735822122038b42f312318b95343bd39529d5ae43fd4b5cf130d94305d19c1386761c4340364736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212201f2f6efd6e0788ac52f20eb3b14e6a226bc32de18166247e9ba91c0379feae2964736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122012233c84da20adbad70e7dcdaf998f500bd4fe5f2afcc8a5a017db4607df226164736f6c634300081d0033", "storage": { "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" @@ -68,16 +68,16 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212201f2f6efd6e0788ac52f20eb3b14e6a226bc32de18166247e9ba91c0379feae2964736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122012233c84da20adbad70e7dcdaf998f500bd4fe5f2afcc8a5a017db4607df226164736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122047ad886fd01ebeb21075f7771acc89d9e74f348f7818d59230d8b85c2c3ba3c464736f6c634300081d0033a264697066735822122040f4e73e9c45a622caf25d8479203e048de3af10862bc51e071ab44eb21a327364736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122053e1cd3ed516d50e33c9e4998dbe10aeda0147fbf383465899e87973062cffd664736f6c634300081d0033a2646970667358221220d821642e3aab6408db6ebb650cf70371deba32d4a31ca34edb627dfd75751da864736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" diff --git a/tooling/ef_tests/blockchain/test_runner.rs b/tooling/ef_tests/blockchain/test_runner.rs index 040562d9efd..ebec3d35af2 100644 --- a/tooling/ef_tests/blockchain/test_runner.rs +++ b/tooling/ef_tests/blockchain/test_runner.rs @@ -141,7 +141,7 @@ async fn run( let hash = block.hash(); // Attempt to add the block as the head of the chain - let chain_result = blockchain.add_block(&block, None).await; + let chain_result = blockchain.add_block(&block).await; match chain_result { Err(error) => { diff --git a/tooling/ef_tests/state_v2/src/modules/block_runner.rs b/tooling/ef_tests/state_v2/src/modules/block_runner.rs index 255ba22bb11..dc63679a529 100644 --- a/tooling/ef_tests/state_v2/src/modules/block_runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/block_runner.rs @@ -146,7 +146,7 @@ pub async fn run_test(test: &Test, test_case: &TestCase) -> Result<(), RunnerErr let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false); - let result = blockchain.add_block(&block, None).await; + let result = blockchain.add_block(&block).await; if result.is_err() && test_case.post.expected_exceptions.is_none() { return Err(RunnerError::Custom( From df483ca47b8eee316c6363cc8ed76d3d9192ecf3 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 24 Sep 2025 18:50:42 -0300 Subject: [PATCH 16/88] Rename base_fees to priority fees in test --- crates/l2/tests/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 50f22732cbd..ecb62d7c089 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -1503,14 +1503,14 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let mut base_fees = U256::zero(); + let mut priority_fees = U256::zero(); for receipt in receipts { - base_fees += get_fees_details_l2(&receipt, l2_client).await.priority_fees; + priority_fees += get_fees_details_l2(&receipt, l2_client).await.priority_fees; } assert_eq!( coinbase_balance_after_withdrawal, - coinbase_balance_before_withdrawal + base_fees, + coinbase_balance_before_withdrawal + priority_fees, "Coinbase balance didn't increase as expected after withdrawal" ); From e7ffedd2bd3493570f20d5a18c9b51210414315e Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 10:13:01 -0300 Subject: [PATCH 17/88] Update cli.md --- crates/l2/tests/tests.rs | 4 +- docs/CLI.md | 111 ++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index ecb62d7c089..c49ba576000 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -268,7 +268,7 @@ async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result Result {final_impl:#x}"); assert_ne!(initial_impl, final_impl); - Ok(deploy_base_fees) + Ok(fees_details) } /// In this test we deploy a contract on L2 and call it from L1 using the CommonBridge contract. diff --git a/docs/CLI.md b/docs/CLI.md index ea10f9b0d08..6cae47f3379 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -122,17 +122,19 @@ Commands: blobs-saver Launch a server that listens for Blobs submissions and saves them offline. reconstruct Reconstructs the L2 state from L1 blobs. revert-batch Reverts unverified batches. + pause Pause L1 contracts + unpause Unpause L1 contracts deploy Deploy in L1 all contracts needed by an L2. help Print this message or the help of the given subcommand(s) Options: -t, --tick-rate time in ms between two ticks - + [default: 1000] --batch-widget-height - + -h, --help Print help (see a summary with '-h') @@ -140,14 +142,14 @@ Options: Node options: --network Alternatively, the name of a known network can be provided instead to use its preset genesis file and include its preset bootnodes. The networks currently supported include holesky, sepolia, hoodi and mainnet. If not specified, defaults to mainnet. - + [env: ETHREX_NETWORK=] --datadir If the datadir is the word `memory`, ethrex will use the `InMemory Engine`. - + [env: ETHREX_DATADIR=] - [default: /home/runner/.local/share/ethrex] + [default: "/Users/gaston/Library/Application Support/ethrex"] --force Delete the database without confirmation. @@ -167,7 +169,7 @@ Node options: --log.level Possible values: info, debug, trace, warn, error - + [default: INFO] P2P options: @@ -176,53 +178,54 @@ P2P options: --syncmode Can be either "full" or "snap" with "full" as default value. - + [default: full] --p2p.enabled + --p2p.port - TCP port for P2P. - + TCP port for P2P protocol. + [default: 30303] --discovery.port UDP port for P2P discovery. - + [default: 30303] RPC options: --http.addr
Listening address for the http rpc server. - + [env: ETHREX_HTTP_ADDR=] - [default: localhost] + [default: 0.0.0.0] --http.port Listening port for the http rpc server. - + [env: ETHREX_HTTP_PORT=] [default: 8545] --authrpc.addr
Listening address for the authenticated rpc server. - - [default: localhost] + + [default: 127.0.0.1] --authrpc.port Listening port for the authenticated rpc server. - + [default: 8551] --authrpc.jwtsecret Receives the jwt secret used for authenticated rpc requests. - + [default: jwt.hex] Eth options: --eth.rpc-url ... List of rpc urls to use. - + [env: ETHREX_ETH_RPC_URL=] --eth.maximum-allowed-max-fee-per-gas @@ -255,9 +258,9 @@ L1 Watcher options: --watcher.watch-interval How often the L1 watcher checks for new blocks in milliseconds. - + [env: ETHREX_WATCHER_WATCH_INTERVAL=] - [default: 1000] + [default: 12000] --watcher.max-block-step [env: ETHREX_WATCHER_MAX_BLOCK_STEP=] @@ -265,20 +268,29 @@ L1 Watcher options: --watcher.block-delay Number of blocks the L1 watcher waits before trusting an L1 block. - + [env: ETHREX_WATCHER_BLOCK_DELAY=] [default: 10] Block producer options: --block-producer.block-time How often does the sequencer produce new blocks to the L1 in milliseconds. - + [env: ETHREX_BLOCK_PRODUCER_BLOCK_TIME=] [default: 5000] --block-producer.coinbase-address
[env: ETHREX_BLOCK_PRODUCER_COINBASE_ADDRESS=] + --block-producer.fee-vault-address
+ [env: ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=] + + --block-producer.block-gas-limit + Maximum gas limit for the L2 blocks. + + [env: ETHREX_BLOCK_PRODUCER_BLOCK_GAS_LIMIT=] + [default: 30000000] + Proposer options: --elasticity-multiplier [env: ETHREX_PROPOSER_ELASTICITY_MULTIPLIER=] @@ -287,17 +299,17 @@ Proposer options: L1 Committer options: --committer.l1-private-key Private key of a funded account that the sequencer will use to send commit txs to the L1. - + [env: ETHREX_COMMITTER_L1_PRIVATE_KEY=] --committer.remote-signer-url URL of a Web3Signer-compatible server to remote sign instead of a local private key. - + [env: ETHREX_COMMITTER_REMOTE_SIGNER_URL=] --committer.remote-signer-public-key Public key to request the remote signature from. - + [env: ETHREX_COMMITTER_REMOTE_SIGNER_PUBLIC_KEY=] --l1.on-chain-proposer-address
@@ -305,10 +317,20 @@ L1 Committer options: --committer.commit-time How often does the sequencer commit new blocks to the L1 in milliseconds. - + [env: ETHREX_COMMITTER_COMMIT_TIME=] [default: 60000] + --committer.batch-gas-limit + Maximum gas limit for the batch + + [env: ETHREX_COMMITTER_BATCH_GAS_LIMIT=] + + --committer.first-wake-up-time + Time to wait before the sequencer seals a batch when started. After committing the first batch, `committer.commit-time` will be used. + + [env: ETHREX_COMMITTER_FIRST_WAKE_UP_TIME=] + --committer.arbitrary-base-blob-gas-price [env: ETHREX_COMMITTER_ARBITRARY_BASE_BLOB_GAS_PRICE=] [default: 1000000000] @@ -316,27 +338,27 @@ L1 Committer options: Proof coordinator options: --proof-coordinator.l1-private-key Private key of of a funded account that the sequencer will use to send verify txs to the L1. Has to be a different account than --committer-l1-private-key. - + [env: ETHREX_PROOF_COORDINATOR_L1_PRIVATE_KEY=] --proof-coordinator.tdx-private-key Private key of of a funded account that the TDX tool that will use to send the tdx attestation to L1. - + [env: ETHREX_PROOF_COORDINATOR_TDX_PRIVATE_KEY=] --proof-coordinator.remote-signer-url URL of a Web3Signer-compatible server to remote sign instead of a local private key. - + [env: ETHREX_PROOF_COORDINATOR_REMOTE_SIGNER_URL=] --proof-coordinator.remote-signer-public-key Public key to request the remote signature from. - + [env: ETHREX_PROOF_COORDINATOR_REMOTE_SIGNER_PUBLIC_KEY=] --proof-coordinator.addr Set it to 0.0.0.0 to allow connections from other machines. - + [env: ETHREX_PROOF_COORDINATOR_LISTEN_ADDRESS=] [default: 127.0.0.1] @@ -346,13 +368,10 @@ Proof coordinator options: --proof-coordinator.send-interval How often does the proof coordinator send proofs to the L1 in milliseconds. - + [env: ETHREX_PROOF_COORDINATOR_SEND_INTERVAL=] [default: 5000] - --proof-coordinator.dev-mode - [env: ETHREX_PROOF_COORDINATOR_DEV_MODE=] - Based options: --state-updater.sequencer-registry
[env: ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=] @@ -382,30 +401,39 @@ Aligned options: --aligned.beacon-url ... List of beacon urls to use. - + [env: ETHREX_ALIGNED_BEACON_URL=] --aligned-network L1 network name for Aligned sdk - + [env: ETHREX_ALIGNED_NETWORK=] [default: devnet] --aligned.fee-estimate Fee estimate for Aligned sdk - + [env: ETHREX_ALIGNED_FEE_ESTIMATE=] [default: instant] --aligned-sp1-elf-path Path to the SP1 elf. This is used for proof verification. - + [env: ETHREX_ALIGNED_SP1_ELF_PATH=] +Admin server options: + --admin-server.addr + [env: ETHREX_ADMIN_SERVER_LISTEN_ADDRESS=] + [default: 127.0.0.1] + + --admin-server.port + [env: ETHREX_ADMIN_SERVER_LISTEN_PORT=] + [default: 5555] + L2 options: --validium If true, L2 will run on validium mode as opposed to the default rollup mode, meaning it will not publish state diffs to the L1. - + [env: ETHREX_L2_VALIDIUM=] --sponsorable-addresses @@ -413,13 +441,14 @@ L2 options: --sponsor-private-key The private key of ethrex L2 transactions sponsor. - + [env: SPONSOR_PRIVATE_KEY=] [default: 0xffd790338a2798b648806fc8635ac7bf14af15425fed0c8f25bcc5febaa9b192] Monitor options: --no-monitor [env: ETHREX_NO_MONITOR=] + ``` ## ethrex l2 prover From 061a61735215e3de381f284eda42ccb38861a4d8 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 12:07:12 -0300 Subject: [PATCH 18/88] Add disclaimer to docs --- crates/l2/sequencer/block_producer.rs | 7 +++++++ docs/l2/running.md | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 868c0c41111..3d1fb4005ab 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -87,6 +87,13 @@ impl BlockProducer { elasticity_multiplier, block_gas_limit, } = config; + + if coinbase_address == fee_vault_address { + warn!( + "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected." + ); + } + Self { store, blockchain, diff --git a/docs/l2/running.md b/docs/l2/running.md index 9eb53d27341..19967d204b2 100644 --- a/docs/l2/running.md +++ b/docs/l2/running.md @@ -25,12 +25,17 @@ First we need to set some environment variables. --committer_l1_private_key \ --proof_coordinator_l1_private_key \ --block-producer.coinbase-address \ + --block-producer.fee-vault-address ``` For further configuration take a look at the [CLI document](../CLI.md#ethrex-l2) This will start an ethrex l2 sequencer with the RPC server listening at `http://localhost:1729` and the proof coordinator server listening at `http://localhost:3900` +> **Note:** If `--block-producer.fee-vault-address` is set, the sequencer will send collected base fees to that address instead of burning them. +> Be cautious: if the fee vault address is the same as the coinbase address, the coinbase balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. + + ## Starting a prover server ```sh From 80d57dc9c2597be64bd39cde16d4aeffa19a5b5b Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 13:37:47 -0300 Subject: [PATCH 19/88] Move fee_vault to blockchain struct --- cmd/ethrex/bench/build_block_benchmark.rs | 1 + cmd/ethrex/cli.rs | 2 +- cmd/ethrex/initializers.rs | 8 +- cmd/ethrex/l2/initializers.rs | 10 ++- cmd/ethrex_replay/src/cli.rs | 27 +++---- cmd/ethrex_replay/src/run.rs | 13 ++-- crates/blockchain/blockchain.rs | 25 ++++--- crates/blockchain/payload.rs | 5 +- crates/blockchain/tracing.rs | 19 ++--- crates/l2/based/block_fetcher.rs | 2 +- crates/l2/networking/rpc/l2/fee_vault.rs | 6 +- crates/l2/networking/rpc/rpc.rs | 2 - .../prover/src/guest_program/src/execution.rs | 4 +- crates/l2/sequencer/block_producer.rs | 15 ++-- .../block_producer/payload_builder.rs | 9 ++- crates/l2/sequencer/l1_committer.rs | 6 +- crates/l2/sequencer/proof_coordinator.rs | 6 +- .../networking/rpc/debug/execution_witness.rs | 2 +- crates/networking/rpc/eth/transaction.rs | 11 +-- crates/networking/rpc/rpc.rs | 4 - crates/networking/rpc/tracing.rs | 2 - crates/networking/rpc/utils.rs | 2 - crates/vm/backends/mod.rs | 74 ++++++++++--------- crates/vm/backends/revm/helpers.rs | 2 - crates/vm/backends/revm/mod.rs | 4 +- crates/vm/backends/revm/tracing.rs | 2 - crates/vm/tracing.rs | 25 +++---- fixtures/genesis/l2.json | 8 +- .../state_v2/src/modules/block_runner.rs | 2 +- 29 files changed, 141 insertions(+), 157 deletions(-) diff --git a/cmd/ethrex/bench/build_block_benchmark.rs b/cmd/ethrex/bench/build_block_benchmark.rs index ffcb72241b6..40a4697c896 100644 --- a/cmd/ethrex/bench/build_block_benchmark.rs +++ b/cmd/ethrex/bench/build_block_benchmark.rs @@ -238,6 +238,7 @@ pub fn build_block_benchmark(c: &mut Criterion) { store_with_genesis.clone(), BlockchainType::L1, // TODO: Should we support L2? false, + None, ); fill_mempool(&block_chain, accounts).await; diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index 066fe5dd819..ac7f6321a5d 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -374,7 +374,7 @@ pub async fn import_blocks( let start_time = Instant::now(); init_datadir(datadir); let store = init_store(datadir, genesis).await; - let blockchain = init_blockchain(store.clone(), blockchain_type, false); + let blockchain = init_blockchain(store.clone(), blockchain_type, false, None); let path_metadata = metadata(path).expect("Failed to read path"); // If it's an .rlp file it will be just one chain, but if it's a directory there can be multiple chains. diff --git a/cmd/ethrex/initializers.rs b/cmd/ethrex/initializers.rs index 7bdf1d1cdfa..55025f55c78 100644 --- a/cmd/ethrex/initializers.rs +++ b/cmd/ethrex/initializers.rs @@ -6,7 +6,7 @@ use crate::{ }, }; use ethrex_blockchain::{Blockchain, BlockchainType}; -use ethrex_common::types::Genesis; +use ethrex_common::{Address, types::Genesis}; use ethrex_config::networks::Network; use ethrex_metrics::profiling::{FunctionProfilingLayer, initialize_block_processing_profile}; @@ -118,12 +118,13 @@ pub fn init_blockchain( store: Store, blockchain_type: BlockchainType, perf_logs_enabled: bool, + fee_vault: Option
, ) -> Arc { #[cfg(feature = "revm")] info!("Initiating blockchain with revm"); #[cfg(not(feature = "revm"))] info!("Initiating blockchain with levm"); - Blockchain::new(store, blockchain_type, perf_logs_enabled).into() + Blockchain::new(store, blockchain_type, perf_logs_enabled, fee_vault).into() } #[allow(clippy::too_many_arguments)] @@ -164,7 +165,6 @@ pub async fn init_rpc_api( get_client_version(), log_filter_handler, gas_ceil, - None, ); tracker.spawn(rpc_api); @@ -389,7 +389,7 @@ pub async fn init_l1( #[cfg(feature = "sync-test")] set_sync_block(&store).await; - let blockchain = init_blockchain(store.clone(), BlockchainType::L1, true); + let blockchain = init_blockchain(store.clone(), BlockchainType::L1, true, None); let signer = get_signer(datadir); diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 21bd7355724..0005757e57d 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -49,7 +49,6 @@ async fn init_rpc_api( rollup_store: StoreRollup, log_filter_handler: Option>, gas_ceil: Option, - fee_vault: Option
, ) { let peer_handler = PeerHandler::new(peer_table); @@ -82,7 +81,6 @@ async fn init_rpc_api( rollup_store, log_filter_handler, gas_ceil.unwrap_or(DEFAULT_BUILDER_GAS_CEIL), - fee_vault, ); tracker.spawn(rpc_api); @@ -172,7 +170,12 @@ pub async fn init_l2( let store = init_store(&datadir, genesis).await; let rollup_store = init_rollup_store(&rollup_store_dir).await; - let blockchain = init_blockchain(store.clone(), BlockchainType::L2, true); + let blockchain = init_blockchain( + store.clone(), + BlockchainType::L2, + true, + opts.sequencer_opts.block_producer_opts.fee_vault_address, + ); let signer = get_signer(&datadir); @@ -205,7 +208,6 @@ pub async fn init_l2( rollup_store.clone(), log_filter_handler, Some(opts.sequencer_opts.block_producer_opts.block_gas_limit), - opts.sequencer_opts.block_producer_opts.fee_vault_address, ) .await; diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index 0f1df006380..d9731aa31e6 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -859,7 +859,12 @@ pub async fn replay_custom_l1_blocks( store_inner }; - let blockchain = Arc::new(Blockchain::new(store.clone(), BlockchainType::L1, false)); + let blockchain = Arc::new(Blockchain::new( + store.clone(), + BlockchainType::L1, + false, + None, + )); let blocks = produce_l1_blocks( blockchain.clone(), @@ -870,9 +875,7 @@ pub async fn replay_custom_l1_blocks( ) .await?; - let execution_witness = blockchain - .generate_witness_for_blocks(&blocks, None) - .await?; + let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; let chain_config = execution_witness.chain_config; let cache = Cache::new( @@ -1001,7 +1004,12 @@ pub async fn replay_custom_l2_blocks( rollup_store }; - let blockchain = Arc::new(Blockchain::new(store.clone(), BlockchainType::L2, false)); + let blockchain = Arc::new(Blockchain::new( + store.clone(), + BlockchainType::L2, + false, + fee_vault, + )); let genesis_hash = genesis.get_block().hash(); @@ -1012,13 +1020,10 @@ pub async fn replay_custom_l2_blocks( genesis_hash, genesis.timestamp + 1, n_blocks, - fee_vault, ) .await?; - let execution_witness = blockchain - .generate_witness_for_blocks(&blocks, fee_vault) - .await?; + let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; let cache = Cache::new( blocks, @@ -1044,7 +1049,6 @@ pub async fn produce_custom_l2_blocks( head_block_hash: H256, initial_timestamp: u64, n_blocks: u64, - fee_vault: Option
, ) -> eyre::Result> { let mut blocks = Vec::new(); let mut current_parent_hash = head_block_hash; @@ -1059,7 +1063,6 @@ pub async fn produce_custom_l2_blocks( current_parent_hash, current_timestamp, &mut last_privilege_nonce, - fee_vault, ) .await?; current_parent_hash = block.hash(); @@ -1078,7 +1081,6 @@ pub async fn produce_custom_l2_block( head_block_hash: H256, timestamp: u64, last_privilege_nonce: &mut Option, - fee_vault: Option
, ) -> eyre::Result { let build_payload_args = BuildPayloadArgs { parent: head_block_hash, @@ -1100,7 +1102,6 @@ pub async fn produce_custom_l2_block( store, last_privilege_nonce, DEFAULT_BUILDER_GAS_CEIL, - fee_vault, ) .await?; diff --git a/cmd/ethrex_replay/src/run.rs b/cmd/ethrex_replay/src/run.rs index 0ff45c12d7c..09c16f4dee1 100644 --- a/cmd/ethrex_replay/src/run.rs +++ b/cmd/ethrex_replay/src/run.rs @@ -111,16 +111,13 @@ pub async fn run_tx(cache: Cache, tx_hash: H256) -> eyre::Result<(Receipt, Vec>>, + /// If set, collected base fees will be sent to this address instead of being burned + pub fee_vault: Option
, } #[derive(Debug, Clone)] @@ -94,7 +96,12 @@ fn log_batch_progress(batch_size: u32, current_block: u32) { } impl Blockchain { - pub fn new(store: Store, blockchain_type: BlockchainType, perf_logs_enabled: bool) -> Self { + pub fn new( + store: Store, + blockchain_type: BlockchainType, + perf_logs_enabled: bool, + fee_vault: Option
, + ) -> Self { Self { storage: store, mempool: Mempool::new(), @@ -102,6 +109,7 @@ impl Blockchain { r#type: blockchain_type, payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled, + fee_vault, } } @@ -113,6 +121,7 @@ impl Blockchain { r#type: BlockchainType::default(), payloads: Arc::new(TokioMutex::new(Vec::new())), perf_logs_enabled: false, + fee_vault: None, } } @@ -120,7 +129,6 @@ impl Blockchain { async fn execute_block( &self, block: &Block, - fee_vault: Option
, ) -> Result<(BlockExecutionResult, Vec), ChainError> { // Validate if it can be the new head and find the parent let Ok(parent_header) = find_parent_header(&block.header, &self.storage) else { @@ -137,7 +145,7 @@ impl Blockchain { let vm_db = StoreVmDatabase::new(self.storage.clone(), block.header.parent_hash); let mut vm = self.new_evm(vm_db)?; - let execution_result = vm.execute_block(block, fee_vault)?; + let execution_result = vm.execute_block(block)?; let account_updates = vm.get_state_transitions()?; // Validate execution went alright @@ -158,7 +166,7 @@ impl Blockchain { ) -> Result { // Validate the block pre-execution validate_block(block, parent_header, chain_config, ELASTICITY_MULTIPLIER)?; - let execution_result = vm.execute_block(block, None)?; + let execution_result = vm.execute_block(block)?; // Validate execution went alright validate_gas_used(&execution_result.receipts, &block.header)?; validate_receipts_root(&block.header, &execution_result.receipts)?; @@ -170,7 +178,6 @@ impl Blockchain { pub async fn generate_witness_for_blocks( &self, blocks: &[Block], - fee_vault: Option
, ) -> Result { let first_block_header = blocks .first() @@ -208,11 +215,11 @@ impl Blockchain { let logger = Arc::new(DatabaseLogger::new(Arc::new(Mutex::new(Box::new(vm_db))))); let mut vm = match self.r#type { BlockchainType::L1 => Evm::new_from_db_for_l1(logger.clone()), - BlockchainType::L2 => Evm::new_from_db_for_l2(logger.clone()), + BlockchainType::L2 => Evm::new_from_db_for_l2(logger.clone(), self.fee_vault), }; // Re-execute block with logger - vm.execute_block(block, fee_vault)?; + vm.execute_block(block)?; // Gather account updates let account_updates = vm.get_state_transitions()?; @@ -410,7 +417,7 @@ impl Blockchain { pub async fn add_block(&self, block: &Block) -> Result<(), ChainError> { let since = Instant::now(); - let (res, updates) = self.execute_block(block, None).await?; + let (res, updates) = self.execute_block(block).await?; let executed = Instant::now(); // Apply the account updates over the last block's state and compute the new state root @@ -887,7 +894,7 @@ impl Blockchain { pub fn new_evm(&self, vm_db: StoreVmDatabase) -> Result { let evm = match self.r#type { BlockchainType::L1 => Evm::new_for_l1(vm_db), - BlockchainType::L2 => Evm::new_for_l2(vm_db)?, + BlockchainType::L2 => Evm::new_for_l2(vm_db, self.fee_vault)?, }; Ok(evm) } diff --git a/crates/blockchain/payload.rs b/crates/blockchain/payload.rs index f69f945f639..5d7605382b9 100644 --- a/crates/blockchain/payload.rs +++ b/crates/blockchain/payload.rs @@ -211,7 +211,6 @@ pub struct PayloadBuildContext { pub store: Store, pub vm: Evm, pub account_updates: Vec, - pub fee_vault: Option
, } impl PayloadBuildContext { @@ -235,7 +234,7 @@ impl PayloadBuildContext { let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); let vm = match blockchain_type { BlockchainType::L1 => Evm::new_for_l1(vm_db), - BlockchainType::L2 => Evm::new_for_l2(vm_db)?, + BlockchainType::L2 => Evm::new_for_l2(vm_db, fee_vault)?, }; Ok(PayloadBuildContext { @@ -251,7 +250,6 @@ impl PayloadBuildContext { store: storage.clone(), vm, account_updates: Vec::new(), - fee_vault, }) } @@ -668,7 +666,6 @@ pub fn apply_plain_transaction( &context.payload.header, &mut context.remaining_gas, head.tx.sender(), - context.fee_vault, )?; context.block_value += U256::from(gas_used) * head.tip; Ok(report) diff --git a/crates/blockchain/tracing.rs b/crates/blockchain/tracing.rs index 54f87bd8b05..291d43bb0ed 100644 --- a/crates/blockchain/tracing.rs +++ b/crates/blockchain/tracing.rs @@ -3,7 +3,7 @@ use std::{ time::Duration, }; -use ethrex_common::{Address, H256, tracing::CallTrace, types::Block}; +use ethrex_common::{H256, tracing::CallTrace, types::Block}; use ethrex_storage::Store; use ethrex_vm::{Evm, EvmError}; @@ -19,7 +19,6 @@ impl Blockchain { timeout: Duration, only_top_call: bool, with_log: bool, - fee_vault: Option
, ) -> Result { // Fetch the transaction's location and the block it is contained in let Some((_, block_hash, tx_index)) = @@ -33,14 +32,14 @@ impl Blockchain { }; // Obtain the block's parent state let mut vm = self - .rebuild_parent_state(block.header.parent_hash, reexec, fee_vault) + .rebuild_parent_state(block.header.parent_hash, reexec) .await?; // Run the block until the transaction we want to trace - vm.rerun_block(&block, Some(tx_index), fee_vault)?; + vm.rerun_block(&block, Some(tx_index))?; // Trace the transaction timeout_trace_operation(timeout, move || { - vm.trace_tx_calls(&block, tx_index, only_top_call, with_log, fee_vault) + vm.trace_tx_calls(&block, tx_index, only_top_call, with_log) }) .await } @@ -56,14 +55,13 @@ impl Blockchain { timeout: Duration, only_top_call: bool, with_log: bool, - fee_vault: Option
, ) -> Result, ChainError> { // Obtain the block's parent state let mut vm = self - .rebuild_parent_state(block.header.parent_hash, reexec, fee_vault) + .rebuild_parent_state(block.header.parent_hash, reexec) .await?; // Run anything necessary before executing the block's transactions (system calls, etc) - vm.rerun_block(&block, Some(0), fee_vault)?; + vm.rerun_block(&block, Some(0))?; // Trace each transaction // We need to do this in order to pass ownership of block & evm to a blocking process without cloning let vm = Arc::new(Mutex::new(vm)); @@ -77,7 +75,7 @@ impl Blockchain { let call_trace = timeout_trace_operation(timeout, move || { vm.lock() .map_err(|_| EvmError::Custom("Unexpected Runtime Error".to_string()))? - .trace_tx_calls(block.as_ref(), index, only_top_call, with_log, fee_vault) + .trace_tx_calls(block.as_ref(), index, only_top_call, with_log) }) .await?; call_traces.push((tx_hash, call_trace)); @@ -91,7 +89,6 @@ impl Blockchain { &self, parent_hash: H256, reexec: u32, - fee_vault: Option
, ) -> Result { // Check if we need to re-execute parent blocks let blocks_to_re_execute = @@ -114,7 +111,7 @@ impl Blockchain { let mut vm = self.new_evm(vm_db)?; // Run parents to rebuild pre-state for block in blocks_to_re_execute.iter().rev() { - vm.rerun_block(block, None, fee_vault)?; + vm.rerun_block(block, None)?; } Ok(vm) } diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 7e5f6088192..1a493cd258d 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -359,7 +359,7 @@ impl BlockFetcher { for block in batch { let vm_db = StoreVmDatabase::new(self.store.clone(), block.header.parent_hash); let mut vm = self.blockchain.new_evm(vm_db)?; - vm.execute_block(block, None) + vm.execute_block(block) .map_err(BlockFetcherError::EvmError)?; let account_updates = vm .get_state_transitions() diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/fee_vault.rs index a25d23a0802..4e84907e28d 100644 --- a/crates/l2/networking/rpc/l2/fee_vault.rs +++ b/crates/l2/networking/rpc/l2/fee_vault.rs @@ -13,7 +13,11 @@ impl RpcHandler for GetFeeVaultAddress { } async fn handle(&self, context: RpcApiContext) -> Result { - let fee_vault_address = context.l1_ctx.fee_vault.map(|addr| format!("{:#x}", addr)); + let fee_vault_address = context + .l1_ctx + .blockchain + .fee_vault + .map(|addr| format!("{:#x}", addr)); Ok(serde_json::to_value(fee_vault_address).map_err(|e| { ethrex_rpc::RpcErr::Internal(format!("Failed to serialize fee vault address: {}", e)) })?) diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index fefe3db04c4..dceb723f825 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -80,7 +80,6 @@ pub async fn start_api( rollup_store: StoreRollup, log_filter_handler: Option>, gas_ceil: u64, - fee_vault: Option
, ) -> Result<(), RpcErr> { // TODO: Refactor how filters are handled, // filters are used by the filters endpoints (eth_newFilter, eth_getFilterChanges, ...etc) @@ -101,7 +100,6 @@ pub async fn start_api( gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler, gas_ceil, - fee_vault, }, valid_delegation_addresses, sponsor_pk, diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 8a26d3f8a3d..46371a3118e 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -334,11 +334,11 @@ fn execute_stateless( // Execute block #[cfg(feature = "l2")] - let mut vm = Evm::new_for_l2(wrapped_db.clone())?; + let mut vm = Evm::new_for_l2(wrapped_db.clone(), fee_vault)?; #[cfg(not(feature = "l2"))] let mut vm = Evm::new_for_l1(wrapped_db.clone()); let result = vm - .execute_block(block, fee_vault) + .execute_block(block) .map_err(StatelessExecutionError::EvmError)?; let receipts = result.receipts; let account_updates = vm diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 3d1fb4005ab..3d8a504ed51 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -21,7 +21,7 @@ use serde::Serialize; use spawned_concurrency::tasks::{ CallResponse, CastResponse, GenServer, GenServerHandle, send_after, }; -use tracing::{debug, error, info}; +use tracing::{debug, error, info, warn}; use crate::{ BlockProducerConfig, SequencerConfig, @@ -56,7 +56,6 @@ pub struct BlockProducer { sequencer_state: SequencerState, block_time_ms: u64, coinbase_address: Address, - fee_vault_address: Option
, elasticity_multiplier: u64, rollup_store: StoreRollup, // Needed to ensure privileged tx nonces are sequential @@ -88,10 +87,12 @@ impl BlockProducer { block_gas_limit, } = config; - if coinbase_address == fee_vault_address { - warn!( - "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected." - ); + if let Some(fee_vault) = fee_vault_address { + if fee_vault == coinbase_address { + warn!( + "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", + ); + } } Self { @@ -100,7 +101,6 @@ impl BlockProducer { sequencer_state, block_time_ms: *block_time_ms, coinbase_address: *coinbase_address, - fee_vault_address: *fee_vault_address, elasticity_multiplier: *elasticity_multiplier, rollup_store, // FIXME: Initialize properly to the last privileged nonce in the chain @@ -169,7 +169,6 @@ impl BlockProducer { &self.store, &mut self.last_privileged_nonce, self.block_gas_limit, - self.fee_vault_address, ) .await?; info!( diff --git a/crates/l2/sequencer/block_producer/payload_builder.rs b/crates/l2/sequencer/block_producer/payload_builder.rs index dca43886833..760e7cbcdeb 100644 --- a/crates/l2/sequencer/block_producer/payload_builder.rs +++ b/crates/l2/sequencer/block_producer/payload_builder.rs @@ -40,14 +40,17 @@ pub async fn build_payload( store: &Store, last_privileged_nonce: &mut Option, block_gas_limit: u64, - fee_vault: Option
, ) -> Result { let since = Instant::now(); let gas_limit = payload.header.gas_limit; debug!("Building payload"); - let mut context = - PayloadBuildContext::new(payload, store, blockchain.r#type.clone(), fee_vault)?; + let mut context = PayloadBuildContext::new( + payload, + store, + blockchain.r#type.clone(), + blockchain.fee_vault, + )?; fill_transactions( blockchain.clone(), diff --git a/crates/l2/sequencer/l1_committer.rs b/crates/l2/sequencer/l1_committer.rs index 114dc361a50..d542e4c9d88 100644 --- a/crates/l2/sequencer/l1_committer.rs +++ b/crates/l2/sequencer/l1_committer.rs @@ -103,7 +103,6 @@ pub struct L1Committer { last_committed_batch: u64, /// Cancellation token for the next inbound InMessage::Commit cancellation_token: Option, - fee_vault: Option
, } #[derive(Clone, Serialize)] @@ -132,7 +131,6 @@ impl L1Committer { rollup_store: StoreRollup, based: bool, sequencer_state: SequencerState, - fee_vault: Option
, ) -> Result { let eth_client = EthClient::new_with_config( eth_config.rpc_url.iter().map(AsRef::as_ref).collect(), @@ -165,7 +163,6 @@ impl L1Committer { last_committed_batch_timestamp: 0, last_committed_batch, cancellation_token: None, - fee_vault, }) } @@ -184,7 +181,6 @@ impl L1Committer { rollup_store.clone(), cfg.based.enabled, sequencer_state, - cfg.block_producer.fee_vault_address, ) .await?; // NOTE: we spawn as blocking due to `generate_blobs_bundle` and @@ -409,7 +405,7 @@ impl L1Committer { let vm_db = StoreVmDatabase::new(self.store.clone(), block_to_commit.header.parent_hash); let mut vm = self.blockchain.new_evm(vm_db)?; - vm.execute_block(&block_to_commit, self.fee_vault)?; + vm.execute_block(&block_to_commit)?; vm.get_state_transitions()? }; diff --git a/crates/l2/sequencer/proof_coordinator.rs b/crates/l2/sequencer/proof_coordinator.rs index 7d57b88649c..79b36eace7a 100644 --- a/crates/l2/sequencer/proof_coordinator.rs +++ b/crates/l2/sequencer/proof_coordinator.rs @@ -184,7 +184,6 @@ pub struct ProofCoordinator { commit_hash: String, #[cfg(feature = "metrics")] request_timestamp: Arc>>, - fee_vault: Option
, } impl ProofCoordinator { @@ -234,7 +233,6 @@ impl ProofCoordinator { commit_hash: get_commit_hash(), #[cfg(feature = "metrics")] request_timestamp: Arc::new(Mutex::new(HashMap::new())), - fee_vault: proposer_config.fee_vault_address, }) } @@ -470,7 +468,7 @@ impl ProofCoordinator { let witness = self .blockchain - .generate_witness_for_blocks(&blocks, self.fee_vault) + .generate_witness_for_blocks(&blocks) .await .map_err(ProofCoordinatorError::from)?; @@ -504,7 +502,7 @@ impl ProofCoordinator { blob_commitment, #[cfg(feature = "l2")] blob_proof, - fee_vault: self.fee_vault, + fee_vault: self.blockchain.fee_vault, }) } diff --git a/crates/networking/rpc/debug/execution_witness.rs b/crates/networking/rpc/debug/execution_witness.rs index 2c587b09fbb..16b626fa73f 100644 --- a/crates/networking/rpc/debug/execution_witness.rs +++ b/crates/networking/rpc/debug/execution_witness.rs @@ -156,7 +156,7 @@ impl RpcHandler for ExecutionWitnessRequest { let execution_witness = context .blockchain - .generate_witness_for_blocks(&blocks, context.fee_vault) + .generate_witness_for_blocks(&blocks) .await .map_err(|e| RpcErr::Internal(format!("Failed to build execution witness {e}")))?; diff --git a/crates/networking/rpc/eth/transaction.rs b/crates/networking/rpc/eth/transaction.rs index 3d37e9131b7..4b4c7a35392 100644 --- a/crates/networking/rpc/eth/transaction.rs +++ b/crates/networking/rpc/eth/transaction.rs @@ -11,7 +11,7 @@ use crate::{ }; use ethrex_blockchain::{Blockchain, vm::StoreVmDatabase}; use ethrex_common::{ - Address, H256, U256, + H256, U256, types::{ AccessListEntry, BlockHash, BlockHeader, BlockNumber, Fork, GenericTransaction, TxKind, }, @@ -117,7 +117,6 @@ impl RpcHandler for CallRequest { context.storage, context.blockchain, fork, - context.fee_vault, )?; serde_json::to_value(format!("0x{:#x}", result.output())) .map_err(|error| RpcErr::Internal(error.to_string())) @@ -359,7 +358,7 @@ impl RpcHandler for CreateAccessListRequest { // Run transaction and obtain access list let (gas_used, access_list, error) = - vm.create_access_list(&self.transaction, &header, fork, context.fee_vault)?; + vm.create_access_list(&self.transaction, &header, fork)?; let result = AccessListResult { access_list: access_list .into_iter() @@ -484,7 +483,6 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, - context.fee_vault, ); if let Ok(ExecutionResult::Success { .. }) = result { return serde_json::to_value(format!("{TRANSACTION_GAS:#x}")) @@ -518,7 +516,6 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, - context.fee_vault, )?; let gas_used = result.gas_used(); @@ -548,7 +545,6 @@ impl RpcHandler for EstimateGasRequest { storage.clone(), blockchain.clone(), fork, - context.fee_vault, ); if let Ok(ExecutionResult::Success { .. }) = result { highest_gas_limit = middle_gas_limit; @@ -585,12 +581,11 @@ fn simulate_tx( storage: Store, blockchain: Arc, fork: Fork, - fee_vault: Option
, ) -> Result { let vm_db = StoreVmDatabase::new(storage.clone(), block_header.hash()); let mut vm = blockchain.new_evm(vm_db)?; - match vm.simulate_tx_from_generic(transaction, block_header, fork, fee_vault)? { + match vm.simulate_tx_from_generic(transaction, block_header, fork)? { ExecutionResult::Revert { gas_used: _, output, diff --git a/crates/networking/rpc/rpc.rs b/crates/networking/rpc/rpc.rs index 41754f0baf0..9588c99f6ac 100644 --- a/crates/networking/rpc/rpc.rs +++ b/crates/networking/rpc/rpc.rs @@ -49,7 +49,6 @@ use axum_extra::{ }; use bytes::Bytes; use ethrex_blockchain::Blockchain; -use ethrex_common::Address; use ethrex_common::types::DEFAULT_BUILDER_GAS_CEIL; use ethrex_p2p::peer_handler::PeerHandler; use ethrex_p2p::sync_manager::SyncManager; @@ -162,7 +161,6 @@ pub struct RpcApiContext { pub gas_tip_estimator: Arc>, pub log_filter_handler: Option>, pub gas_ceil: u64, - pub fee_vault: Option
, } #[derive(Debug, Clone)] @@ -207,7 +205,6 @@ pub async fn start_api( client_version: String, log_filter_handler: Option>, gas_ceil: Option, - fee_vault: Option
, ) -> Result<(), RpcErr> { // TODO: Refactor how filters are handled, // filters are used by the filters endpoints (eth_newFilter, eth_getFilterChanges, ...etc) @@ -227,7 +224,6 @@ pub async fn start_api( gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler, gas_ceil: gas_ceil.unwrap_or(DEFAULT_BUILDER_GAS_CEIL), - fee_vault, }; // Periodically clean up the active filters for the filters endpoints. diff --git a/crates/networking/rpc/tracing.rs b/crates/networking/rpc/tracing.rs index d2b826eae4c..dc7d8258033 100644 --- a/crates/networking/rpc/tracing.rs +++ b/crates/networking/rpc/tracing.rs @@ -113,7 +113,6 @@ impl RpcHandler for TraceTransactionRequest { timeout, config.only_top_call, config.with_log, - context.fee_vault, ) .await .map_err(|err| RpcErr::Internal(err.to_string()))?; @@ -171,7 +170,6 @@ impl RpcHandler for TraceBlockByNumberRequest { timeout, config.only_top_call, config.with_log, - context.fee_vault, ) .await .map_err(|err| RpcErr::Internal(err.to_string()))?; diff --git a/crates/networking/rpc/utils.rs b/crates/networking/rpc/utils.rs index 609274a4d65..652e654835f 100644 --- a/crates/networking/rpc/utils.rs +++ b/crates/networking/rpc/utils.rs @@ -395,7 +395,6 @@ pub mod test_utils { "ethrex/test".to_string(), None, None, - None, ) .await .unwrap(); @@ -419,7 +418,6 @@ pub mod test_utils { gas_tip_estimator: Arc::new(TokioMutex::new(GasTipEstimator::new())), log_filter_handler: None, gas_ceil: DEFAULT_BUILDER_GAS_CEIL, - fee_vault: None, } } } diff --git a/crates/vm/backends/mod.rs b/crates/vm/backends/mod.rs index 125449847cc..396aa28c4a4 100644 --- a/crates/vm/backends/mod.rs +++ b/crates/vm/backends/mod.rs @@ -34,6 +34,8 @@ pub struct Evm { // For simplifying compilation we decided to include them both in revm and levm builds. pub db: GeneralizedDatabase, pub vm_type: VMType, + // Address where the base fee will be sent instead of burned. If None, base fees are burned. + pub fee_vault: Option
, } impl core::fmt::Debug for Evm { @@ -62,6 +64,7 @@ impl Evm { state: evm_state(wrapped_db.clone()), db: GeneralizedDatabase::new(Arc::new(wrapped_db)), vm_type: VMType::L1, + fee_vault: None, } } @@ -70,11 +73,15 @@ impl Evm { Evm { db: GeneralizedDatabase::new(Arc::new(wrapped_db)), vm_type: VMType::L1, + fee_vault: None, } } } - pub fn new_for_l2(_db: impl VmDatabase + 'static) -> Result { + pub fn new_for_l2( + _db: impl VmDatabase + 'static, + _fee_vault: Option
, + ) -> Result { #[cfg(feature = "revm")] { Err(EvmError::InvalidEVM( @@ -89,6 +96,7 @@ impl Evm { let evm = Evm { db: GeneralizedDatabase::new(Arc::new(wrapped_db)), vm_type: VMType::L2, + fee_vault: _fee_vault, }; Ok(evm) @@ -96,41 +104,49 @@ impl Evm { } pub fn new_from_db_for_l1(store: Arc) -> Self { - Self::_new_from_db(store, VMType::L1) + Self::_new_from_db(store, VMType::L1, None) } - pub fn new_from_db_for_l2(store: Arc) -> Self { - Self::_new_from_db(store, VMType::L2) + pub fn new_from_db_for_l2( + store: Arc, + fee_vault: Option
, + ) -> Self { + Self::_new_from_db(store, VMType::L2, fee_vault) } // Only used in non-REVM builds; in REVM builds this constructor is not supported. #[cfg(feature = "revm")] - fn _new_from_db(_store: Arc, _vm_type: VMType) -> Self { + fn _new_from_db( + _store: Arc, + _vm_type: VMType, + _fee_vault: Option
, + ) -> Self { unreachable!("new_from_db is not supported when built with the `revm` feature") } #[cfg(not(feature = "revm"))] - fn _new_from_db(store: Arc, vm_type: VMType) -> Self { + fn _new_from_db( + store: Arc, + vm_type: VMType, + fee_vault: Option
, + ) -> Self { Evm { db: GeneralizedDatabase::new(store), vm_type, + fee_vault, } } #[instrument(level = "trace", name = "Block execution", skip_all)] - pub fn execute_block( - &mut self, - block: &Block, - fee_vault: Option
, - ) -> Result { + pub fn execute_block(&mut self, block: &Block) -> Result { #[cfg(feature = "revm")] { - REVM::execute_block(block, &mut self.state, fee_vault) + REVM::execute_block(block, &mut self.state) } #[cfg(not(feature = "revm"))] { - LEVM::execute_block(block, &mut self.db, self.vm_type, fee_vault) + LEVM::execute_block(block, &mut self.db, self.vm_type, self.fee_vault) } } @@ -143,7 +159,6 @@ impl Evm { block_header: &BlockHeader, remaining_gas: &mut u64, sender: Address, - fee_vault: Option
, ) -> Result<(Receipt, u64), EvmError> { #[cfg(feature = "revm")] { @@ -154,7 +169,6 @@ impl Evm { &mut self.state, spec_id(&chain_config, block_header.timestamp), sender, - fee_vault, )?; *remaining_gas = remaining_gas.saturating_sub(execution_result.gas_used()); @@ -177,7 +191,7 @@ impl Evm { block_header, &mut self.db, self.vm_type, - fee_vault, + self.fee_vault, )?; *remaining_gas = remaining_gas.saturating_sub(execution_report.gas_used); @@ -300,23 +314,16 @@ impl Evm { tx: &GenericTransaction, header: &BlockHeader, _fork: Fork, - fee_vault: Option
, ) -> Result { #[cfg(feature = "revm")] { let spec_id = fork_to_spec_id(_fork); - self::revm::helpers::simulate_tx_from_generic( - tx, - header, - &mut self.state, - spec_id, - fee_vault, - ) + self::revm::helpers::simulate_tx_from_generic(tx, header, &mut self.state, spec_id) } #[cfg(not(feature = "revm"))] { - LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type, fee_vault) + LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type, self.fee_vault) } } @@ -325,23 +332,22 @@ impl Evm { tx: &GenericTransaction, header: &BlockHeader, _fork: Fork, - fee_vault: Option
, ) -> Result<(u64, AccessList, Option), EvmError> { #[cfg(feature = "revm")] let result = { let spec_id = fork_to_spec_id(_fork); - self::revm::helpers::create_access_list( - tx, - header, - &mut self.state, - spec_id, - fee_vault, - )? + self::revm::helpers::create_access_list(tx, header, &mut self.state, spec_id)? }; #[cfg(not(feature = "revm"))] let result = { - LEVM::create_access_list(tx.clone(), header, &mut self.db, self.vm_type, fee_vault)? + LEVM::create_access_list( + tx.clone(), + header, + &mut self.db, + self.vm_type, + self.fee_vault, + )? }; match result { diff --git a/crates/vm/backends/revm/helpers.rs b/crates/vm/backends/revm/helpers.rs index efe57ce2e05..a4f87673881 100644 --- a/crates/vm/backends/revm/helpers.rs +++ b/crates/vm/backends/revm/helpers.rs @@ -21,7 +21,6 @@ pub fn simulate_tx_from_generic( header: &BlockHeader, state: &mut EvmState, spec_id: SpecId, - _fee_vault: Option
, ) -> Result { let block_env = block_env(header, spec_id); let tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); @@ -34,7 +33,6 @@ pub fn create_access_list( header: &BlockHeader, state: &mut EvmState, spec_id: SpecId, - _fee_vault: Option
, ) -> Result<(ExecutionResult, AccessList), EvmError> { let mut tx_env = tx_env_from_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); let block_env = block_env(header, spec_id); diff --git a/crates/vm/backends/revm/mod.rs b/crates/vm/backends/revm/mod.rs index 3c15deadb65..98b53948686 100644 --- a/crates/vm/backends/revm/mod.rs +++ b/crates/vm/backends/revm/mod.rs @@ -53,7 +53,6 @@ impl REVM { pub fn execute_block( block: &Block, state: &mut EvmState, - fee_vault: Option
, ) -> Result { let block_header = &block.header; let spec_id: SpecId = spec_id( @@ -76,7 +75,7 @@ impl REVM { for (tx, sender) in block.body.get_transactions_with_sender().map_err(|error| { EvmError::Transaction(format!("Couldn't recover addresses with error: {error}")) })? { - let result = Self::execute_tx(tx, block_header, state, spec_id, sender, fee_vault)?; + let result = Self::execute_tx(tx, block_header, state, spec_id, sender)?; cumulative_gas_used += result.gas_used(); let receipt = Receipt::new( tx.tx_type(), @@ -103,7 +102,6 @@ impl REVM { state: &mut EvmState, spec_id: SpecId, sender: Address, - _fee_vault: Option
, ) -> Result { let block_env = block_env(header, spec_id); let tx_env = tx_env(tx, sender); diff --git a/crates/vm/backends/revm/tracing.rs b/crates/vm/backends/revm/tracing.rs index e3c3327a772..55b10a55eaa 100644 --- a/crates/vm/backends/revm/tracing.rs +++ b/crates/vm/backends/revm/tracing.rs @@ -27,7 +27,6 @@ impl REVM { state: &mut EvmState, only_top_call: bool, with_log: bool, - _fee_vault: Option
, ) -> Result { let spec_id: SpecId = spec_id(&state.chain_config()?, block_header.timestamp); let block_env = block_env(block_header, spec_id); @@ -48,7 +47,6 @@ impl REVM { block: &Block, state: &mut EvmState, stop_index: Option, - _fee_vault: Option
, ) -> Result<(), EvmError> { let spec_id: SpecId = spec_id(&state.chain_config()?, block.header.timestamp); let block_env = block_env(&block.header, spec_id); diff --git a/crates/vm/tracing.rs b/crates/vm/tracing.rs index e654bc281fc..2843fdcc6ce 100644 --- a/crates/vm/tracing.rs +++ b/crates/vm/tracing.rs @@ -1,5 +1,5 @@ +use ethrex_common::tracing::CallTrace; use ethrex_common::types::Block; -use ethrex_common::{Address, tracing::CallTrace}; #[cfg(not(feature = "revm"))] use crate::backends::levm::LEVM; @@ -19,7 +19,6 @@ impl Evm { tx_index: usize, only_top_call: bool, with_log: bool, - fee_vault: Option
, ) -> Result { let tx = block .body @@ -31,14 +30,7 @@ impl Evm { #[cfg(feature = "revm")] { - REVM::trace_tx_calls( - &block.header, - tx, - &mut self.state, - only_top_call, - with_log, - fee_vault, - ) + REVM::trace_tx_calls(&block.header, tx, &mut self.state, only_top_call, with_log) } #[cfg(not(feature = "revm"))] @@ -50,7 +42,7 @@ impl Evm { only_top_call, with_log, self.vm_type, - fee_vault, + self.fee_vault, ) } } @@ -63,16 +55,21 @@ impl Evm { &mut self, block: &Block, stop_index: Option, - fee_vault: Option
, ) -> Result<(), EvmError> { #[cfg(feature = "revm")] { - REVM::rerun_block(block, &mut self.state, stop_index, fee_vault) + REVM::rerun_block(block, &mut self.state, stop_index) } #[cfg(not(feature = "revm"))] { - LEVM::rerun_block(&mut self.db, block, stop_index, self.vm_type, fee_vault) + LEVM::rerun_block( + &mut self.db, + block, + stop_index, + self.vm_type, + self.fee_vault, + ) } } } diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index b964f23e120..afb5f2084ff 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -61,8 +61,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122012233c84da20adbad70e7dcdaf998f500bd4fe5f2afcc8a5a017db4607df226164736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" @@ -70,8 +70,8 @@ "0x000000000000000000000000000000000000ffff": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122012233c84da20adbad70e7dcdaf998f500bd4fe5f2afcc8a5a017db4607df226164736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" }, "balance": "0x0", "nonce": "0x1" diff --git a/tooling/ef_tests/state_v2/src/modules/block_runner.rs b/tooling/ef_tests/state_v2/src/modules/block_runner.rs index dc63679a529..020ffa2ba9d 100644 --- a/tooling/ef_tests/state_v2/src/modules/block_runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/block_runner.rs @@ -144,7 +144,7 @@ pub async fn run_test(test: &Test, test_case: &TestCase) -> Result<(), RunnerErr // 3. Create Blockchain and add block. - let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false); + let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false, None); let result = blockchain.add_block(&block).await; From 9aa040717c54a49a4baa2d448493d1bba86fb8fb Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 13:53:21 -0300 Subject: [PATCH 20/88] Fix linter --- crates/blockchain/tracing.rs | 1 - crates/l2/prover/src/guest_program/src/execution.rs | 13 +++---------- tooling/ef_tests/blockchain/test_runner.rs | 4 ++-- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/crates/blockchain/tracing.rs b/crates/blockchain/tracing.rs index 291d43bb0ed..b10e94533d7 100644 --- a/crates/blockchain/tracing.rs +++ b/crates/blockchain/tracing.rs @@ -36,7 +36,6 @@ impl Blockchain { .await?; // Run the block until the transaction we want to trace vm.rerun_block(&block, Some(tx_index))?; - // Trace the transaction timeout_trace_operation(timeout, move || { vm.trace_tx_calls(&block, tx_index, only_top_call, with_log) diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 46371a3118e..af910fc1a9a 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -100,7 +100,7 @@ pub fn execution_program(input: ProgramInput) -> Result Result, chain_id: u64, ) -> Result { let StatelessResult { diff --git a/tooling/ef_tests/blockchain/test_runner.rs b/tooling/ef_tests/blockchain/test_runner.rs index ebec3d35af2..1ef2fca7eaa 100644 --- a/tooling/ef_tests/blockchain/test_runner.rs +++ b/tooling/ef_tests/blockchain/test_runner.rs @@ -105,7 +105,7 @@ pub async fn run_ef_test( check_prestate_against_db(test_key, test, &store); // Blockchain EF tests are meant for L1. - let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false); + let blockchain = Blockchain::new(store.clone(), BlockchainType::L1, false, None); // Early return if the exception is in the rlp decoding of the block for bf in &test.blocks { @@ -453,7 +453,7 @@ async fn re_run_stateless( let test_should_fail = test.blocks.iter().any(|t| t.expect_exception.is_some()); - let witness = blockchain.generate_witness_for_blocks(&blocks, None).await; + let witness = blockchain.generate_witness_for_blocks(&blocks).await; if test_should_fail && witness.is_err() { // We can't generate witness for a test that should fail. return Ok(()); From 6445c832096dbb72e8fe9e85542aa5399b597577 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 16:34:31 -0300 Subject: [PATCH 21/88] Use cfg! macro to resolve fee_vault --- cmd/ethrex_replay/src/cli.rs | 18 ++++++++++-------- crates/blockchain/blockchain.rs | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index 1a6831c7ee9..e27e80296ee 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -615,10 +615,11 @@ async fn replay_transaction(tx_opts: TransactionOpts) -> eyre::Result<()> { .await? .ok_or(eyre::Error::msg("error fetching transaction"))?; - #[cfg(not(feature = "l2"))] - let fee_vault = None; - #[cfg(feature = "l2")] - let fee_vault = get_fee_vault_address(ð_client).await?; + let fee_vault = if cfg!(feature = "l2") { + get_fee_vault_address(ð_client).await? + } else { + None + }; let cache = get_blockdata( eth_client, @@ -650,10 +651,11 @@ async fn replay_block(block_opts: BlockOptions) -> eyre::Result<()> { let (eth_client, network) = setup(&opts).await?; - #[cfg(not(feature = "l2"))] - let fee_vault = None; - #[cfg(feature = "l2")] - let fee_vault = get_fee_vault_address(ð_client).await?; + let fee_vault = if cfg!(feature = "l2") { + get_fee_vault_address(ð_client).await? + } else { + None + }; let cache = get_blockdata(eth_client, network.clone(), or_latest(block)?, fee_vault).await?; diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 71108dc5055..08ff09ee9ea 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -73,7 +73,7 @@ pub struct Blockchain { /// Mapping from a payload id to either a complete payload or a payload build task /// We need to keep completed payloads around in case consensus requests them twice pub payloads: Arc>>, - /// If set, collected base fees will be sent to this address instead of being burned + /// (L2 only) If set, collected base fees will be sent to this address instead of being burned pub fee_vault: Option
, } From 9ae24023687c8a3e40f589b88fb2a2b3bf4754ba Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 16:50:14 -0300 Subject: [PATCH 22/88] separate payload builder interfaces --- cmd/ethrex_replay/src/cli.rs | 1 - crates/blockchain/payload.rs | 25 +++++++++++-------- .../block_producer/payload_builder.rs | 7 +----- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index e27e80296ee..41ce25cbecd 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -11,7 +11,6 @@ use ethrex_common::{ ELASTICITY_MULTIPLIER, Receipt, block_execution_witness::GuestProgramState, }, }; -#[cfg(feature = "l2")] use ethrex_l2_rpc::clients::get_fee_vault_address; use ethrex_prover_lib::backend::Backend; use ethrex_rlp::{decode::RLPDecode, encode::RLPEncode}; diff --git a/crates/blockchain/payload.rs b/crates/blockchain/payload.rs index 5d7605382b9..cb8c1854bfb 100644 --- a/crates/blockchain/payload.rs +++ b/crates/blockchain/payload.rs @@ -214,12 +214,23 @@ pub struct PayloadBuildContext { } impl PayloadBuildContext { - pub fn new( + pub fn new_for_l1(payload: Block, storage: &Store) -> Result { + let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); + let vm = Evm::new_for_l1(vm_db); + Self::new(payload, storage, vm) + } + + pub fn new_for_l2( payload: Block, storage: &Store, - blockchain_type: BlockchainType, fee_vault: Option
, ) -> Result { + let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); + let vm = Evm::new_for_l2(vm_db, fee_vault)?; + Self::new(payload, storage, vm) + } + + pub fn new(payload: Block, storage: &Store, vm: Evm) -> Result { let config = storage .get_chain_config() .map_err(|e| EvmError::DB(e.to_string()))?; @@ -230,13 +241,6 @@ impl PayloadBuildContext { .map(|schedule| schedule.base_fee_update_fraction) .unwrap_or_default(), ); - - let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); - let vm = match blockchain_type { - BlockchainType::L1 => Evm::new_for_l1(vm_db), - BlockchainType::L2 => Evm::new_for_l2(vm_db, fee_vault)?, - }; - Ok(PayloadBuildContext { remaining_gas: payload.header.gas_limit, receipts: vec![], @@ -387,8 +391,7 @@ impl Blockchain { debug!("Building payload"); let base_fee = payload.header.base_fee_per_gas.unwrap_or_default(); - let mut context = - PayloadBuildContext::new(payload, &self.storage, self.r#type.clone(), None)?; + let mut context = PayloadBuildContext::new_for_l1(payload, &self.storage)?; if let BlockchainType::L1 = self.r#type { self.apply_system_operations(&mut context)?; diff --git a/crates/l2/sequencer/block_producer/payload_builder.rs b/crates/l2/sequencer/block_producer/payload_builder.rs index 760e7cbcdeb..a6cf1c2ece9 100644 --- a/crates/l2/sequencer/block_producer/payload_builder.rs +++ b/crates/l2/sequencer/block_producer/payload_builder.rs @@ -45,12 +45,7 @@ pub async fn build_payload( let gas_limit = payload.header.gas_limit; debug!("Building payload"); - let mut context = PayloadBuildContext::new( - payload, - store, - blockchain.r#type.clone(), - blockchain.fee_vault, - )?; + let mut context = PayloadBuildContext::new_for_l2(payload, store, blockchain.fee_vault)?; fill_transactions( blockchain.clone(), From 65da300c2fa25c3c59fb0f07151e5d7b9afc44f4 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 17:38:09 -0300 Subject: [PATCH 23/88] Store fee_vault in l2_hook --- crates/vm/backends/levm/mod.rs | 23 ++++++++----------- crates/vm/backends/levm/tracing.rs | 2 +- .../bench/revm_comparison/src/levm_bench.rs | 2 +- crates/vm/levm/runner/src/main.rs | 1 + crates/vm/levm/src/environment.rs | 2 -- crates/vm/levm/src/hooks/hook.rs | 13 +++++++---- crates/vm/levm/src/hooks/l2_hook.rs | 15 ++++++++---- crates/vm/levm/src/vm.rs | 3 ++- tooling/ef_tests/state/runner/levm_runner.rs | 2 +- .../state_v2/src/modules/block_runner.rs | 4 ++-- .../ef_tests/state_v2/src/modules/runner.rs | 3 +-- 11 files changed, 39 insertions(+), 31 deletions(-) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index e059d470ee6..1482a289a85 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -85,7 +85,6 @@ impl LEVM { tx_sender: Address, block_header: &BlockHeader, db: &mut GeneralizedDatabase, - fee_vault: Option
, ) -> Result { let chain_config = db.store.get_chain_config()?; let gas_price: U256 = tx @@ -102,7 +101,6 @@ impl LEVM { config, block_number: block_header.number.into(), coinbase: block_header.coinbase, - fee_vault, timestamp: block_header.timestamp.into(), prev_randao: Some(block_header.prev_randao), chain_id: chain_config.chain_id.into(), @@ -134,8 +132,8 @@ impl LEVM { vm_type: VMType, fee_vault: Option
, ) -> Result { - let env = Self::setup_env(tx, tx_sender, block_header, db, fee_vault)?; - let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?; + let env = Self::setup_env(tx, tx_sender, block_header, db)?; + let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type, fee_vault)?; vm.execute().map_err(VMError::into) } @@ -154,13 +152,13 @@ impl LEVM { vm_type: VMType, fee_vault: Option
, ) -> Result { - let mut env = env_from_generic(tx, block_header, db, fee_vault)?; + let mut env = env_from_generic(tx, block_header, db)?; env.block_gas_limit = u64::MAX; // disable block gas limit adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(tx, env, db, vm_type)?; + let mut vm = vm_from_generic(tx, env, db, vm_type, fee_vault)?; vm.execute() .map(|value| value.into()) @@ -305,17 +303,17 @@ impl LEVM { vm_type: VMType, fee_vault: Option
, ) -> Result<(ExecutionResult, AccessList), VMError> { - let mut env = env_from_generic(&tx, header, db, fee_vault)?; + let mut env = env_from_generic(&tx, header, db)?; adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; + let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type, fee_vault)?; vm.stateless_execute()?; // Execute the tx again, now with the created access list. tx.access_list = vm.substate.make_access_list(); - let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; + let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type, fee_vault)?; let report = vm.stateless_execute()?; @@ -394,7 +392,7 @@ pub fn generic_system_contract_levm( ..Default::default() }); let mut vm = - VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type).map_err(EvmError::from)?; + VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type, None).map_err(EvmError::from)?; let report = vm.execute().map_err(EvmError::from)?; @@ -488,7 +486,6 @@ fn env_from_generic( tx: &GenericTransaction, header: &BlockHeader, db: &GeneralizedDatabase, - fee_vault: Option
, ) -> Result { let chain_config = db.store.get_chain_config()?; let gas_price = calculate_gas_price(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); @@ -499,7 +496,6 @@ fn env_from_generic( config, block_number: header.number.into(), coinbase: header.coinbase, - fee_vault, timestamp: header.timestamp.into(), prev_randao: Some(header.prev_randao), chain_id: chain_config.chain_id.into(), @@ -523,6 +519,7 @@ fn vm_from_generic<'a>( env: Environment, db: &'a mut GeneralizedDatabase, vm_type: VMType, + fee_vault: Option
, ) -> Result, VMError> { let tx = match &tx.authorization_list { Some(authorization_list) => Transaction::EIP7702Transaction(EIP7702Transaction { @@ -557,5 +554,5 @@ fn vm_from_generic<'a>( ..Default::default() }), }; - VM::new(env, db, &tx, LevmCallTracer::disabled(), vm_type) + VM::new(env, db, &tx, LevmCallTracer::disabled(), vm_type, fee_vault) } diff --git a/crates/vm/backends/levm/tracing.rs b/crates/vm/backends/levm/tracing.rs index 8b0b01a75bf..e6d14071896 100644 --- a/crates/vm/backends/levm/tracing.rs +++ b/crates/vm/backends/levm/tracing.rs @@ -60,7 +60,6 @@ impl LEVM { })?, block_header, db, - fee_vault, )?; let mut vm = VM::new( env, @@ -68,6 +67,7 @@ impl LEVM { tx, LevmCallTracer::new(only_top_call, with_log), vm_type, + fee_vault, )?; vm.execute()?; diff --git a/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs b/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs index 00b8051f1c3..b5391221582 100644 --- a/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs +++ b/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs @@ -83,5 +83,5 @@ fn init_vm(db: &mut GeneralizedDatabase, nonce: u64, calldata: Bytes) -> Result< data: calldata, ..Default::default() }); - VM::new(env, db, &tx, LevmCallTracer::disabled(), VMType::L1) + VM::new(env, db, &tx, LevmCallTracer::disabled(), VMType::L1, None) } diff --git a/crates/vm/levm/runner/src/main.rs b/crates/vm/levm/runner/src/main.rs index 978ec7e36c6..6cbc288aaac 100644 --- a/crates/vm/levm/runner/src/main.rs +++ b/crates/vm/levm/runner/src/main.rs @@ -151,6 +151,7 @@ fn main() { &Transaction::LegacyTransaction(LegacyTransaction::from(runner_input.transaction.clone())), LevmCallTracer::disabled(), VMType::L1, + None, ) .expect("Failed to initialize VM"); diff --git a/crates/vm/levm/src/environment.rs b/crates/vm/levm/src/environment.rs index d9a57128138..0a7d1c81cb2 100644 --- a/crates/vm/levm/src/environment.rs +++ b/crates/vm/levm/src/environment.rs @@ -23,8 +23,6 @@ pub struct Environment { pub block_number: U256, /// Coinbase is the block's beneficiary - the address that receives the block rewards (priority fees). pub coinbase: Address, - /// Fee vault is the address that receives the base fees in L2. - pub fee_vault: Option
, pub timestamp: U256, pub prev_randao: Option, pub difficulty: U256, diff --git a/crates/vm/levm/src/hooks/hook.rs b/crates/vm/levm/src/hooks/hook.rs index 023a2a5ada4..c7e27ff990a 100644 --- a/crates/vm/levm/src/hooks/hook.rs +++ b/crates/vm/levm/src/hooks/hook.rs @@ -1,5 +1,7 @@ use std::{cell::RefCell, rc::Rc}; +use ethrex_common::Address; + use crate::{ errors::{ContextResult, VMError}, hooks::{L2Hook, backup_hook::BackupHook, default_hook::DefaultHook}, @@ -16,10 +18,13 @@ pub trait Hook { ) -> Result<(), VMError>; } -pub fn get_hooks(vm_type: &VMType) -> Vec>> { +pub fn get_hooks( + vm_type: &VMType, + fee_vault: Option
, +) -> Vec>> { match vm_type { VMType::L1 => l1_hooks(), - VMType::L2 => l2_hooks(), + VMType::L2 => l2_hooks(fee_vault), } } @@ -27,9 +32,9 @@ pub fn l1_hooks() -> Vec>> { vec![Rc::new(RefCell::new(DefaultHook))] } -pub fn l2_hooks() -> Vec>> { +pub fn l2_hooks(fee_vault: Option
) -> Vec>> { vec![ - Rc::new(RefCell::new(L2Hook {})), + Rc::new(RefCell::new(L2Hook { fee_vault })), Rc::new(RefCell::new(BackupHook::default())), ] } diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index b3083613116..3896e6e3548 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -12,7 +12,10 @@ pub const COMMON_BRIDGE_L2_ADDRESS: Address = H160([ 0x00, 0x00, 0xff, 0xff, ]); -pub struct L2Hook {} +pub struct L2Hook { + /// If set, the base fee is sent to this address instead of being burned. + pub fee_vault: Option
, +} impl Hook for L2Hook { fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), crate::errors::VMError> { @@ -109,7 +112,7 @@ impl Hook for L2Hook { if !vm.env.is_privileged { DefaultHook.finalize_execution(vm, ctx_result)?; // Different from L1, the base fee is not burned - return pay_to_fee_vault(vm, ctx_result.gas_used); + return pay_to_fee_vault(vm, ctx_result.gas_used, self.fee_vault); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { @@ -124,11 +127,15 @@ impl Hook for L2Hook { } } -fn pay_to_fee_vault(vm: &mut VM<'_>, gas_to_pay: u64) -> Result<(), crate::errors::VMError> { +fn pay_to_fee_vault( + vm: &mut VM<'_>, + gas_to_pay: u64, + fee_vault: Option
, +) -> Result<(), crate::errors::VMError> { let base_fee = U256::from(gas_to_pay) .checked_mul(vm.env.base_fee_per_gas) .ok_or(InternalError::Overflow)?; - let Some(fee_vault) = vm.env.fee_vault else { + let Some(fee_vault) = fee_vault else { // No fee vault configured, base fee is effectively burned return Ok(()); }; diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs index 5839cf2cd51..67f42eb1491 100644 --- a/crates/vm/levm/src/vm.rs +++ b/crates/vm/levm/src/vm.rs @@ -335,6 +335,7 @@ impl<'a> VM<'a> { tx: &Transaction, tracer: LevmCallTracer, vm_type: VMType, + fee_vault: Option
, ) -> Result { db.tx_backup = None; // If BackupHook is enabled, it will contain backup at the end of tx execution. @@ -349,7 +350,7 @@ impl<'a> VM<'a> { substate, db, tx: tx.clone(), - hooks: get_hooks(&vm_type), + hooks: get_hooks(&vm_type, fee_vault), substate_backups: Vec::new(), storage_original_values: BTreeMap::new(), tracer, diff --git a/tooling/ef_tests/state/runner/levm_runner.rs b/tooling/ef_tests/state/runner/levm_runner.rs index 1a54d9c4236..832f1981bd0 100644 --- a/tooling/ef_tests/state/runner/levm_runner.rs +++ b/tooling/ef_tests/state/runner/levm_runner.rs @@ -219,7 +219,6 @@ pub fn prepare_vm_for_tx<'a>( config, block_number: test.env.current_number, coinbase: test.env.current_coinbase, - fee_vault: None, timestamp: test.env.current_timestamp, prev_randao: test.env.current_random, difficulty: test.env.current_difficulty, @@ -240,6 +239,7 @@ pub fn prepare_vm_for_tx<'a>( &tx, LevmCallTracer::disabled(), VMType::L1, // TODO: Should we run the EF tests with L2? + None, ) .map_err(|e| EFTestRunnerError::FailedToEnsurePreState(format!("Failed to initialize VM: {e}"))) } diff --git a/tooling/ef_tests/state_v2/src/modules/block_runner.rs b/tooling/ef_tests/state_v2/src/modules/block_runner.rs index 020ffa2ba9d..82cd002d05a 100644 --- a/tooling/ef_tests/state_v2/src/modules/block_runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/block_runner.rs @@ -43,8 +43,8 @@ pub async fn run_test(test: &Test, test_case: &TestCase) -> Result<(), RunnerErr let (mut db, initial_block_hash, store, _genesis) = load_initial_state(test, &test_case.fork).await; - let mut vm = - VM::new(env.clone(), &mut db, &tx, tracer, VMType::L1).map_err(RunnerError::VMError)?; + let mut vm = VM::new(env.clone(), &mut db, &tx, tracer, VMType::L1, None) + .map_err(RunnerError::VMError)?; let execution_result = vm.execute(); let (receipts, gas_used) = match execution_result { diff --git a/tooling/ef_tests/state_v2/src/modules/runner.rs b/tooling/ef_tests/state_v2/src/modules/runner.rs index 91d60b3a120..7bd0c93aee6 100644 --- a/tooling/ef_tests/state_v2/src/modules/runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/runner.rs @@ -83,7 +83,7 @@ pub async fn run_test( let tx = get_tx_from_test_case(test_case).await?; let tracer = LevmCallTracer::disabled(); let mut vm = - VM::new(env, &mut db, &tx, tracer, VMType::L1).map_err(RunnerError::VMError)?; + VM::new(env, &mut db, &tx, tracer, VMType::L1, None).map_err(RunnerError::VMError)?; // Execute transaction with VM. let execution_result = vm.execute(); @@ -134,7 +134,6 @@ pub fn get_vm_env_for_test( config, block_number: test_env.current_number, coinbase: test_env.current_coinbase, - fee_vault: None, timestamp: test_env.current_timestamp, prev_randao: test_env.current_random, difficulty: test_env.current_difficulty, From ef38d6907ea9b70910952e93d9e2fed629adbcb9 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 18:38:24 -0300 Subject: [PATCH 24/88] Improve docs --- docs/CLI.md | 2 +- docs/l2/configuration.md | 20 ++++++++++++++++++++ docs/l2/running.md | 7 +++---- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 docs/l2/configuration.md diff --git a/docs/CLI.md b/docs/CLI.md index 6cae47f3379..aec722c95b1 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -149,7 +149,7 @@ Node options: If the datadir is the word `memory`, ethrex will use the `InMemory Engine`. [env: ETHREX_DATADIR=] - [default: "/Users/gaston/Library/Application Support/ethrex"] + [default: "/home/runner/.local/share/ethrex"] --force Delete the database without confirmation. diff --git a/docs/l2/configuration.md b/docs/l2/configuration.md new file mode 100644 index 00000000000..6ba2e09659e --- /dev/null +++ b/docs/l2/configuration.md @@ -0,0 +1,20 @@ +# Configuration + +This page covers the advanced configuration options for running an L2 node with ethrex. + +## Base fee Configuration + +You can configure the base fee behavior in ethrex. + +Set a fee vault address with: + +```sh +ethrex l2 --block-producer.fee-vault-address +``` + +When configured, the sequencer redirects collected base fees to the specified address instead of burning them. The sequencer may designate any address as the fee vault, including the coinbase address. + +> [!CAUTION] +> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. + + diff --git a/docs/l2/running.md b/docs/l2/running.md index 19967d204b2..ecdb6fa2284 100644 --- a/docs/l2/running.md +++ b/docs/l2/running.md @@ -25,16 +25,12 @@ First we need to set some environment variables. --committer_l1_private_key \ --proof_coordinator_l1_private_key \ --block-producer.coinbase-address \ - --block-producer.fee-vault-address ``` For further configuration take a look at the [CLI document](../CLI.md#ethrex-l2) This will start an ethrex l2 sequencer with the RPC server listening at `http://localhost:1729` and the proof coordinator server listening at `http://localhost:3900` -> **Note:** If `--block-producer.fee-vault-address` is set, the sequencer will send collected base fees to that address instead of burning them. -> Be cautious: if the fee vault address is the same as the coinbase address, the coinbase balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. - ## Starting a prover server @@ -68,3 +64,6 @@ After starting the sequencer and prover, you can verify that your L2 node is run - Review the terminal output or log files for any errors or warnings. If all endpoints respond and there are no errors in the logs, your L2 node is running successfully. + +> [!NOTE] +> For more information about the configuration options, see the [Configuration](./configuration.md) section. \ No newline at end of file From 7c692f284065179f3b597ca09fbb9955b06a6503 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 25 Sep 2025 18:56:42 -0300 Subject: [PATCH 25/88] Add disclaimer --- docs/l2/configuration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/l2/configuration.md b/docs/l2/configuration.md index 6ba2e09659e..fd6779cbf79 100644 --- a/docs/l2/configuration.md +++ b/docs/l2/configuration.md @@ -17,4 +17,5 @@ When configured, the sequencer redirects collected base fees to the specified ad > [!CAUTION] > If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. - +> [!CAUTION] +> Even though it may technically be possible to change the fee vault address or switch between burning and not burning fees from one batch to another, the feature was not designed to allow such behavior once the chain has been launched. From 8f57e4107e7ff398b98f200908028595bd8d8a01 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 30 Sep 2025 13:25:18 -0300 Subject: [PATCH 26/88] Add fee_config to blockchain and vm l2 type --- cmd/ethrex/cli.rs | 4 +- cmd/ethrex/initializers.rs | 1 - cmd/ethrex/l2/initializers.rs | 9 +++- cmd/ethrex_replay/src/fetcher.rs | 2 +- cmd/ethrex_replay/src/rpc/db.rs | 8 +-- crates/blockchain/blockchain.rs | 12 ++--- crates/blockchain/payload.rs | 26 ++++----- crates/common/types/l2.rs | 2 + crates/common/types/{ => l2}/batch.rs | 5 +- crates/common/types/l2/fee_config.rs | 26 +++++++++ crates/common/types/mod.rs | 3 +- crates/l2/networking/rpc/l2/fee_vault.rs | 24 +++++---- .../prover/src/guest_program/src/execution.rs | 19 ++++--- .../l2/prover/src/guest_program/src/input.rs | 10 ++-- crates/l2/prover/src/prover.rs | 2 +- .../block_producer/payload_builder.rs | 3 +- crates/l2/sequencer/proof_coordinator.rs | 13 +++-- crates/vm/backends/levm/mod.rs | 33 +++++------- crates/vm/backends/levm/tracing.rs | 6 +-- crates/vm/backends/mod.rs | 54 +++++-------------- .../bench/revm_comparison/src/levm_bench.rs | 2 +- crates/vm/levm/runner/src/main.rs | 1 - crates/vm/levm/src/hooks/hook.rs | 16 +++--- crates/vm/levm/src/hooks/l2_hook.rs | 7 ++- crates/vm/levm/src/vm.rs | 7 ++- crates/vm/tracing.rs | 9 +--- fixtures/genesis/l2.json | 4 +- tooling/ef_tests/state/runner/levm_runner.rs | 1 - .../state_v2/src/modules/block_runner.rs | 4 +- .../ef_tests/state_v2/src/modules/runner.rs | 2 +- 30 files changed, 150 insertions(+), 165 deletions(-) create mode 100644 crates/common/types/l2.rs rename crates/common/types/{ => l2}/batch.rs (90%) create mode 100644 crates/common/types/l2/fee_config.rs diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index c2c3f82faea..748c9bb867a 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -7,7 +7,7 @@ use std::{ use clap::{ArgAction, Parser as ClapParser, Subcommand as ClapSubcommand}; use ethrex_blockchain::{BlockchainOptions, BlockchainType, error::ChainError}; -use ethrex_common::types::{Block, Genesis}; +use ethrex_common::types::{Block, Genesis, fee_config::FeeConfig}; use ethrex_p2p::sync::SyncMode; use ethrex_p2p::types::Node; use ethrex_rlp::encode::RLPEncode; @@ -336,7 +336,7 @@ impl Subcommand { let network = get_network(opts); let genesis = network.get_genesis()?; let blockchain_type = if l2 { - BlockchainType::L2 + BlockchainType::L2(FeeConfig::default()) } else { BlockchainType::L1 }; diff --git a/cmd/ethrex/initializers.rs b/cmd/ethrex/initializers.rs index d8f681b535d..e0d330ff705 100644 --- a/cmd/ethrex/initializers.rs +++ b/cmd/ethrex/initializers.rs @@ -392,7 +392,6 @@ pub async fn init_l1( max_mempool_size: opts.mempool_max_size, perf_logs_enabled: true, r#type: BlockchainType::L1, - ..Default::default() }, ); diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 2fea0dbc56a..68090e94328 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -6,6 +6,7 @@ use std::time::Duration; use ethrex_blockchain::{Blockchain, BlockchainType}; use ethrex_common::Address; use ethrex_common::types::DEFAULT_BUILDER_GAS_CEIL; +use ethrex_common::types::fee_config::FeeConfig; use ethrex_l2::SequencerConfig; use ethrex_p2p::kademlia::Kademlia; use ethrex_p2p::network::peer_table; @@ -170,11 +171,15 @@ pub async fn init_l2( let store = init_store(&datadir, genesis).await; let rollup_store = init_rollup_store(&rollup_store_dir).await; + let fee_config = FeeConfig { + fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, + ..Default::default() + }; + let blockchain_opts = ethrex_blockchain::BlockchainOptions { max_mempool_size: opts.node_opts.mempool_max_size, - r#type: BlockchainType::L2, + r#type: BlockchainType::L2(fee_config), perf_logs_enabled: true, - fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, }; let blockchain = init_blockchain(store.clone(), blockchain_opts); diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index 6995fb903e0..e8b6c613d25 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -123,7 +123,7 @@ pub async fn get_blockdata( requested_block_number ); let rpc_db = rpc_db - .to_execution_witness(&block, fee_vault) + .to_execution_witness(&block) .wrap_err("failed to build execution db")?; info!( "Finished building execution witness for block {}", diff --git a/cmd/ethrex_replay/src/rpc/db.rs b/cmd/ethrex_replay/src/rpc/db.rs index ac2910e9d20..0061fb3d685 100644 --- a/cmd/ethrex_replay/src/rpc/db.rs +++ b/cmd/ethrex_replay/src/rpc/db.rs @@ -319,15 +319,11 @@ impl RpcDB { /// 1. Pre-executes the block to capture all state changes /// 2. Gathers account and storage proofs for both initial and final states /// 3. Collects potential child nodes for deleted account and storage entries - pub fn to_execution_witness( - &self, - block: &Block, - fee_vault: Option
, - ) -> eyre::Result { + pub fn to_execution_witness(&self, block: &Block) -> eyre::Result { let mut db = GeneralizedDatabase::new(Arc::new(self.clone())); // pre-execute and get all state changes - let _ = LEVM::execute_block(block, &mut db, self.vm_type, fee_vault).map_err(Box::new)?; + let _ = LEVM::execute_block(block, &mut db, self.vm_type).map_err(Box::new)?; let execution_updates = LEVM::get_state_transitions(&mut db).map_err(Box::new)?; info!( diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index cffc1795fba..208ff596129 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -13,6 +13,7 @@ use error::MempoolError; use error::{ChainError, InvalidBlockError}; use ethrex_common::constants::{GAS_PER_BLOB, MAX_RLP_BLOCK_SIZE, MIN_BASE_FEE_PER_BLOB_GAS}; use ethrex_common::types::block_execution_witness::ExecutionWitness; +use ethrex_common::types::fee_config::FeeConfig; use ethrex_common::types::requests::{EncodedRequests, Requests, compute_requests_hash}; use ethrex_common::types::{ AccountUpdate, Block, BlockHash, BlockHeader, BlockNumber, ChainConfig, EIP4844Transaction, @@ -57,7 +58,7 @@ const MAX_MEMPOOL_SIZE_DEFAULT: usize = 10_000; pub enum BlockchainType { #[default] L1, - L2, + L2(FeeConfig), } #[derive(Debug)] @@ -80,8 +81,6 @@ pub struct BlockchainOptions { /// Whether performance logs should be emitted pub perf_logs_enabled: bool, pub r#type: BlockchainType, - /// (L2 only) If set, collected base fees will be sent to this address instead of being burned - pub fee_vault: Option
, } impl Default for BlockchainOptions { @@ -90,7 +89,6 @@ impl Default for BlockchainOptions { max_mempool_size: MAX_MEMPOOL_SIZE_DEFAULT, perf_logs_enabled: false, r#type: BlockchainType::default(), - fee_vault: None, } } } @@ -224,8 +222,8 @@ impl Blockchain { let logger = Arc::new(DatabaseLogger::new(Arc::new(Mutex::new(Box::new(vm_db))))); let mut vm = match self.options.r#type { BlockchainType::L1 => Evm::new_from_db_for_l1(logger.clone()), - BlockchainType::L2 => { - Evm::new_from_db_for_l2(logger.clone(), self.options.fee_vault) + BlockchainType::L2(fee_config) => { + Evm::new_from_db_for_l2(logger.clone(), fee_config) } }; @@ -905,7 +903,7 @@ impl Blockchain { pub fn new_evm(&self, vm_db: StoreVmDatabase) -> Result { let evm = match self.options.r#type { BlockchainType::L1 => Evm::new_for_l1(vm_db), - BlockchainType::L2 => Evm::new_for_l2(vm_db, self.options.fee_vault)?, + BlockchainType::L2(fee_config) => Evm::new_for_l2(vm_db, fee_config)?, }; Ok(evm) } diff --git a/crates/blockchain/payload.rs b/crates/blockchain/payload.rs index ece2ddd1669..6283afb45ed 100644 --- a/crates/blockchain/payload.rs +++ b/crates/blockchain/payload.rs @@ -217,23 +217,11 @@ pub struct PayloadBuildContext { } impl PayloadBuildContext { - pub fn new_for_l1(payload: Block, storage: &Store) -> Result { - let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); - let vm = Evm::new_for_l1(vm_db); - Self::new(payload, storage, vm) - } - - pub fn new_for_l2( + pub fn new( payload: Block, storage: &Store, - fee_vault: Option
, + blockchain_type: BlockchainType, ) -> Result { - let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); - let vm = Evm::new_for_l2(vm_db, fee_vault)?; - Self::new(payload, storage, vm) - } - - pub fn new(payload: Block, storage: &Store, vm: Evm) -> Result { let config = storage .get_chain_config() .map_err(|e| EvmError::DB(e.to_string()))?; @@ -244,6 +232,13 @@ impl PayloadBuildContext { .map(|schedule| schedule.base_fee_update_fraction) .unwrap_or_default(), ); + + let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash); + let vm = match blockchain_type { + BlockchainType::L1 => Evm::new_for_l1(vm_db), + BlockchainType::L2(fee_config) => Evm::new_for_l2(vm_db, fee_config)?, + }; + Ok(PayloadBuildContext { remaining_gas: payload.header.gas_limit, receipts: vec![], @@ -394,7 +389,8 @@ impl Blockchain { debug!("Building payload"); let base_fee = payload.header.base_fee_per_gas.unwrap_or_default(); - let mut context = PayloadBuildContext::new_for_l1(payload, &self.storage)?; + let mut context = + PayloadBuildContext::new(payload, &self.storage, self.options.r#type.clone())?; if let BlockchainType::L1 = self.options.r#type { self.apply_system_operations(&mut context)?; diff --git a/crates/common/types/l2.rs b/crates/common/types/l2.rs new file mode 100644 index 00000000000..d1764247099 --- /dev/null +++ b/crates/common/types/l2.rs @@ -0,0 +1,2 @@ +pub mod batch; +pub mod fee_config; diff --git a/crates/common/types/batch.rs b/crates/common/types/l2/batch.rs similarity index 90% rename from crates/common/types/batch.rs rename to crates/common/types/l2/batch.rs index 901cdabd03b..379d6ce814e 100644 --- a/crates/common/types/batch.rs +++ b/crates/common/types/l2/batch.rs @@ -1,9 +1,6 @@ +use crate::{H256, types::BlobsBundle}; use serde::{Deserialize, Serialize}; -use crate::H256; - -use super::BlobsBundle; - #[derive(Clone, Serialize, Deserialize, Debug, Default)] pub struct Batch { pub number: u64, diff --git a/crates/common/types/l2/fee_config.rs b/crates/common/types/l2/fee_config.rs new file mode 100644 index 00000000000..9a37cf5e52f --- /dev/null +++ b/crates/common/types/l2/fee_config.rs @@ -0,0 +1,26 @@ +use ethereum_types::Address; +use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; +use serde::{Deserialize, Serialize}; + +use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper}; + +#[derive( + Serialize, Deserialize, RDeserialize, RSerialize, Archive, Clone, Copy, Debug, Default, +)] +pub struct FeeConfig { + /// If set, the base fee is sent to this address instead of being burned. + #[rkyv(with=OptionH160Wrapper)] + pub fee_vault: Option
, + pub operator_fee_config: Option, +} + +/// Configuration for operator fees on L2 +/// The operator fee is an additional fee on top of the base fee +/// that is sent to the operator fee vault. +/// This is used to pay for the cost of running the L2 network. +#[derive(Serialize, Deserialize, RDeserialize, RSerialize, Archive, Clone, Copy, Debug)] +pub struct OperatorFeeConfig { + #[rkyv(with=H160Wrapper)] + pub operator_fee_vault: Address, + pub operator_fee: u64, +} diff --git a/crates/common/types/mod.rs b/crates/common/types/mod.rs index 2d9134bf13e..96487001e11 100644 --- a/crates/common/types/mod.rs +++ b/crates/common/types/mod.rs @@ -1,12 +1,12 @@ mod account; mod account_update; -pub mod batch; pub mod blobs_bundle; mod block; pub mod block_execution_witness; mod constants; mod fork_id; mod genesis; +pub mod l2; pub mod payload; mod receipt; pub mod requests; @@ -20,6 +20,7 @@ pub use block::*; pub use constants::*; pub use fork_id::*; pub use genesis::*; +pub use l2::*; pub use receipt::*; pub use transaction::*; pub use tx_fields::*; diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/fee_vault.rs index b9ae3f4a773..59d1132f366 100644 --- a/crates/l2/networking/rpc/l2/fee_vault.rs +++ b/crates/l2/networking/rpc/l2/fee_vault.rs @@ -13,14 +13,20 @@ impl RpcHandler for GetFeeVaultAddress { } async fn handle(&self, context: RpcApiContext) -> Result { - let fee_vault_address = context - .l1_ctx - .blockchain - .options - .fee_vault - .map(|addr| format!("{:#x}", addr)); - Ok(serde_json::to_value(fee_vault_address).map_err(|e| { - ethrex_rpc::RpcErr::Internal(format!("Failed to serialize fee vault address: {}", e)) - })?) + let fee_vault_address = match context.l1_ctx.blockchain.options.r#type { + ethrex_blockchain::BlockchainType::L1 => None, + ethrex_blockchain::BlockchainType::L2(fee_config) => fee_config.fee_vault, + }; + + Ok( + serde_json::to_value(fee_vault_address.map(|addr| format!("{:#x}", addr))).map_err( + |e| { + ethrex_rpc::RpcErr::Internal(format!( + "Failed to serialize fee vault address: {}", + e + )) + }, + )?, + ) } } diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index af910fc1a9a..2638413fe91 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -7,6 +7,7 @@ use ethrex_blockchain::{ }; use ethrex_common::types::AccountUpdate; use ethrex_common::types::block_execution_witness::ExecutionWitness; +use ethrex_common::types::fee_config::FeeConfig; use ethrex_common::types::{ block_execution_witness::GuestProgramState, block_execution_witness::GuestProgramStateError, }; @@ -67,6 +68,9 @@ pub enum StatelessExecutionError { #[cfg(feature = "l2")] #[error("Invalid state diff")] InvalidStateDiff, + #[cfg(feature = "l2")] + #[error("FeeConfig not provided for L2 execution")] + FeeConfigNotFound, #[error("Batch has no blocks")] EmptyBatchError, #[error("Invalid database")] @@ -100,7 +104,7 @@ pub fn execution_program(input: ProgramInput) -> Result Result, + fee_config: Option, blob_commitment: Commitment, blob_proof: Proof, chain_id: u64, @@ -177,7 +181,7 @@ pub fn stateless_validation_l2( nodes_hashed, codes_hashed, parent_block_header, - } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_vault)?; + } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_config)?; let (l1messages, privileged_transactions) = get_batch_l1messages_and_privileged_transactions(blocks, &receipts)?; @@ -261,7 +265,7 @@ fn execute_stateless( blocks: &[Block], execution_witness: ExecutionWitness, elasticity_multiplier: u64, - fee_vault: Option
, + fee_config: Option, ) -> Result { let guest_program_state: GuestProgramState = execution_witness .try_into() @@ -327,7 +331,10 @@ fn execute_stateless( // Execute block #[cfg(feature = "l2")] - let mut vm = Evm::new_for_l2(wrapped_db.clone(), fee_vault)?; + let mut vm = Evm::new_for_l2( + wrapped_db.clone(), + fee_config.ok_or_else(|| StatelessExecutionError::FeeConfigNotFound)?, + )?; #[cfg(not(feature = "l2"))] let mut vm = Evm::new_for_l1(wrapped_db.clone()); let result = vm diff --git a/crates/l2/prover/src/guest_program/src/input.rs b/crates/l2/prover/src/guest_program/src/input.rs index 1241dd3dc52..13dc3496ae5 100644 --- a/crates/l2/prover/src/guest_program/src/input.rs +++ b/crates/l2/prover/src/guest_program/src/input.rs @@ -1,6 +1,5 @@ -use ethrex_common::{ - Address, - types::{Block, block_execution_witness::ExecutionWitness}, +use ethrex_common::types::{ + Block, block_execution_witness::ExecutionWitness, fee_config::FeeConfig, }; use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; use serde::{Deserialize, Serialize}; @@ -20,8 +19,7 @@ pub struct ProgramInput { /// value used to calculate base fee pub elasticity_multiplier: u64, /// Address where collected fees are sent. If None, fees are burned. - #[rkyv(with=ethrex_common::rkyv_utils::OptionH160Wrapper)] - pub fee_vault: Option
, + pub fee_config: Option, #[cfg(feature = "l2")] /// KZG commitment to the blob data #[serde_as(as = "[_; 48]")] @@ -38,7 +36,7 @@ impl Default for ProgramInput { blocks: Default::default(), execution_witness: ExecutionWitness::default(), elasticity_multiplier: Default::default(), - fee_vault: None, + fee_config: None, #[cfg(feature = "l2")] blob_commitment: [0; 48], #[cfg(feature = "l2")] diff --git a/crates/l2/prover/src/prover.rs b/crates/l2/prover/src/prover.rs index 7175a517bd7..21e8f1df576 100644 --- a/crates/l2/prover/src/prover.rs +++ b/crates/l2/prover/src/prover.rs @@ -120,7 +120,7 @@ impl Prover { blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, - fee_vault: input.fee_vault, + fee_config: Some(input.fee_config), }, })) } diff --git a/crates/l2/sequencer/block_producer/payload_builder.rs b/crates/l2/sequencer/block_producer/payload_builder.rs index e3366468788..8d1340b9379 100644 --- a/crates/l2/sequencer/block_producer/payload_builder.rs +++ b/crates/l2/sequencer/block_producer/payload_builder.rs @@ -45,8 +45,7 @@ pub async fn build_payload( let gas_limit = payload.header.gas_limit; debug!("Building payload"); - let mut context = - PayloadBuildContext::new_for_l2(payload, store, blockchain.options.fee_vault)?; + let mut context = PayloadBuildContext::new(payload, store, blockchain.options.r#type.clone())?; fill_transactions( blockchain.clone(), diff --git a/crates/l2/sequencer/proof_coordinator.rs b/crates/l2/sequencer/proof_coordinator.rs index 45ed700a3e7..63061e0704d 100644 --- a/crates/l2/sequencer/proof_coordinator.rs +++ b/crates/l2/sequencer/proof_coordinator.rs @@ -5,9 +5,10 @@ use crate::{ BlockProducerConfig, CommitterConfig, EthConfig, ProofCoordinatorConfig, SequencerConfig, }; use bytes::Bytes; -use ethrex_blockchain::Blockchain; +use ethrex_blockchain::{Blockchain, BlockchainType}; use ethrex_common::types::BlobsBundle; use ethrex_common::types::block_execution_witness::ExecutionWitness; +use ethrex_common::types::fee_config::FeeConfig; use ethrex_common::{ Address, types::{Block, blobs_bundle}, @@ -49,7 +50,7 @@ pub struct ProverInputData { #[cfg(feature = "l2")] #[serde_as(as = "[_; 48]")] pub blob_proof: blobs_bundle::Proof, - pub fee_vault: Option
, + pub fee_config: FeeConfig, } /// Enum for the ProverServer <--> ProverClient Communication Protocol. @@ -494,6 +495,12 @@ impl ProofCoordinator { debug!("Created prover input for batch {batch_number}"); + let BlockchainType::L2(fee_config) = self.blockchain.options.r#type else { + return Err(ProofCoordinatorError::InternalError( + "Invalid blockchain type, expected L2".to_string(), + )); + }; + Ok(ProverInputData { execution_witness: witness, blocks, @@ -502,7 +509,7 @@ impl ProofCoordinator { blob_commitment, #[cfg(feature = "l2")] blob_proof, - fee_vault: self.blockchain.options.fee_vault, + fee_config, }) } diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 1482a289a85..4902adb6425 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -42,7 +42,6 @@ impl LEVM { block: &Block, db: &mut GeneralizedDatabase, vm_type: VMType, - fee_vault: Option
, ) -> Result { Self::prepare_block(block, db, vm_type)?; @@ -52,7 +51,7 @@ impl LEVM { for (tx, tx_sender) in block.body.get_transactions_with_sender().map_err(|error| { EvmError::Transaction(format!("Couldn't recover addresses with error: {error}")) })? { - let report = Self::execute_tx(tx, tx_sender, &block.header, db, vm_type, fee_vault)?; + let report = Self::execute_tx(tx, tx_sender, &block.header, db, vm_type)?; cumulative_gas_used += report.gas_used; let receipt = Receipt::new( @@ -74,7 +73,7 @@ impl LEVM { // in L2 execution, but its implementation behaves differently based on this. let requests = match vm_type { VMType::L1 => extract_all_requests_levm(&receipts, db, &block.header, vm_type)?, - VMType::L2 => Default::default(), + VMType::L2(_) => Default::default(), }; Ok(BlockExecutionResult { receipts, requests }) @@ -130,10 +129,9 @@ impl LEVM { block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, - fee_vault: Option
, ) -> Result { let env = Self::setup_env(tx, tx_sender, block_header, db)?; - let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type, fee_vault)?; + let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?; vm.execute().map_err(VMError::into) } @@ -150,7 +148,6 @@ impl LEVM { block_header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, - fee_vault: Option
, ) -> Result { let mut env = env_from_generic(tx, block_header, db)?; @@ -158,7 +155,7 @@ impl LEVM { adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(tx, env, db, vm_type, fee_vault)?; + let mut vm = vm_from_generic(tx, env, db, vm_type)?; vm.execute() .map(|value| value.into()) @@ -196,7 +193,7 @@ impl LEVM { db: &mut GeneralizedDatabase, vm_type: VMType, ) -> Result<(), EvmError> { - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Err(EvmError::InvalidEVM( "beacon_root_contract_call should not be called for L2 VM".to_string(), )); @@ -222,7 +219,7 @@ impl LEVM { db: &mut GeneralizedDatabase, vm_type: VMType, ) -> Result<(), EvmError> { - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Err(EvmError::InvalidEVM( "process_block_hash_history should not be called for L2 VM".to_string(), )); @@ -243,7 +240,7 @@ impl LEVM { db: &mut GeneralizedDatabase, vm_type: VMType, ) -> Result { - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Err(EvmError::InvalidEVM( "read_withdrawal_requests should not be called for L2 VM".to_string(), )); @@ -272,7 +269,7 @@ impl LEVM { db: &mut GeneralizedDatabase, vm_type: VMType, ) -> Result { - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Err(EvmError::InvalidEVM( "dequeue_consolidation_requests should not be called for L2 VM".to_string(), )); @@ -301,19 +298,18 @@ impl LEVM { header: &BlockHeader, db: &mut GeneralizedDatabase, vm_type: VMType, - fee_vault: Option
, ) -> Result<(ExecutionResult, AccessList), VMError> { let mut env = env_from_generic(&tx, header, db)?; adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type, fee_vault)?; + let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; vm.stateless_execute()?; // Execute the tx again, now with the created access list. tx.access_list = vm.substate.make_access_list(); - let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type, fee_vault)?; + let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; let report = vm.stateless_execute()?; @@ -336,7 +332,7 @@ impl LEVM { let fork = chain_config.fork(block_header.timestamp); // TODO: I don't like deciding the behavior based on the VMType here. - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Ok(()); } @@ -392,7 +388,7 @@ pub fn generic_system_contract_levm( ..Default::default() }); let mut vm = - VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type, None).map_err(EvmError::from)?; + VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type).map_err(EvmError::from)?; let report = vm.execute().map_err(EvmError::from)?; @@ -423,7 +419,7 @@ pub fn extract_all_requests_levm( header: &BlockHeader, vm_type: VMType, ) -> Result, EvmError> { - if let VMType::L2 = vm_type { + if let VMType::L2(_) = vm_type { return Err(EvmError::InvalidEVM( "extract_all_requests_levm should not be called for L2 VM".to_string(), )); @@ -519,7 +515,6 @@ fn vm_from_generic<'a>( env: Environment, db: &'a mut GeneralizedDatabase, vm_type: VMType, - fee_vault: Option
, ) -> Result, VMError> { let tx = match &tx.authorization_list { Some(authorization_list) => Transaction::EIP7702Transaction(EIP7702Transaction { @@ -554,5 +549,5 @@ fn vm_from_generic<'a>( ..Default::default() }), }; - VM::new(env, db, &tx, LevmCallTracer::disabled(), vm_type, fee_vault) + VM::new(env, db, &tx, LevmCallTracer::disabled(), vm_type) } diff --git a/crates/vm/backends/levm/tracing.rs b/crates/vm/backends/levm/tracing.rs index e6d14071896..b6b95228c6b 100644 --- a/crates/vm/backends/levm/tracing.rs +++ b/crates/vm/backends/levm/tracing.rs @@ -1,4 +1,3 @@ -use ethrex_common::Address; use ethrex_common::types::{Block, Transaction}; use ethrex_common::{tracing::CallTrace, types::BlockHeader}; use ethrex_levm::vm::VMType; @@ -14,7 +13,6 @@ impl LEVM { block: &Block, stop_index: Option, vm_type: VMType, - fee_vault: Option
, ) -> Result<(), EvmError> { Self::prepare_block(block, db, vm_type)?; @@ -30,7 +28,7 @@ impl LEVM { break; } - Self::execute_tx(tx, sender, &block.header, db, vm_type, fee_vault)?; + Self::execute_tx(tx, sender, &block.header, db, vm_type)?; } // Process withdrawals only if the whole block has been executed. @@ -51,7 +49,6 @@ impl LEVM { only_top_call: bool, with_log: bool, vm_type: VMType, - fee_vault: Option
, ) -> Result { let env = Self::setup_env( tx, @@ -67,7 +64,6 @@ impl LEVM { tx, LevmCallTracer::new(only_top_call, with_log), vm_type, - fee_vault, )?; vm.execute()?; diff --git a/crates/vm/backends/mod.rs b/crates/vm/backends/mod.rs index 396aa28c4a4..65687d7252d 100644 --- a/crates/vm/backends/mod.rs +++ b/crates/vm/backends/mod.rs @@ -12,12 +12,12 @@ use levm::LEVM; use crate::db::{DynVmDatabase, VmDatabase}; use crate::errors::EvmError; use crate::execution_result::ExecutionResult; -use ethrex_common::Address; use ethrex_common::types::requests::Requests; use ethrex_common::types::{ AccessList, AccountUpdate, Block, BlockHeader, Fork, GenericTransaction, Receipt, Transaction, Withdrawal, }; +use ethrex_common::{Address, types::fee_config::FeeConfig}; pub use ethrex_levm::call_frame::CallFrameBackup; use ethrex_levm::db::Database as LevmDatabase; use ethrex_levm::db::gen_db::GeneralizedDatabase; @@ -34,8 +34,6 @@ pub struct Evm { // For simplifying compilation we decided to include them both in revm and levm builds. pub db: GeneralizedDatabase, pub vm_type: VMType, - // Address where the base fee will be sent instead of burned. If None, base fees are burned. - pub fee_vault: Option
, } impl core::fmt::Debug for Evm { @@ -64,7 +62,6 @@ impl Evm { state: evm_state(wrapped_db.clone()), db: GeneralizedDatabase::new(Arc::new(wrapped_db)), vm_type: VMType::L1, - fee_vault: None, } } @@ -73,14 +70,13 @@ impl Evm { Evm { db: GeneralizedDatabase::new(Arc::new(wrapped_db)), vm_type: VMType::L1, - fee_vault: None, } } } pub fn new_for_l2( _db: impl VmDatabase + 'static, - _fee_vault: Option
, + _fee_config: FeeConfig, ) -> Result { #[cfg(feature = "revm")] { @@ -95,8 +91,7 @@ impl Evm { let evm = Evm { db: GeneralizedDatabase::new(Arc::new(wrapped_db)), - vm_type: VMType::L2, - fee_vault: _fee_vault, + vm_type: VMType::L2(_fee_config), }; Ok(evm) @@ -104,36 +99,27 @@ impl Evm { } pub fn new_from_db_for_l1(store: Arc) -> Self { - Self::_new_from_db(store, VMType::L1, None) + Self::_new_from_db(store, VMType::L1) } pub fn new_from_db_for_l2( store: Arc, - fee_vault: Option
, + fee_config: FeeConfig, ) -> Self { - Self::_new_from_db(store, VMType::L2, fee_vault) + Self::_new_from_db(store, VMType::L2(fee_config)) } // Only used in non-REVM builds; in REVM builds this constructor is not supported. #[cfg(feature = "revm")] - fn _new_from_db( - _store: Arc, - _vm_type: VMType, - _fee_vault: Option
, - ) -> Self { + fn _new_from_db(_store: Arc, _vm_type: VMType) -> Self { unreachable!("new_from_db is not supported when built with the `revm` feature") } #[cfg(not(feature = "revm"))] - fn _new_from_db( - store: Arc, - vm_type: VMType, - fee_vault: Option
, - ) -> Self { + fn _new_from_db(store: Arc, vm_type: VMType) -> Self { Evm { db: GeneralizedDatabase::new(store), vm_type, - fee_vault, } } @@ -146,7 +132,7 @@ impl Evm { #[cfg(not(feature = "revm"))] { - LEVM::execute_block(block, &mut self.db, self.vm_type, self.fee_vault) + LEVM::execute_block(block, &mut self.db, self.vm_type) } } @@ -185,14 +171,8 @@ impl Evm { #[cfg(not(feature = "revm"))] { - let execution_report = LEVM::execute_tx( - tx, - sender, - block_header, - &mut self.db, - self.vm_type, - self.fee_vault, - )?; + let execution_report = + LEVM::execute_tx(tx, sender, block_header, &mut self.db, self.vm_type)?; *remaining_gas = remaining_gas.saturating_sub(execution_report.gas_used); @@ -323,7 +303,7 @@ impl Evm { #[cfg(not(feature = "revm"))] { - LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type, self.fee_vault) + LEVM::simulate_tx_from_generic(tx, header, &mut self.db, self.vm_type) } } @@ -340,15 +320,7 @@ impl Evm { }; #[cfg(not(feature = "revm"))] - let result = { - LEVM::create_access_list( - tx.clone(), - header, - &mut self.db, - self.vm_type, - self.fee_vault, - )? - }; + let result = { LEVM::create_access_list(tx.clone(), header, &mut self.db, self.vm_type)? }; match result { ( diff --git a/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs b/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs index b5391221582..00b8051f1c3 100644 --- a/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs +++ b/crates/vm/levm/bench/revm_comparison/src/levm_bench.rs @@ -83,5 +83,5 @@ fn init_vm(db: &mut GeneralizedDatabase, nonce: u64, calldata: Bytes) -> Result< data: calldata, ..Default::default() }); - VM::new(env, db, &tx, LevmCallTracer::disabled(), VMType::L1, None) + VM::new(env, db, &tx, LevmCallTracer::disabled(), VMType::L1) } diff --git a/crates/vm/levm/runner/src/main.rs b/crates/vm/levm/runner/src/main.rs index 6cbc288aaac..978ec7e36c6 100644 --- a/crates/vm/levm/runner/src/main.rs +++ b/crates/vm/levm/runner/src/main.rs @@ -151,7 +151,6 @@ fn main() { &Transaction::LegacyTransaction(LegacyTransaction::from(runner_input.transaction.clone())), LevmCallTracer::disabled(), VMType::L1, - None, ) .expect("Failed to initialize VM"); diff --git a/crates/vm/levm/src/hooks/hook.rs b/crates/vm/levm/src/hooks/hook.rs index c7e27ff990a..5af3ff590d0 100644 --- a/crates/vm/levm/src/hooks/hook.rs +++ b/crates/vm/levm/src/hooks/hook.rs @@ -1,12 +1,11 @@ -use std::{cell::RefCell, rc::Rc}; - -use ethrex_common::Address; +use ethrex_common::types::fee_config::FeeConfig; use crate::{ errors::{ContextResult, VMError}, hooks::{L2Hook, backup_hook::BackupHook, default_hook::DefaultHook}, vm::{VM, VMType}, }; +use std::{cell::RefCell, rc::Rc}; pub trait Hook { fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), VMError>; @@ -18,13 +17,10 @@ pub trait Hook { ) -> Result<(), VMError>; } -pub fn get_hooks( - vm_type: &VMType, - fee_vault: Option
, -) -> Vec>> { +pub fn get_hooks(vm_type: &VMType) -> Vec>> { match vm_type { VMType::L1 => l1_hooks(), - VMType::L2 => l2_hooks(fee_vault), + VMType::L2(fee_config) => l2_hooks(*fee_config), } } @@ -32,9 +28,9 @@ pub fn l1_hooks() -> Vec>> { vec![Rc::new(RefCell::new(DefaultHook))] } -pub fn l2_hooks(fee_vault: Option
) -> Vec>> { +pub fn l2_hooks(fee_config: FeeConfig) -> Vec>> { vec![ - Rc::new(RefCell::new(L2Hook { fee_vault })), + Rc::new(RefCell::new(L2Hook { fee_config })), Rc::new(RefCell::new(BackupHook::default())), ] } diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 3896e6e3548..34fbe74da39 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -5,7 +5,7 @@ use crate::{ vm::VM, }; -use ethrex_common::{Address, H160, U256}; +use ethrex_common::{Address, H160, U256, types::fee_config::FeeConfig}; pub const COMMON_BRIDGE_L2_ADDRESS: Address = H160([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13,8 +13,7 @@ pub const COMMON_BRIDGE_L2_ADDRESS: Address = H160([ ]); pub struct L2Hook { - /// If set, the base fee is sent to this address instead of being burned. - pub fee_vault: Option
, + pub fee_config: FeeConfig, } impl Hook for L2Hook { @@ -112,7 +111,7 @@ impl Hook for L2Hook { if !vm.env.is_privileged { DefaultHook.finalize_execution(vm, ctx_result)?; // Different from L1, the base fee is not burned - return pay_to_fee_vault(vm, ctx_result.gas_used, self.fee_vault); + return pay_to_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs index 67f42eb1491..599912ae246 100644 --- a/crates/vm/levm/src/vm.rs +++ b/crates/vm/levm/src/vm.rs @@ -20,7 +20,7 @@ use bytes::Bytes; use ethrex_common::{ Address, H160, H256, U256, tracing::CallType, - types::{AccessListEntry, Fork, Log, Transaction}, + types::{AccessListEntry, Fork, Log, Transaction, fee_config::FeeConfig}, }; use std::{ cell::RefCell, @@ -35,7 +35,7 @@ pub type Storage = HashMap; pub enum VMType { #[default] L1, - L2, + L2(FeeConfig), } /// Information that changes during transaction execution. @@ -335,7 +335,6 @@ impl<'a> VM<'a> { tx: &Transaction, tracer: LevmCallTracer, vm_type: VMType, - fee_vault: Option
, ) -> Result { db.tx_backup = None; // If BackupHook is enabled, it will contain backup at the end of tx execution. @@ -350,7 +349,7 @@ impl<'a> VM<'a> { substate, db, tx: tx.clone(), - hooks: get_hooks(&vm_type, fee_vault), + hooks: get_hooks(&vm_type), substate_backups: Vec::new(), storage_original_values: BTreeMap::new(), tracer, diff --git a/crates/vm/tracing.rs b/crates/vm/tracing.rs index 2843fdcc6ce..26298f4f604 100644 --- a/crates/vm/tracing.rs +++ b/crates/vm/tracing.rs @@ -42,7 +42,6 @@ impl Evm { only_top_call, with_log, self.vm_type, - self.fee_vault, ) } } @@ -63,13 +62,7 @@ impl Evm { #[cfg(not(feature = "revm"))] { - LEVM::rerun_block( - &mut self.db, - block, - stop_index, - self.vm_type, - self.fee_vault, - ) + LEVM::rerun_block(&mut self.db, block, stop_index, self.vm_type) } } } diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index ddc6b23040f..cd6b6cb8f60 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220961ae9e1d2a628512962b1f8f4c79559df1ecd98b3141766e6ac95fb257590b964736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" diff --git a/tooling/ef_tests/state/runner/levm_runner.rs b/tooling/ef_tests/state/runner/levm_runner.rs index 62e4b16b562..5a51b91cfc4 100644 --- a/tooling/ef_tests/state/runner/levm_runner.rs +++ b/tooling/ef_tests/state/runner/levm_runner.rs @@ -239,7 +239,6 @@ pub fn prepare_vm_for_tx<'a>( &tx, LevmCallTracer::disabled(), VMType::L1, // TODO: Should we run the EF tests with L2? - None, ) .map_err(|e| EFTestRunnerError::FailedToEnsurePreState(format!("Failed to initialize VM: {e}"))) } diff --git a/tooling/ef_tests/state_v2/src/modules/block_runner.rs b/tooling/ef_tests/state_v2/src/modules/block_runner.rs index 2397578dadb..ed579f332f9 100644 --- a/tooling/ef_tests/state_v2/src/modules/block_runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/block_runner.rs @@ -43,8 +43,8 @@ pub async fn run_test(test: &Test, test_case: &TestCase) -> Result<(), RunnerErr let (mut db, initial_block_hash, store, _genesis) = load_initial_state(test, &test_case.fork).await; - let mut vm = VM::new(env.clone(), &mut db, &tx, tracer, VMType::L1, None) - .map_err(RunnerError::VMError)?; + let mut vm = + VM::new(env.clone(), &mut db, &tx, tracer, VMType::L1).map_err(RunnerError::VMError)?; let execution_result = vm.execute(); let (receipts, gas_used) = match execution_result { diff --git a/tooling/ef_tests/state_v2/src/modules/runner.rs b/tooling/ef_tests/state_v2/src/modules/runner.rs index 7bd0c93aee6..73fc0ec1671 100644 --- a/tooling/ef_tests/state_v2/src/modules/runner.rs +++ b/tooling/ef_tests/state_v2/src/modules/runner.rs @@ -83,7 +83,7 @@ pub async fn run_test( let tx = get_tx_from_test_case(test_case).await?; let tracer = LevmCallTracer::disabled(); let mut vm = - VM::new(env, &mut db, &tx, tracer, VMType::L1, None).map_err(RunnerError::VMError)?; + VM::new(env, &mut db, &tx, tracer, VMType::L1).map_err(RunnerError::VMError)?; // Execute transaction with VM. let execution_result = vm.execute(); From 3b3d0016f3bfb665fc086f6d2246ca58b6b77b34 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 30 Sep 2025 15:09:20 -0300 Subject: [PATCH 27/88] Fix ethrex replay for l2 --- cmd/ethrex_replay/src/cli.rs | 40 +++++++++++++++++++++++++------- cmd/ethrex_replay/src/fetcher.rs | 10 ++++---- cmd/ethrex_replay/src/run.rs | 14 ++++++----- crates/blockchain/blockchain.rs | 2 +- fixtures/genesis/l2.json | 14 +++++------ 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index 5e228738575..93b97355a12 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -666,9 +666,12 @@ impl EthrexReplayCommand { let (eth_client, network) = setup(&opts).await?; - let fee_vault = get_fee_vault_address(ð_client).await?; + let fee_config = Some(FeeConfig { + fee_vault: get_fee_vault_address(ð_client).await?, + ..Default::default() + }); - let cache = get_batchdata(eth_client, network, batch, fee_vault).await?; + let cache = get_batchdata(eth_client, network, batch, fee_config).await?; let backend = backend(&opts.common.zkvm)?; @@ -721,9 +724,16 @@ impl EthrexReplayCommand { no_zkvm: false, cache_level: CacheLevel::default(), slack_webhook_url: None, + verbose: false, + bench: false, + }; + + let fee_config = FeeConfig { + fee_vault: fee_vault, + ..Default::default() }; - let report = replay_custom_l2_blocks(max(1, n_blocks), fee_vault, opts).await?; + let report = replay_custom_l2_blocks(max(1, n_blocks), fee_config, opts).await?; println!("{report}"); } @@ -1262,9 +1272,13 @@ use ethrex_vm::BlockExecutionResult; #[cfg(feature = "l2")] pub async fn replay_custom_l2_blocks( n_blocks: u64, - fee_vault: Option
, + fee_config: FeeConfig, opts: EthrexReplayOptions, ) -> eyre::Result { + use ethrex_blockchain::{BlockchainOptions, BlockchainType, MAX_MEMPOOL_SIZE_DEFAULT}; + + use crate::cache::L2Fields; + let network = Network::LocalDevnetL2; let genesis = network.get_genesis()?; @@ -1287,9 +1301,11 @@ pub async fn replay_custom_l2_blocks( let blockchain = Arc::new(Blockchain::new( store.clone(), - BlockchainType::L2, - false, - fee_vault, + BlockchainOptions { + max_mempool_size: MAX_MEMPOOL_SIZE_DEFAULT, + r#type: BlockchainType::L2(fee_config.clone()), + ..Default::default() + }, )); let genesis_hash = genesis.get_block().hash(); @@ -1306,11 +1322,17 @@ pub async fn replay_custom_l2_blocks( let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; + let l2_fields = Some(L2Fields { + blob_commitment: [0u8; 48], + blob_proof: [0u8; 48], + fee_config, + }); + let cache = Cache::new( blocks, RpcExecutionWitness::from(execution_witness), genesis.config, - fee_vault, + l2_fields, ); let backend = backend(&opts.common.zkvm)?; @@ -1390,7 +1412,7 @@ pub async fn produce_custom_l2_block( gas_ceil: DEFAULT_BUILDER_GAS_CEIL, }; - let payload = create_payload(&build_payload_args, store)?; + let payload = create_payload(&build_payload_args, store, Bytes::new())?; let payload_build_result = build_payload( blockchain.clone(), diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index 022ec4b9398..c547424adb7 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -96,7 +96,9 @@ pub async fn get_blockdata( warn!("debug_executionWitness endpoint not implemented, using fallback eth_getProof"); #[cfg(feature = "l2")] - let vm_type = VMType::L2; + let vm_type = VMType::L2( + _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, + ); #[cfg(not(feature = "l2"))] let vm_type = VMType::L1; @@ -282,7 +284,7 @@ pub async fn get_batchdata( rollup_client: EthClient, network: Network, batch_number: u64, - fee_vault: Option
, + fee_config: Option, ) -> eyre::Result { use ethrex_l2_rpc::clients::get_batch_by_number; @@ -300,7 +302,7 @@ pub async fn get_batchdata( network.get_genesis()?.config, rpc_batch.batch.first_block, rpc_batch.batch.last_block, - fee_vault, + fee_config, ) .await?; @@ -318,7 +320,7 @@ pub async fn get_batchdata( .proofs .first() .unwrap_or(&[0_u8; 48]), - fee_vault, + fee_config: fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, }); cache.write()?; diff --git a/cmd/ethrex_replay/src/run.rs b/cmd/ethrex_replay/src/run.rs index b79430281ce..0a9f9010b25 100644 --- a/cmd/ethrex_replay/src/run.rs +++ b/cmd/ethrex_replay/src/run.rs @@ -106,7 +106,12 @@ pub async fn run_tx(cache: Cache, tx_hash: H256) -> eyre::Result<(Receipt, Vec eyre::Result<(Receipt, Vec eyre::Result { elasticity_multiplier: ELASTICITY_MULTIPLIER, blob_commitment: l2_fields.blob_commitment, blob_proof: l2_fields.blob_proof, - fee_vault: l2_fields.fee_vault, + fee_config: Some(l2_fields.fee_config), }) } diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index 208ff596129..2988f1fe62a 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -49,7 +49,7 @@ use ethrex_metrics::metrics_blocks::METRICS_BLOCKS; use ethrex_common::types::BlobsBundle; const MAX_PAYLOADS: usize = 10; -const MAX_MEMPOOL_SIZE_DEFAULT: usize = 10_000; +pub const MAX_MEMPOOL_SIZE_DEFAULT: usize = 10_000; //TODO: Implement a struct Chain or BlockChain to encapsulate //functionality and canonical chain state and config diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index cd6b6cb8f60..b4d8f515f13 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -57,19 +57,19 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea26469706673582212202b117db6ab0c51bf9996d96714ca144c747436e262b0ff72b264674c5ce8ca7864736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea2646970667358221220254b9cd21ba4a3393799c35cdd4c56266ed31bed0acae2f4dc2dfedf0e55c65a64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220e8ff78fccd558ce2353e1d7c6ef9f7d5a31231f4dc26cac6f2c68f323c8b3d5f64736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea26469706673582212201f4cbb6764c259cc74da5665b55eb3e7441e150a2c8efc0ade605cbc70a8965e64736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220961ae9e1d2a628512962b1f8f4c79559df1ecd98b3141766e6ac95fb257590b964736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" @@ -78,16 +78,16 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220961ae9e1d2a628512962b1f8f4c79559df1ecd98b3141766e6ac95fb257590b964736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea26469706673582212204ef2140b5ed0e0c8e13386861dcc8c907036672db6141fab296e94611f66e40064736f6c634300081d0033a2646970667358221220a34372b31ab6f61f3dad2bb4d92b6297700c56a75273a84c9b9393e39f67228564736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea264697066735822122044bf02eaa3ba5bc8d15555c7b89f6e345878257368b6885caa55dc32cac2d1e864736f6c634300081d0033a2646970667358221220cd3b29b568f2dc998fa50a6f9cf580dc01e15a176e0c7c824f72c3bc6ae860e664736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" From aa01211bfe00447dac06a049c95975018bed1b5d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 30 Sep 2025 15:12:45 -0300 Subject: [PATCH 28/88] Fix tdx build --- crates/l2/tee/quote-gen/src/sender.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/l2/tee/quote-gen/src/sender.rs b/crates/l2/tee/quote-gen/src/sender.rs index 699dd5ca5e3..a26c83cb14e 100644 --- a/crates/l2/tee/quote-gen/src/sender.rs +++ b/crates/l2/tee/quote-gen/src/sender.rs @@ -33,7 +33,7 @@ pub async fn get_batch(commit_hash: String) -> Result<(u64, ProgramInput), Strin blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, - fee_vault: input.fee_vault, + fee_config: Some(input.fee_config), }, )), _ => Err("No blocks to prove.".to_owned()), From 9eaf648e0e977ef9d17fac2f33e4d403d93d29fc Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 30 Sep 2025 15:36:19 -0300 Subject: [PATCH 29/88] Minor improvements --- cmd/ethrex_replay/src/cli.rs | 9 ++--- cmd/ethrex_replay/src/fetcher.rs | 40 ++++++++++--------- .../l2/prover/src/guest_program/src/input.rs | 2 +- crates/vm/levm/src/hooks/hook.rs | 3 +- crates/vm/levm/src/hooks/l2_hook.rs | 8 ++-- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index 93b97355a12..97a5172eb85 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -666,10 +666,10 @@ impl EthrexReplayCommand { let (eth_client, network) = setup(&opts).await?; - let fee_config = Some(FeeConfig { + let fee_config = FeeConfig { fee_vault: get_fee_vault_address(ð_client).await?, ..Default::default() - }); + }; let cache = get_batchdata(eth_client, network, batch, fee_config).await?; @@ -699,9 +699,7 @@ impl EthrexReplayCommand { Self::L2(L2Subcommand::Custom(CustomSubcommand::Batch( CustomBatchOptions { n_blocks: 1, - common, - fee_vault, }, ))) @@ -1275,9 +1273,8 @@ pub async fn replay_custom_l2_blocks( fee_config: FeeConfig, opts: EthrexReplayOptions, ) -> eyre::Result { - use ethrex_blockchain::{BlockchainOptions, BlockchainType, MAX_MEMPOOL_SIZE_DEFAULT}; - use crate::cache::L2Fields; + use ethrex_blockchain::{BlockchainOptions, BlockchainType, MAX_MEMPOOL_SIZE_DEFAULT}; let network = Network::LocalDevnetL2; diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index c547424adb7..efadd24071c 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -151,14 +151,15 @@ pub async fn get_blockdata( format_duration(&execution_witness_retrieval_duration) ); - #[cfg(not(feature = "l2"))] - let l2_fields = None; - #[cfg(feature = "l2")] - let l2_fields = Some(L2Fields { - blob_commitment: [0u8; 48], - blob_proof: [0u8; 48], - fee_config: _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, - }); + let l2_fields = if cfg!(feature = "l2") { + Some(L2Fields { + blob_commitment: [0u8; 48], + blob_proof: [0u8; 48], + fee_config: _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, + }) + } else { + None + }; Ok(Cache::new( vec![block], @@ -240,14 +241,15 @@ async fn fetch_rangedata_from_client( format_duration(&execution_witness_retrieval_duration) ); - #[cfg(not(feature = "l2"))] - let l2_fields = None; - #[cfg(feature = "l2")] - let l2_fields = Some(L2Fields { - blob_commitment: [0u8; 48], - blob_proof: [0u8; 48], - fee_config: _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, - }); + let l2_fields = if cfg!(feature = "l2") { + Some(L2Fields { + blob_commitment: [0u8; 48], + blob_proof: [0u8; 48], + fee_config: _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, + }) + } else { + None + }; let cache = Cache::new(blocks, witness_rpc, chain_config, l2_fields); @@ -284,7 +286,7 @@ pub async fn get_batchdata( rollup_client: EthClient, network: Network, batch_number: u64, - fee_config: Option, + fee_config: FeeConfig, ) -> eyre::Result { use ethrex_l2_rpc::clients::get_batch_by_number; @@ -302,7 +304,7 @@ pub async fn get_batchdata( network.get_genesis()?.config, rpc_batch.batch.first_block, rpc_batch.batch.last_block, - fee_config, + Some(fee_config), ) .await?; @@ -320,7 +322,7 @@ pub async fn get_batchdata( .proofs .first() .unwrap_or(&[0_u8; 48]), - fee_config: fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, + fee_config, }); cache.write()?; diff --git a/crates/l2/prover/src/guest_program/src/input.rs b/crates/l2/prover/src/guest_program/src/input.rs index 13dc3496ae5..31bb3989843 100644 --- a/crates/l2/prover/src/guest_program/src/input.rs +++ b/crates/l2/prover/src/guest_program/src/input.rs @@ -18,7 +18,7 @@ pub struct ProgramInput { pub execution_witness: ExecutionWitness, /// value used to calculate base fee pub elasticity_multiplier: u64, - /// Address where collected fees are sent. If None, fees are burned. + /// Configuration for L2 fees pub fee_config: Option, #[cfg(feature = "l2")] /// KZG commitment to the blob data diff --git a/crates/vm/levm/src/hooks/hook.rs b/crates/vm/levm/src/hooks/hook.rs index 5af3ff590d0..d79c4fb5a79 100644 --- a/crates/vm/levm/src/hooks/hook.rs +++ b/crates/vm/levm/src/hooks/hook.rs @@ -1,10 +1,9 @@ -use ethrex_common::types::fee_config::FeeConfig; - use crate::{ errors::{ContextResult, VMError}, hooks::{L2Hook, backup_hook::BackupHook, default_hook::DefaultHook}, vm::{VM, VMType}, }; +use ethrex_common::types::fee_config::FeeConfig; use std::{cell::RefCell, rc::Rc}; pub trait Hook { diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 34fbe74da39..46f52660a45 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -131,13 +131,15 @@ fn pay_to_fee_vault( gas_to_pay: u64, fee_vault: Option
, ) -> Result<(), crate::errors::VMError> { - let base_fee = U256::from(gas_to_pay) - .checked_mul(vm.env.base_fee_per_gas) - .ok_or(InternalError::Overflow)?; let Some(fee_vault) = fee_vault else { // No fee vault configured, base fee is effectively burned return Ok(()); }; + + let base_fee = U256::from(gas_to_pay) + .checked_mul(vm.env.base_fee_per_gas) + .ok_or(InternalError::Overflow)?; + vm.increase_account_balance(fee_vault, base_fee)?; Ok(()) } From d4dc6596688faa0fbe91efc35d00ef9ba98c675d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 30 Sep 2025 15:40:41 -0300 Subject: [PATCH 30/88] Fix linter --- cmd/ethrex_replay/src/fetcher.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index efadd24071c..70f3a73696d 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -17,7 +17,6 @@ use crate::{ rpc::db::RpcDB, }; -#[cfg(feature = "l2")] use crate::cache::L2Fields; #[cfg(feature = "l2")] use crate::cache::get_batch_cache_file_name; From 228175a639b02f3d09fdde0860fe1e9d5c94b9f8 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 1 Oct 2025 13:18:54 -0300 Subject: [PATCH 31/88] feat(l2): implement operator fee --- cmd/ethrex/l2/initializers.rs | 9 +++-- cmd/ethrex/l2/options.rs | 10 ++++++ crates/common/types/l2/fee_config.rs | 7 ++-- crates/l2/sequencer/configs.rs | 1 + crates/vm/levm/src/hooks/default_hook.rs | 2 +- crates/vm/levm/src/hooks/l2_hook.rs | 44 +++++++++++++++++++++--- crates/vm/levm/src/utils.rs | 10 +++--- 7 files changed, 67 insertions(+), 16 deletions(-) diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 1ceaaef5cde..618b1a0c9aa 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -6,7 +6,7 @@ use std::time::Duration; use ethrex_blockchain::{Blockchain, BlockchainType}; use ethrex_common::Address; use ethrex_common::types::DEFAULT_BUILDER_GAS_CEIL; -use ethrex_common::types::fee_config::FeeConfig; +use ethrex_common::types::fee_config::{FeeConfig, OperatorFeeConfig}; use ethrex_l2::SequencerConfig; use ethrex_p2p::kademlia::Kademlia; use ethrex_p2p::network::peer_table; @@ -170,7 +170,12 @@ pub async fn init_l2( let fee_config = FeeConfig { fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, - ..Default::default() + operator_fee_config: OperatorFeeConfig { + operator_fee_vault: opts + .sequencer_opts + .block_producer_opts + .operator_fee_vault_address, + }..Default::default(), }; let blockchain_opts = ethrex_blockchain::BlockchainOptions { diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 03fe0d305c5..0dacec13acc 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -161,6 +161,7 @@ impl TryFrom for SequencerConfig { .coinbase_address .ok_or(SequencerOptionsError::NoCoinbaseAddress)?, fee_vault_address: opts.block_producer_opts.fee_vault_address, + operator_fee_vault_address: opts.block_producer_opts.operator_fee_vault_address, elasticity_multiplier: opts.block_producer_opts.elasticity_multiplier, block_gas_limit: opts.block_producer_opts.block_gas_limit, }, @@ -395,6 +396,14 @@ pub struct BlockProducerOptions { help_heading = "Block producer options" )] pub fee_vault_address: Option
, + // TODO: rename fee_vault to base_fee_vault + #[arg( + long = "block-producer.operator-fee-vault-address", + value_name = "ADDRESS", + env = "ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS", + help_heading = "Block producer options" + )] + pub operator_fee_vault_address: Option
, #[arg( long, default_value = "2", @@ -424,6 +433,7 @@ impl Default for BlockProducerOptions { .unwrap(), ), fee_vault_address: None, + operator_fee_vault_address: None, elasticity_multiplier: 2, block_gas_limit: DEFAULT_BUILDER_GAS_CEIL, } diff --git a/crates/common/types/l2/fee_config.rs b/crates/common/types/l2/fee_config.rs index 9a37cf5e52f..cee258d66b9 100644 --- a/crates/common/types/l2/fee_config.rs +++ b/crates/common/types/l2/fee_config.rs @@ -1,8 +1,8 @@ -use ethereum_types::Address; +use ethereum_types::{Address, U256}; use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; use serde::{Deserialize, Serialize}; -use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper}; +use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper, U256Wrapper}; #[derive( Serialize, Deserialize, RDeserialize, RSerialize, Archive, Clone, Copy, Debug, Default, @@ -22,5 +22,6 @@ pub struct FeeConfig { pub struct OperatorFeeConfig { #[rkyv(with=H160Wrapper)] pub operator_fee_vault: Address, - pub operator_fee: u64, + #[rkyv(with=U256Wrapper)] + pub operator_fee: U256, } diff --git a/crates/l2/sequencer/configs.rs b/crates/l2/sequencer/configs.rs index 2a09d982846..d72046190b8 100644 --- a/crates/l2/sequencer/configs.rs +++ b/crates/l2/sequencer/configs.rs @@ -24,6 +24,7 @@ pub struct BlockProducerConfig { pub block_time_ms: u64, pub coinbase_address: Address, pub fee_vault_address: Option
, + pub operator_fee_vault_address: Option
, pub elasticity_multiplier: u64, pub block_gas_limit: u64, } diff --git a/crates/vm/levm/src/hooks/default_hook.rs b/crates/vm/levm/src/hooks/default_hook.rs index 22ce5f7d161..b6a973c8571 100644 --- a/crates/vm/levm/src/hooks/default_hook.rs +++ b/crates/vm/levm/src/hooks/default_hook.rs @@ -454,7 +454,7 @@ pub fn deduct_caller( // Up front cost is the maximum amount of wei that a user is willing to pay for. Gaslimit * gasprice + value + blob_gas_cost let value = vm.current_call_frame.msg_value; - let blob_gas_cost = get_blob_gas_price( + let blob_gas_cost = calculate_blob_gas_cost( &vm.env.tx_blob_hashes, vm.env.block_excess_blob_gas, &vm.env.config, diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 46f52660a45..470c4908a32 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -1,11 +1,14 @@ use crate::{ - errors::{ContextResult, InternalError}, + errors::{ContextResult, InternalError, TxValidationError}, hooks::{DefaultHook, default_hook, hook::Hook}, opcodes::Opcode, vm::VM, }; -use ethrex_common::{Address, H160, U256, types::fee_config::FeeConfig}; +use ethrex_common::{ + Address, H160, U256, + types::fee_config::{FeeConfig, OperatorFeeConfig}, +}; pub const COMMON_BRIDGE_L2_ADDRESS: Address = H160([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -19,7 +22,9 @@ pub struct L2Hook { impl Hook for L2Hook { fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { - return DefaultHook.prepare_execution(vm); + DefaultHook.prepare_execution(vm)?; + deduct_operator_fee(vm, &self.fee_config.operator_fee_config)?; + return Ok(()); } let sender_address = vm.env.origin; @@ -111,7 +116,8 @@ impl Hook for L2Hook { if !vm.env.is_privileged { DefaultHook.finalize_execution(vm, ctx_result)?; // Different from L1, the base fee is not burned - return pay_to_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault); + pay_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault)?; + pay_operator_fee(vm, self.fee_config.operator_fee_config)?; } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { @@ -126,7 +132,22 @@ impl Hook for L2Hook { } } -fn pay_to_fee_vault( +fn deduct_operator_fee( + vm: &mut VM<'_>, + operator_fee_config: &Option, +) -> Result<(), crate::errors::VMError> { + let Some(fee_config) = operator_fee_config else { + // No operator fee configured, operator fee is not paid + return Ok(()); + }; + let sender_address = vm.env.origin; + + vm.decrease_account_balance(sender_address, fee_config.operator_fee) + .map_err(|_| TxValidationError::InsufficientAccountFunds)?; + Ok(()) +} + +fn pay_fee_vault( vm: &mut VM<'_>, gas_to_pay: u64, fee_vault: Option
, @@ -143,3 +164,16 @@ fn pay_to_fee_vault( vm.increase_account_balance(fee_vault, base_fee)?; Ok(()) } + +fn pay_operator_fee( + vm: &mut VM<'_>, + operator_fee_config: Option, +) -> Result<(), crate::errors::VMError> { + let Some(fee_config) = operator_fee_config else { + // No operator fee configured, operator fee is not paid + return Ok(()); + }; + + vm.increase_account_balance(fee_config.operator_fee_vault, fee_config.operator_fee)?; + Ok(()) +} diff --git a/crates/vm/levm/src/utils.rs b/crates/vm/levm/src/utils.rs index eb602b3d39a..6aefc59c3f6 100644 --- a/crates/vm/levm/src/utils.rs +++ b/crates/vm/levm/src/utils.rs @@ -201,8 +201,8 @@ pub fn get_max_blob_gas_price( Ok(max_blob_gas_cost) } -/// Gets the actual blob gas cost. -pub fn get_blob_gas_price( +/// Caltulate the actual blob gas cost. +pub fn calculate_blob_gas_cost( tx_blob_hashes: &[H256], block_excess_blob_gas: Option, evm_config: &EVMConfig, @@ -212,14 +212,14 @@ pub fn get_blob_gas_price( .try_into() .map_err(|_| InternalError::TypeConversion)?; - let blob_gas_price: u64 = blobhash_amount + let blob_gas_used: u64 = blobhash_amount .checked_mul(BLOB_GAS_PER_BLOB) .unwrap_or_default(); let base_fee_per_blob_gas = get_base_fee_per_blob_gas(block_excess_blob_gas, evm_config)?; - let blob_gas_price: U256 = blob_gas_price.into(); - let blob_fee: U256 = blob_gas_price + let blob_gas_used: U256 = blob_gas_used.into(); + let blob_fee: U256 = blob_gas_used .checked_mul(base_fee_per_blob_gas) .ok_or(InternalError::Overflow)?; From 88ab25e380042c816f864c68783b1967fd05f87c Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 14:06:54 -0300 Subject: [PATCH 32/88] Update deployer --- cmd/ethrex/l2/deployer.rs | 12 +++- cmd/ethrex/l2/initializers.rs | 62 ++++++++++++++++--- crates/l2/Makefile | 3 +- .../l2/contracts/src/l1/OnChainProposer.sol | 7 ++- crates/l2/sdk/src/sdk.rs | 19 ++++++ crates/l2/sequencer/block_producer.rs | 9 +++ fixtures/genesis/l2.json | 8 +-- 7 files changed, 105 insertions(+), 15 deletions(-) diff --git a/cmd/ethrex/l2/deployer.rs b/cmd/ethrex/l2/deployer.rs index 9e8d75f26ae..13de4e7575d 100644 --- a/cmd/ethrex/l2/deployer.rs +++ b/cmd/ethrex/l2/deployer.rs @@ -324,6 +324,14 @@ pub struct DeployerOptions { help = "Genesis data is extracted at compile time, used for development" )] pub use_compiled_genesis: bool, + #[arg( + long, + value_name = "UINT256", + env = "ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE", + help_heading = "Deployer options", + help = "Fee that the operator will receive for each transaction included in a block." + )] + pub operator_fee: U256, } impl Default for DeployerOptions { @@ -406,6 +414,7 @@ impl Default for DeployerOptions { sequencer_registry_owner: None, inclusion_max_wait: 3000, use_compiled_genesis: true, + operator_fee: U256::zero(), } } } @@ -485,7 +494,7 @@ const SP1_VERIFIER_BYTECODE: &[u8] = include_bytes!(concat!( )); const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE_BASED: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address,uint256)"; -const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address[],uint256)"; +const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address[],uint256,uint256)"; const INITIALIZE_BRIDGE_ADDRESS_SIGNATURE: &str = "initializeBridgeAddress(address)"; const TRANSFER_OWNERSHIP_SIGNATURE: &str = "transferOwnership(address)"; @@ -824,6 +833,7 @@ async fn initialize_contracts( Value::Address(opts.proof_sender_l1_address), ]), Value::Uint(genesis.config.chain_id.into()), + Value::Uint(opts.operator_fee), ]; trace!(calldata_values = ?calldata_values, "OnChainProposer initialization calldata values"); let on_chain_proposer_initialization_calldata = diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 618b1a0c9aa..f5e0ae2f16b 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -4,16 +4,19 @@ use std::sync::Arc; use std::time::Duration; use ethrex_blockchain::{Blockchain, BlockchainType}; -use ethrex_common::Address; use ethrex_common::types::DEFAULT_BUILDER_GAS_CEIL; use ethrex_common::types::fee_config::{FeeConfig, OperatorFeeConfig}; +use ethrex_common::{Address, U256}; use ethrex_l2::SequencerConfig; +use ethrex_l2_sdk::get_operator_fee; use ethrex_p2p::kademlia::Kademlia; use ethrex_p2p::network::peer_table; use ethrex_p2p::peer_handler::PeerHandler; use ethrex_p2p::rlpx::l2::l2_connection::P2PBasedContext; use ethrex_p2p::sync_manager::SyncManager; use ethrex_p2p::types::{Node, NodeRecord}; +use ethrex_rpc::EthClient; +use ethrex_rpc::clients::EthClientError; use ethrex_storage::Store; use ethrex_storage_rollup::{EngineTypeRollup, StoreRollup}; use secp256k1::SecretKey; @@ -31,7 +34,7 @@ use crate::initializers::{ self, get_authrpc_socket_addr, get_http_socket_addr, get_local_node_record, get_local_p2p_node, get_network, get_signer, init_blockchain, init_network, init_store, }; -use crate::l2::L2Options; +use crate::l2::{L2Options, SequencerOptions}; use crate::utils::{ NodeConfigFile, get_client_version, init_datadir, read_jwtsecret_file, store_node_config_file, }; @@ -168,14 +171,11 @@ pub async fn init_l2( let store = init_store(&datadir, genesis).await; let rollup_store = init_rollup_store(&rollup_store_dir).await; + let operator_fee_config = get_operator_fee_config(&opts.sequencer_opts).await?; + let fee_config = FeeConfig { fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, - operator_fee_config: OperatorFeeConfig { - operator_fee_vault: opts - .sequencer_opts - .block_producer_opts - .operator_fee_vault_address, - }..Default::default(), + operator_fee_config: operator_fee_config, }; let blockchain_opts = ethrex_blockchain::BlockchainOptions { @@ -305,3 +305,49 @@ pub async fn init_l2( info!("Server shutting down!"); Ok(()) } + +pub async fn get_operator_fee_config( + sequencer_opts: &SequencerOptions, +) -> eyre::Result> { + // Fetch operator fee from the on-chain proposer contract + let operator_fee = fetch_operator_fee( + sequencer_opts.eth_opts.rpc_url.clone(), + sequencer_opts + .committer_opts + .on_chain_proposer_address + .clone(), + ) + .await?; + + // Check if operator fee vault address is provided in the config + let operator_address = sequencer_opts + .block_producer_opts + .operator_fee_vault_address; + + let operator_fee_config = if let Some(address) = operator_address { + Some(OperatorFeeConfig { + operator_fee: operator_fee, + operator_fee_vault: address, + }) + } else { + if !operator_fee.is_zero() { + error!( + "The operator fee is set on-chain, but no operator fee vault address is provided in the configuration." + ); + return Err(eyre::eyre!("Missing operator fee vault address")); + } + None + }; + Ok(operator_fee_config) +} + +pub async fn fetch_operator_fee( + rpc_urls: Vec, + on_chain_proposer_address: Option
, +) -> Result { + let contract_address = on_chain_proposer_address.ok_or(EthClientError::Custom( + "on_chain_proposer_address not set in config".to_string(), + ))?; + let eth_client = EthClient::new_with_multiple_urls(rpc_urls)?; + get_operator_fee(ð_client, contract_address).await +} diff --git a/crates/l2/Makefile b/crates/l2/Makefile index f1fd5cb719c..72578eaac98 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -94,7 +94,8 @@ deploy-l1: ## 📜 Deploys the L1 contracts --deposit-rich \ --private-keys-file-path ../../fixtures/keys/private_keys_l1.txt \ --genesis-l1-path ../../fixtures/genesis/l1-dev.json \ - --genesis-l2-path ../../fixtures/genesis/l2.json + --genesis-l2-path ../../fixtures/genesis/l2.json \ + --operator-fee 0 ## Same as deploy-l1 but deploys the SP1 verifier deploy-l1-sp1: ## 📜 Deploys the L1 contracts diff --git a/crates/l2/contracts/src/l1/OnChainProposer.sol b/crates/l2/contracts/src/l1/OnChainProposer.sol index 4a2d8ef711e..ab291f72616 100644 --- a/crates/l2/contracts/src/l1/OnChainProposer.sol +++ b/crates/l2/contracts/src/l1/OnChainProposer.sol @@ -91,6 +91,9 @@ contract OnChainProposer is /// @notice Chain ID of the network uint256 public CHAIN_ID; + /// @notice Fee in wei to be paid to the operator fee vault on each transaction + uint256 public OPERATOR_FEE; + modifier onlySequencer() { require( authorizedSequencerAddresses[msg.sender], @@ -117,7 +120,8 @@ contract OnChainProposer is bytes32 risc0Vk, bytes32 genesisStateRoot, address[] calldata sequencerAddresses, - uint256 chainId + uint256 chainId, + uint256 operatorFee ) public initializer { VALIDIUM = _validium; @@ -166,6 +170,7 @@ contract OnChainProposer is } CHAIN_ID = chainId; + OPERATOR_FEE = operatorFee; OwnableUpgradeable.__Ownable_init(owner); } diff --git a/crates/l2/sdk/src/sdk.rs b/crates/l2/sdk/src/sdk.rs index 92fe1dd0728..91472b3150a 100644 --- a/crates/l2/sdk/src/sdk.rs +++ b/crates/l2/sdk/src/sdk.rs @@ -954,6 +954,13 @@ pub async fn get_last_verified_batch( _call_u64_variable(client, b"lastVerifiedBatch()", on_chain_proposer_address).await } +pub async fn get_operator_fee( + client: &EthClient, + on_chain_proposer_address: Address, +) -> Result { + _call_u256_variable(client, b"OPERATOR_FEE()", on_chain_proposer_address).await +} + pub async fn get_sp1_vk( client: &EthClient, on_chain_proposer_address: Address, @@ -1021,6 +1028,18 @@ async fn _call_u64_variable( Ok(value) } +async fn _call_u256_variable( + client: &EthClient, + selector: &[u8], + contract_address: Address, +) -> Result { + let hex_string = _generic_call(client, selector, contract_address).await?; + + let value = U256::from_str_radix(hex_string.trim_start_matches("0x"), 16)?; + + Ok(value) +} + async fn _call_address_variable( eth_client: &EthClient, selector: &[u8], diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index fe8b9d4234a..0165fab7e2e 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -84,6 +84,7 @@ impl BlockProducer { block_time_ms, coinbase_address, fee_vault_address, + operator_fee_vault_address, elasticity_multiplier, block_gas_limit, } = config; @@ -96,6 +97,14 @@ impl BlockProducer { } } + if let Some(operator_fee_vault) = operator_fee_vault_address { + if operator_fee_vault == coinbase_address { + warn!( + "The coinbase address and operator fee vault address are the same. Coinbase balance behavior will be affected.", + ); + } + } + Self { store, blockchain, diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index b4d8f515f13..bdce6b21372 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" @@ -80,8 +80,8 @@ "0x000000000000000000000000000000000000ffff": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" }, "balance": "0x0", "nonce": "0x1" From 8d1d5a3a22194ad118f88f746b6cc45ff05ca432 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 14:11:42 -0300 Subject: [PATCH 33/88] Fix clippy --- cmd/ethrex/l2/initializers.rs | 9 +++------ fixtures/genesis/l2.json | 8 ++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index f5e0ae2f16b..d3264bf376f 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -175,7 +175,7 @@ pub async fn init_l2( let fee_config = FeeConfig { fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, - operator_fee_config: operator_fee_config, + operator_fee_config, }; let blockchain_opts = ethrex_blockchain::BlockchainOptions { @@ -312,10 +312,7 @@ pub async fn get_operator_fee_config( // Fetch operator fee from the on-chain proposer contract let operator_fee = fetch_operator_fee( sequencer_opts.eth_opts.rpc_url.clone(), - sequencer_opts - .committer_opts - .on_chain_proposer_address - .clone(), + sequencer_opts.committer_opts.on_chain_proposer_address, ) .await?; @@ -326,7 +323,7 @@ pub async fn get_operator_fee_config( let operator_fee_config = if let Some(address) = operator_address { Some(OperatorFeeConfig { - operator_fee: operator_fee, + operator_fee, operator_fee_vault: address, }) } else { diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index bdce6b21372..b4d8f515f13 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" @@ -80,8 +80,8 @@ "0x000000000000000000000000000000000000ffff": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" From 51809e41302a53aa8d91bd65d6a4d16569a09750 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 14:30:28 -0300 Subject: [PATCH 34/88] Prove that the operator_fee is the configured one --- crates/l2/contracts/src/l1/OnChainProposer.sol | 6 ++++++ crates/l2/prover/src/guest_program/src/execution.rs | 11 +++++++++++ crates/l2/prover/src/guest_program/src/output.rs | 3 +++ fixtures/genesis/l2.json | 4 ++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/l2/contracts/src/l1/OnChainProposer.sol b/crates/l2/contracts/src/l1/OnChainProposer.sol index ab291f72616..eb3eb1f75ee 100644 --- a/crates/l2/contracts/src/l1/OnChainProposer.sol +++ b/crates/l2/contracts/src/l1/OnChainProposer.sol @@ -535,6 +535,12 @@ contract OnChainProposer is return "exceeded privileged transaction inclusion deadline, can't include non-privileged transactions"; } + + uint256 operatorFee = uint256(bytes32(publicData[256:288])); + if (OPERATOR_FEE != operatorFee) { + return + "operator fee public input does not match with the configured operator fee"; + } return ""; } diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 2638413fe91..d39ed785f28 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -140,6 +140,7 @@ pub fn stateless_validation_l1( final_state_hash, last_block_hash, non_privileged_count, + operator_fee, .. } = execute_stateless(blocks, execution_witness, elasticity_multiplier, None)?; @@ -155,6 +156,7 @@ pub fn stateless_validation_l1( last_block_hash, chain_id: chain_id.into(), non_privileged_count, + operator_fee, }) } @@ -178,6 +180,7 @@ pub fn stateless_validation_l2( last_block_header, last_block_hash, non_privileged_count, + operator_fee, nodes_hashed, codes_hashed, parent_block_header, @@ -238,6 +241,7 @@ pub fn stateless_validation_l2( last_block_hash, chain_id: chain_id.into(), non_privileged_count, + operator_fee, }) } @@ -249,6 +253,7 @@ struct StatelessResult { last_block_header: BlockHeader, last_block_hash: H256, non_privileged_count: U256, + operator_fee: U256, // These fields are only used in L2 to validate state diff blobs. // We return them to avoid recomputing when comparing the initial state @@ -375,6 +380,10 @@ fn execute_stateless( parent_block_header = &block.header; } + let operator_fee = fee_config + .and_then(|fc| fc.operator_fee_config.map(|oc| oc.operator_fee)) + .unwrap_or_else(U256::zero); + // Calculate final state root hash and check let last_block = blocks .last() @@ -397,6 +406,8 @@ fn execute_stateless( last_block_header: last_block.header.clone(), last_block_hash, non_privileged_count: non_privileged_count.into(), + operator_fee, + #[cfg(feature = "l2")] nodes_hashed, #[cfg(feature = "l2")] diff --git a/crates/l2/prover/src/guest_program/src/output.rs b/crates/l2/prover/src/guest_program/src/output.rs index 611314eb9a6..9dcf7ff60a4 100644 --- a/crates/l2/prover/src/guest_program/src/output.rs +++ b/crates/l2/prover/src/guest_program/src/output.rs @@ -24,6 +24,8 @@ pub struct ProgramOutput { pub chain_id: U256, /// amount of non-privileged transactions pub non_privileged_count: U256, + /// fee that the operator will receive for each transaction included in a block + pub operator_fee: U256, } impl ProgramOutput { @@ -40,6 +42,7 @@ impl ProgramOutput { self.last_block_hash.to_fixed_bytes(), self.chain_id.to_big_endian(), self.non_privileged_count.to_big_endian(), + self.operator_fee.to_big_endian(), ] .concat() } diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index b4d8f515f13..f36abe4ea7c 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" From 84f9d7a63e157e54481dec3e6bb34208b7c81e0d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 14:48:19 -0300 Subject: [PATCH 35/88] Fix l2 hook --- crates/vm/levm/src/hooks/l2_hook.rs | 10 ++++++++-- fixtures/genesis/l2.json | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 470c4908a32..a63b79bc43b 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -23,6 +23,8 @@ impl Hook for L2Hook { fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { DefaultHook.prepare_execution(vm)?; + // Different from L1: + // Operator fee is deducted from the sender before execution deduct_operator_fee(vm, &self.fee_config.operator_fee_config)?; return Ok(()); } @@ -115,9 +117,13 @@ impl Hook for L2Hook { ) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { DefaultHook.finalize_execution(vm, ctx_result)?; - // Different from L1, the base fee is not burned + // Different from L1: + + // Base fee is not burned pay_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault)?; - pay_operator_fee(vm, self.fee_config.operator_fee_config)?; + + // Operator fee is paid to the chain operator + return pay_operator_fee(vm, self.fee_config.operator_fee_config); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index f36abe4ea7c..f07300bb35a 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" @@ -80,8 +80,8 @@ "0x000000000000000000000000000000000000ffff": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea2646970667358221220b08258f82b5f2608238001038da918cb423717142f152ef287d3502330a3c68d64736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" }, "balance": "0x0", "nonce": "0x1" From b2aa76a2491be5f708c72ecc42d788aa26eeae94 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 14:49:45 -0300 Subject: [PATCH 36/88] Style --- crates/vm/levm/src/hooks/l2_hook.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index a63b79bc43b..276c1fa7507 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -123,7 +123,9 @@ impl Hook for L2Hook { pay_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault)?; // Operator fee is paid to the chain operator - return pay_operator_fee(vm, self.fee_config.operator_fee_config); + pay_operator_fee(vm, self.fee_config.operator_fee_config)?; + + return Ok(()); } if !ctx_result.is_success() && vm.env.origin != COMMON_BRIDGE_L2_ADDRESS { From dec1042f5107b67fde33d5095e8d40f121f1b699 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 15:16:49 -0300 Subject: [PATCH 37/88] Set operator fee --- .github/workflows/main_prover.yaml | 1 + crates/l2/docker-compose.yaml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 86a99062eb3..9ad9e3a4c59 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -66,6 +66,7 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_SP1_DEPLOY_VERIFIER=true \ + ETHREX_DEPLOYER_OPERATOR_FEE=10000000000000 \ docker compose up --build contract_deployer - name: Ensure admin permissions in _work diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index ffde0084562..bec9e13cee0 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -50,6 +50,7 @@ services: - ETHREX_BRIDGE_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_SEQUENCER_REGISTRY_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=${ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS:-false} + - ETHREX_DEPLOYER_OPERATOR_FEE=${ETHREX_DEPLOYER_OPERATOR_FEE:-0} - ETHREX_L2_VALIDIUM=${ETHREX_L2_VALIDIUM:-false} - COMPILE_CONTRACTS=true depends_on: @@ -88,7 +89,7 @@ services: entrypoint: - /bin/bash - -c - - export $(xargs < /env/.env); ./ethrex l2 "$0" "$@" + - export $(xargs < /env/.env); ./ethrex l2 "$0" "$@" # ETHREX_WATCHER_BRIDGE_ADDRESS and ETHREX_COMMITTER_ON_CHAIN_PROPOSER_ADDRESS are set in the .env file by the contract_deployer service. command: > --network /genesis/l2.json From ff5af2ba43341fd8eed5c150486f31b1276823c1 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 15:22:45 -0300 Subject: [PATCH 38/88] Update cargo lock --- .../src/guest_program/src/sp1/Cargo.lock | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/crates/l2/prover/src/guest_program/src/sp1/Cargo.lock b/crates/l2/prover/src/guest_program/src/sp1/Cargo.lock index e00c77e2d96..5f111080930 100644 --- a/crates/l2/prover/src/guest_program/src/sp1/Cargo.lock +++ b/crates/l2/prover/src/guest_program/src/sp1/Cargo.lock @@ -621,28 +621,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -662,15 +640,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1092,24 +1061,15 @@ dependencies = [ "tracing", ] -[[package]] -name = "ethrex-threadpool" -version = "0.1.0" -dependencies = [ - "crossbeam", -] - [[package]] name = "ethrex-trie" version = "0.1.0" dependencies = [ "anyhow", "bytes", - "crossbeam", "digest", "ethereum-types", "ethrex-rlp", - "ethrex-threadpool", "hex", "lazy_static", "serde", From 1e94dd6858c81dbf5115cb67b4157c597b94e12b Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 15:28:58 -0300 Subject: [PATCH 39/88] Set fee vault address --- .github/workflows/main_prover.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 9ad9e3a4c59..d210e276549 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -81,6 +81,7 @@ jobs: ETHREX_COMMITTER_COMMIT_TIME=30000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ docker compose up --build --detach --no-deps ethrex_l2 - name: Copy env to host From 1db8ba792626f66833a542df5ef4fa6749a794a0 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 19:37:17 -0300 Subject: [PATCH 40/88] Add operator fee to integration tests --- crates/l2/Makefile | 3 +- crates/l2/tests/tests.rs | 212 ++++++++++++++++++++++++++++++--------- 2 files changed, 169 insertions(+), 46 deletions(-) diff --git a/crates/l2/Makefile b/crates/l2/Makefile index 0a02b737815..a0af44e7acd 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -95,7 +95,7 @@ deploy-l1: ## 📜 Deploys the L1 contracts --private-keys-file-path ../../fixtures/keys/private_keys_l1.txt \ --genesis-l1-path ../../fixtures/genesis/l1-dev.json \ --genesis-l2-path ../../fixtures/genesis/l2.json \ - --operator-fee 0 + --operator-fee 10000000000000 \ ## Same as deploy-l1 but deploys the SP1 verifier deploy-l1-sp1: ## 📜 Deploys the L1 contracts @@ -134,6 +134,7 @@ init-l2: ## 🚀 Initializes an L2 Lambda ethrex Client --eth.rpc-url ${L1_RPC_URL} \ --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d \ --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + --block-producer.operator-fee-vault-address 0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 \ --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d \ --proof-coordinator.addr ${PROOF_COORDINATOR_ADDRESS} diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index eee3b29dc08..a4dc3905ec5 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -19,7 +19,8 @@ use ethrex_l2_sdk::{ wait_for_transaction_receipt, }; use ethrex_l2_sdk::{ - build_generic_tx, get_last_verified_batch, send_generic_transaction, wait_for_message_proof, + build_generic_tx, get_last_verified_batch, get_operator_fee, send_generic_transaction, + wait_for_message_proof, }; use ethrex_rpc::{ clients::eth::{EthClient, Overrides}, @@ -34,7 +35,6 @@ use std::ops::{Add, AddAssign}; use std::{ fs::{File, read_to_string}, io::{BufRead, BufReader}, - ops::Mul, path::{Path, PathBuf}, str::FromStr, time::Duration, @@ -87,7 +87,11 @@ const DEFAULT_PROPOSER_FEE_VAULT_ADDRESS: Address = H160([ 0x0f, 0xe6, 0x91, 0x27, ]); -const L2_GAS_COST_MAX_DELTA: U256 = U256([100_000_000_000_000, 0, 0, 0]); +// 0xd5d2a85751b6F158e5b9B8cD509206A865672362 +const DEFAULT_OPERATOR_FEE_VAULT_ADDRESS: Address = H160([ + 0xd5, 0xd2, 0xa8, 0x57, 0x51, 0xb6, 0xf1, 0x58, 0xe5, 0xb9, 0xb8, 0xcd, 0x50, 0x92, 0x06, 0xa8, + 0x65, 0x67, 0x23, 0x62, +]); const DEFAULT_RICH_KEYS_FILE_PATH: &str = "../../fixtures/keys/private_keys_l1.txt"; const DEFAULT_TEST_KEYS_FILE_PATH: &str = "../../fixtures/keys/private_keys_tests.txt"; @@ -113,15 +117,20 @@ async fn l2_integration_test() -> Result<(), Box> { let fee_vault_balance_before_tests = l2_client .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let operator_fee_vault_balance_before_tests = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; let mut set = JoinSet::new(); - set.spawn(test_upgrade(l1_client.clone(), l2_client.clone())); + // set.spawn(test_upgrade(l1_client.clone(), l2_client.clone())); set.spawn(test_transfer( l2_client.clone(), private_keys.pop().unwrap(), private_keys.pop().unwrap(), + operator_fee, )); set.spawn(test_privileged_tx_with_contract_call( @@ -188,10 +197,12 @@ async fn l2_integration_test() -> Result<(), Box> { let mut acc_priority_fees = U256::zero(); let mut acc_base_fees = U256::zero(); + let mut acc_operator_fee = U256::zero(); while let Some(res) = set.join_next().await { let fees_details = res??; acc_priority_fees += fees_details.priority_fees; - acc_base_fees += fees_details.total_fees - fees_details.priority_fees; + acc_base_fees += fees_details.base_fees; + acc_operator_fee += fees_details.operator_fee; } let coinbase_balance_after_tests = l2_client @@ -202,7 +213,11 @@ async fn l2_integration_test() -> Result<(), Box> { .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - println!("Checking coinbase and fee vault balances"); + let operator_fee_vault_balance_after_tests = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + println!("Checking coinbase, base and operator fee vault balances"); assert_eq!( coinbase_balance_after_tests, @@ -218,6 +233,12 @@ async fn l2_integration_test() -> Result<(), Box> { ); } + assert_eq!( + operator_fee_vault_balance_after_tests, + operator_fee_vault_balance_before_tests + acc_operator_fee, + "Operator fee vault is not correct after tests" + ); + // Not thread-safe (coinbase and bridge balance checks) test_n_withdraws( &l1_client, @@ -245,7 +266,7 @@ async fn l2_integration_test() -> Result<(), Box> { async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result { println!("Testing upgrade"); let bridge_owner_private_key = bridge_owner_private_key(); - + let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; println!("test_upgrade: Downloading openzeppelin contracts"); let contracts_path = Path::new("contracts"); @@ -273,6 +294,7 @@ async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result Result { let token_amount: U256 = U256::from(100); + let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; let rich_wallet_signer: Signer = LocalSigner::new(rich_wallet_private_key).into(); let rich_address = rich_wallet_signer.address(); @@ -532,6 +559,7 @@ async fn test_erc20_roundtrip( &init_code_l2, &rich_wallet_private_key, "test_erc20_roundtrip", + operator_fee, ) .await?; @@ -599,7 +627,7 @@ async fn test_erc20_roundtrip( ) .await?; - let approve_fees = get_fees_details_l2(&approve_receipt, &l2_client).await; + let approve_fees = get_fees_details_l2(&approve_receipt, &l2_client, operator_fee).await; let withdraw_receipt = test_send( &l2_client, @@ -616,7 +644,7 @@ async fn test_erc20_roundtrip( ) .await?; - let withdraw_fees = get_fees_details_l2(&withdraw_receipt, &l2_client).await; + let withdraw_fees = get_fees_details_l2(&withdraw_receipt, &l2_client, operator_fee).await; let withdrawal_tx_hash = withdraw_receipt.tx_info.transaction_hash; assert_eq!( @@ -991,7 +1019,7 @@ async fn test_send( } /// Test depositing ETH from L1 to L2 -/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and coinbase on L2. +/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and coinbase, fee vault and operator vault on L2 /// 2. Perform deposit from L1 to L2 /// 3. Check final balances. async fn test_deposit( @@ -1028,6 +1056,14 @@ async fn test_deposit( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let fee_vault_balance_before_deposit = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + let operator_vault_balance_before_deposit = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + println!("test_deposit: Depositing funds from L1 to L2"); let deposit_tx_hash = ethrex_l2_sdk::deposit_through_transfer( @@ -1074,7 +1110,8 @@ async fn test_deposit( println!("test_deposit: Waiting for L2 deposit tx receipt"); - let _ = wait_for_l2_deposit_receipt(&deposit_tx_receipt, l1_client, l2_client).await?; + let l2_receipt = wait_for_l2_deposit_receipt(&deposit_tx_receipt, l1_client, l2_client).await?; + assert!(l2_receipt.receipt.status, "L2 deposit transaction failed."); let deposit_recipient_l2_balance_after_deposit = l2_client .get_balance(rich_wallet_address, BlockIdentifier::Tag(BlockTag::Latest)) @@ -1090,11 +1127,29 @@ async fn test_deposit( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let fee_vault_balance_after_deposit = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + let operator_fee_vault_balance_after_deposit = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + assert_eq!( coinbase_balance_after_deposit, coinbase_balance_before_deposit, "Coinbase balance should not change after deposit" ); + assert_eq!( + fee_vault_balance_after_deposit, fee_vault_balance_before_deposit, + "Fee vault balance should not change after deposit" + ); + + assert_eq!( + operator_fee_vault_balance_after_deposit, operator_vault_balance_before_deposit, + "Operator vault balance should not change after deposit" + ); + Ok(()) } @@ -1129,6 +1184,7 @@ async fn test_transfer( l2_client: EthClient, transferer_private_key: SecretKey, returnerer_private_key: SecretKey, + operator_fee: U256, ) -> Result { println!("test_transfer: Transferring funds on L2"); let transferer_address = get_address_from_secret_key(&transferer_private_key).unwrap(); @@ -1143,8 +1199,12 @@ async fn test_transfer( &transferer_private_key, returner_address, transfer_value(), + operator_fee, + "test_transfer", ) .await?; + + println!("test_transfer: Calculating return amount for return transfer"); // Only return 99% of the transfer, other amount is for fees let return_amount = (transfer_value() * 99) / 100; @@ -1157,6 +1217,8 @@ async fn test_transfer( &returnerer_private_key, transferer_address, return_amount, + operator_fee, + "test_transfer", ) .await?; @@ -1329,6 +1391,8 @@ async fn perform_transfer( transferer_private_key: &SecretKey, transfer_recipient_address: Address, transfer_value: U256, + operator_fee: U256, + test: &str, ) -> Result { let transferer_address = get_address_from_secret_key(transferer_private_key).unwrap(); @@ -1337,7 +1401,7 @@ async fn perform_transfer( .await?; assert!( - transferer_initial_l2_balance >= transfer_value, + transferer_initial_l2_balance >= transfer_value + operator_fee, "L2 transferer doesn't have enough balance to transfer" ); @@ -1365,19 +1429,20 @@ async fn perform_transfer( "Transfer transaction failed" ); - println!("Checking balances on L2 after transfer"); + let transfer_fees = get_fees_details_l2(&transfer_tx_receipt, l2_client, operator_fee).await; + let total_fees = + transfer_fees.base_fees + transfer_fees.priority_fees + transfer_fees.operator_fee; + + println!("{test}: Checking balances on L2 after transfer"); let transferer_l2_balance_after_transfer = l2_client .get_balance(transferer_address, BlockIdentifier::Tag(BlockTag::Latest)) .await?; - assert!( - (transferer_initial_l2_balance - transfer_value) - .abs_diff(transferer_l2_balance_after_transfer) - < L2_GAS_COST_MAX_DELTA, - "L2 transferer balance didn't decrease as expected after transfer. Gas costs were {}/{L2_GAS_COST_MAX_DELTA}", - (transferer_initial_l2_balance - transfer_value) - .abs_diff(transferer_l2_balance_after_transfer) + assert_eq!( + transferer_initial_l2_balance - transfer_value - total_fees, + transferer_l2_balance_after_transfer, + "{test}: L2 transferer balance didn't decrease as expected after transfer. Gas costs were {total_fees}", ); let transfer_recipient_l2_balance_after_transfer = l2_client @@ -1387,13 +1452,14 @@ async fn perform_transfer( ) .await?; + println!("{test}: Checking recipient balance on L2 after transfer"); + assert_eq!( transfer_recipient_l2_balance_after_transfer, transfer_recipient_initial_balance + transfer_value, "L2 transfer recipient balance didn't increase as expected after transfer" ); - - let transfer_fees = get_fees_details_l2(&transfer_tx_receipt, l2_client).await; + println!("{test}: Transfer successful"); Ok(transfer_fees) } @@ -1404,6 +1470,7 @@ async fn test_n_withdraws( withdrawer_private_key: &SecretKey, n: u64, ) -> Result<(), Box> { + let operator_fee = get_operator_fee(l1_client, on_chain_proposer_address()).await?; println!("test_n_withdraws: Withdrawing funds from L2 to L1"); let withdrawer_address = get_address_from_secret_key(withdrawer_private_key)?; let withdraw_value = std::env::var("INTEGRATION_TEST_WITHDRAW_VALUE") @@ -1438,6 +1505,14 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let fee_vault_balance_before_withdrawal = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + let operator_fee_vault_balance_before_withdrawal = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + println!("test_n_withdraws: Withdrawing funds from L2 to L1"); let mut withdraw_txs = vec![]; @@ -1476,14 +1551,15 @@ async fn test_n_withdraws( .await?; // Compute actual total L2 gas paid by the withdrawer from receipts - let mut total_withdraw_fees_l2 = U256::zero(); + let mut total_withdraw_fees_l2 = FeesDetails::default(); for receipt in &receipts { - total_withdraw_fees_l2 += get_fees_details_l2(receipt, l2_client).await.total_fees; + total_withdraw_fees_l2 += get_fees_details_l2(receipt, l2_client, operator_fee).await; } // Now assert exact balance movement on L2: value + gas - let expected_l2_after = - withdrawer_l2_balance_before_withdrawal - (withdraw_value * n) - total_withdraw_fees_l2; + let expected_l2_after = withdrawer_l2_balance_before_withdrawal + - (withdraw_value * n) + - total_withdraw_fees_l2.total(); assert_eq!( withdrawer_l2_balance_after_withdrawal, expected_l2_after, @@ -1503,14 +1579,28 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let mut priority_fees = U256::zero(); - for receipt in receipts { - priority_fees += get_fees_details_l2(&receipt, l2_client).await.priority_fees; - } + let fee_vault_balance_after_withdrawal = l2_client + .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + let operator_fee_vault_balance_after_withdrawal = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; assert_eq!( coinbase_balance_after_withdrawal, - coinbase_balance_before_withdrawal + priority_fees, + coinbase_balance_before_withdrawal + total_withdraw_fees_l2.priority_fees, + "Coinbase balance didn't increase as expected after withdrawal" + ); + + assert_eq!( + fee_vault_balance_after_withdrawal, + fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.base_fees, + "Coinbase balance didn't increase as expected after withdrawal" + ); + + assert_eq!( + operator_fee_vault_balance_after_withdrawal, + operator_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.operator_fee, "Coinbase balance didn't increase as expected after withdrawal" ); @@ -1608,10 +1698,17 @@ async fn test_total_eth_l2( println!("Fee vault balance: {fee_vault_balance}"); - let total_eth_on_l2 = rich_accounts_balance + coinbase_balance + fee_vault_balance; + let operator_fee_vault_balance = l2_client + .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + .await?; + + println!("Operator fee vault balance: {operator_fee_vault_balance}"); + + let total_eth_on_l2 = + rich_accounts_balance + coinbase_balance + fee_vault_balance + operator_fee_vault_balance; println!( - "Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} + {fee_vault_balance} = {total_eth_on_l2}" + "Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} + {fee_vault_balance} + {operator_fee_vault_balance} = {total_eth_on_l2}" ); println!("Checking locked ETH on CommonBridge"); @@ -1646,6 +1743,7 @@ async fn test_deploy( init_code: &[u8], deployer_private_key: &SecretKey, test_name: &str, + operator_fee: U256, ) -> Result<(Address, FeesDetails)> { println!("{test_name}: Deploying contract on L2"); @@ -1671,15 +1769,17 @@ async fn test_deploy( "{test_name}: Deploy transaction failed" ); - let deploy_fees = get_fees_details_l2(&deploy_tx_receipt, l2_client).await; + let deploy_fees = get_fees_details_l2(&deploy_tx_receipt, l2_client, operator_fee).await; let deployer_balance_after_deploy = l2_client .get_balance(deployer.address(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; + let total_fees = deploy_fees.base_fees + deploy_fees.priority_fees + deploy_fees.operator_fee; + assert_eq!( deployer_balance_after_deploy, - deployer_balance_before_deploy - deploy_fees.total_fees, + deployer_balance_before_deploy - total_fees, "{test_name}: Deployer L2 balance didn't decrease as expected after deploy" ); @@ -1806,8 +1906,15 @@ fn bridge_owner_private_key() -> SecretKey { #[derive(Debug, Default)] struct FeesDetails { - total_fees: U256, + base_fees: U256, priority_fees: U256, + operator_fee: U256, +} + +impl FeesDetails { + fn total(&self) -> U256 { + self.base_fees + self.priority_fees + self.operator_fee + } } impl Add for FeesDetails { @@ -1815,24 +1922,30 @@ impl Add for FeesDetails { fn add(self, other: Self) -> Self { Self { - total_fees: self.total_fees + other.total_fees, + base_fees: self.base_fees + other.base_fees, priority_fees: self.priority_fees + other.priority_fees, + operator_fee: self.operator_fee + other.operator_fee, } } } impl AddAssign for FeesDetails { fn add_assign(&mut self, other: Self) { - self.total_fees += other.total_fees; + self.base_fees += other.base_fees; self.priority_fees += other.priority_fees; + self.operator_fee += other.operator_fee; } } -async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> FeesDetails { - let total_fees: U256 = - (tx_receipt.tx_info.gas_used * tx_receipt.tx_info.effective_gas_price).into(); - +async fn get_fees_details_l2( + tx_receipt: &RpcReceipt, + l2_client: &EthClient, + operator_fee: U256, +) -> FeesDetails { + let gas_used = tx_receipt.tx_info.gas_used; let effective_gas_price = tx_receipt.tx_info.effective_gas_price; + let total_execution_fees: U256 = (effective_gas_price * gas_used).into(); + let base_fee_per_gas = l2_client .get_block_by_number( BlockIdentifier::Number(tx_receipt.block_info.block_number), @@ -1844,13 +1957,16 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> .base_fee_per_gas .unwrap(); - let max_priority_fee_per_gas_transfer: U256 = (effective_gas_price - base_fee_per_gas).into(); + // Base = base_fee * gas_used + let base_fees: U256 = (base_fee_per_gas * gas_used).into(); - let priority_fees = max_priority_fee_per_gas_transfer.mul(tx_receipt.tx_info.gas_used); + // Priority = (effective - base_fee) * gas_used + let priority_fees: U256 = total_execution_fees - base_fees; FeesDetails { - total_fees, + base_fees, priority_fees, + operator_fee, } } @@ -1876,6 +1992,12 @@ fn fee_vault() -> Address { .unwrap_or(DEFAULT_PROPOSER_FEE_VAULT_ADDRESS) } +fn operator_fee_vault() -> Address { + std::env::var("INTEGRATION_TEST_OPERATOR_FEE_VAULT_ADDRESS") + .map(|address| address.parse().expect("Invalid proposer coinbase address")) + .unwrap_or(DEFAULT_OPERATOR_FEE_VAULT_ADDRESS) +} + async fn wait_for_l2_deposit_receipt( rpc_receipt: &RpcReceipt, l1_client: &EthClient, From de54296c8d8c29fe16e328ed12275edd1e6f1675 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 19:43:21 -0300 Subject: [PATCH 41/88] Fix env var --- .github/workflows/main_prover.yaml | 2 +- crates/l2/docker-compose.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index d210e276549..7f826620025 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -66,7 +66,7 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_SP1_DEPLOY_VERIFIER=true \ - ETHREX_DEPLOYER_OPERATOR_FEE=10000000000000 \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=10000000000000 \ docker compose up --build contract_deployer - name: Ensure admin permissions in _work diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index bec9e13cee0..3b02180ecd0 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -50,7 +50,7 @@ services: - ETHREX_BRIDGE_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_SEQUENCER_REGISTRY_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=${ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS:-false} - - ETHREX_DEPLOYER_OPERATOR_FEE=${ETHREX_DEPLOYER_OPERATOR_FEE:-0} + - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=${ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE:-10000000000000} - ETHREX_L2_VALIDIUM=${ETHREX_L2_VALIDIUM:-false} - COMPILE_CONTRACTS=true depends_on: From 6af8e5d53ad1a31c3014aab3945d10b40667f4b4 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 19:50:45 -0300 Subject: [PATCH 42/88] Pass operator fee address --- .github/workflows/main_prover.yaml | 1 - .github/workflows/pr-main_l2.yaml | 2 ++ crates/l2/docker-compose.yaml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 7f826620025..b93e1a28158 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -66,7 +66,6 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_SP1_DEPLOY_VERIFIER=true \ - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=10000000000000 \ docker compose up --build contract_deployer - name: Ensure admin permissions in _work diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 3f52a8ae9c3..f97493ea669 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -170,6 +170,7 @@ jobs: ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 - name: Run test @@ -356,6 +357,7 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ ETHREX_PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ docker compose -f docker-compose.yaml -f docker-compose-l2-tdx.yaml up --detach --no-deps ethrex_l2 diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index 3b02180ecd0..6fa0eaf1f11 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -80,6 +80,7 @@ services: - ETHREX_WATCHER_BLOCK_DELAY=${ETHREX_WATCHER_BLOCK_DELAY:-0} - ETHREX_BASED=${ETHREX_BASED:-false} - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS + - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS - ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=${ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY:-0x0000000000000000000000000000000000000000} - ETHREX_COMMITTER_COMMIT_TIME=${ETHREX_COMMITTER_COMMIT_TIME:-60000} - ETHREX_WATCHER_WATCH_INTERVAL=${ETHREX_WATCHER_WATCH_INTERVAL:-12000} From 62e714806bcee545dac2eebdb7df50ef90449dce Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 2 Oct 2025 20:04:23 -0300 Subject: [PATCH 43/88] Add test upgrade --- crates/l2/tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index a4dc3905ec5..b4c8327f1b7 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -124,7 +124,7 @@ async fn l2_integration_test() -> Result<(), Box> { let mut set = JoinSet::new(); - // set.spawn(test_upgrade(l1_client.clone(), l2_client.clone())); + set.spawn(test_upgrade(l1_client.clone(), l2_client.clone())); set.spawn(test_transfer( l2_client.clone(), From 4b5dc0a2fd3cf9ef1dd8927381c50d48a1e9595b Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 11:55:38 -0300 Subject: [PATCH 44/88] Fix dockers --- .github/workflows/main_prover.yaml | 1 + .github/workflows/pr-main_l2.yaml | 2 ++ crates/l2/Makefile | 5 +++-- crates/l2/docker-compose.yaml | 2 +- crates/l2/tests/tests.rs | 6 +++++- crates/vm/backends/levm/mod.rs | 14 +++++++++----- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index b93e1a28158..f348c825cfa 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -66,6 +66,7 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_SP1_DEPLOY_VERIFIER=true \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 \ docker compose up --build contract_deployer - name: Ensure admin permissions in _work diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index f97493ea669..2d59b0a9069 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -154,6 +154,7 @@ jobs: ETHREX_DEPLOYER_SP1_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_RISC0_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_L2_VALIDIUM=${{ matrix.validium }} \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 \ docker compose up contract_deployer - name: Copy env to host @@ -347,6 +348,7 @@ jobs: ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_TDX_DEPLOY_VERIFIER=true \ ETHREX_TDX_DEV_MODE=true \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 \ make deploy-l1 - name: Start Sequencer diff --git a/crates/l2/Makefile b/crates/l2/Makefile index a0af44e7acd..213da595c13 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -45,6 +45,7 @@ L1_AUTH_PORT=8551 L1_RPC_ADDRESS=0.0.0.0 L2_RPC_ADDRESS=0.0.0.0 PROOF_COORDINATOR_ADDRESS?=127.0.0.1 +ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE?=0x3B9ACA00 \ # Matches the ports used by the blockchain/metrics dir L2_PROMETHEUS_METRICS_PORT = 3702 @@ -95,7 +96,7 @@ deploy-l1: ## 📜 Deploys the L1 contracts --private-keys-file-path ../../fixtures/keys/private_keys_l1.txt \ --genesis-l1-path ../../fixtures/genesis/l1-dev.json \ --genesis-l2-path ../../fixtures/genesis/l2.json \ - --operator-fee 10000000000000 \ + --operator-fee ${ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE} ## Same as deploy-l1 but deploys the SP1 verifier deploy-l1-sp1: ## 📜 Deploys the L1 contracts @@ -183,7 +184,7 @@ build-prover: ../../target/release/ethrex: $(PROVER_SRC_FILES) @if [ -z "$$PROVER" ]; then \ echo "Warn: ProverType (PROVER) is missing. Building only with exec mode."; \ - echo "Please provide it as an argument:"; \ + echo "You can provide it as an argument:"; \ echo "make init-prover PROVER= G="; \ echo "The prover can also be run with GPU (G)"; \ fi; \ diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index 6fa0eaf1f11..0f00961f63a 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -50,7 +50,7 @@ services: - ETHREX_BRIDGE_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_SEQUENCER_REGISTRY_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=${ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS:-false} - - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=${ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE:-10000000000000} + - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE - ETHREX_L2_VALIDIUM=${ETHREX_L2_VALIDIUM:-false} - COMPILE_CONTRACTS=true depends_on: diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index b4c8327f1b7..aa903fe6414 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -604,9 +604,13 @@ async fn test_erc20_roundtrip( assert!(res.receipt.status); println!("test_erc20_roundtrip: Waiting for deposit transaction receipt on L2"); - wait_for_l2_deposit_receipt(&res, &l1_client, &l2_client) + + let l2_receipt = wait_for_l2_deposit_receipt(&res, &l1_client, &l2_client) .await .unwrap(); + + assert!(l2_receipt.receipt.status); + let remaining_l1_balance = test_balance_of(&l1_client, token_l1, rich_address).await; let l2_balance = test_balance_of(&l2_client, token_l2, rich_address).await; assert_eq!(initial_balance - remaining_l1_balance, token_amount); diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 13c2b48a9c3..45915371981 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -147,13 +147,13 @@ impl LEVM { // The block header for the current block. block_header: &BlockHeader, db: &mut GeneralizedDatabase, - vm_type: VMType, + mut vm_type: VMType, ) -> Result { let mut env = env_from_generic(tx, block_header, db)?; env.block_gas_limit = i64::MAX as u64; // disable block gas limit - adjust_disabled_base_fee(&mut env); + adjust_disabled_base_fee(&mut env, &mut vm_type); let mut vm = vm_from_generic(tx, env, db, vm_type)?; @@ -297,11 +297,11 @@ impl LEVM { mut tx: GenericTransaction, header: &BlockHeader, db: &mut GeneralizedDatabase, - vm_type: VMType, + mut vm_type: VMType, ) -> Result<(ExecutionResult, AccessList), VMError> { let mut env = env_from_generic(&tx, header, db)?; - adjust_disabled_base_fee(&mut env); + adjust_disabled_base_fee(&mut env, &mut vm_type); let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; @@ -466,9 +466,13 @@ pub fn calculate_gas_price(tx: &GenericTransaction, basefee: u64) -> U256 { /// When basefee tracking is disabled (ie. env.disable_base_fee = true; env.disable_block_gas_limit = true;) /// and no gas prices were specified, lower the basefee to 0 to avoid breaking EVM invariants (basefee < feecap) /// See https://github.com/ethereum/go-ethereum/blob/00294e9d28151122e955c7db4344f06724295ec5/core/vm/evm.go#L137 -fn adjust_disabled_base_fee(env: &mut Environment) { +fn adjust_disabled_base_fee(env: &mut Environment, vm_type: &mut VMType) { if env.gas_price == U256::zero() { env.base_fee_per_gas = U256::zero(); + if let VMType::L2(fee_config) = vm_type { + // Don't deduct operator fee if no gas price is set + fee_config.operator_fee_config = None; + } } if env .tx_max_fee_per_blob_gas From bd063f6417b610095b7986b224fbe46b4022fd9a Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 12:17:45 -0300 Subject: [PATCH 45/88] Fix public input length --- .github/workflows/pr-main_l2.yaml | 1 + crates/l2/contracts/src/l1/OnChainProposer.sol | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 2d59b0a9069..20b60e274e5 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -417,6 +417,7 @@ jobs: ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_SP1_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_RISC0_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x0 \ COMPILE_CONTRACTS=true \ docker compose up contract_deployer diff --git a/crates/l2/contracts/src/l1/OnChainProposer.sol b/crates/l2/contracts/src/l1/OnChainProposer.sol index eb3eb1f75ee..763c3ffea8a 100644 --- a/crates/l2/contracts/src/l1/OnChainProposer.sol +++ b/crates/l2/contracts/src/l1/OnChainProposer.sol @@ -476,7 +476,7 @@ contract OnChainProposer is uint256 batchNumber, bytes calldata publicData ) internal view returns (string memory) { - if (publicData.length != 256) { + if (publicData.length != 288) { return "invalid public data length"; } bytes32 initialStateRoot = bytes32(publicData[0:32]); From 0075f72c3f70523b3f63ea725102d75e4d06e641 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 14:13:49 -0300 Subject: [PATCH 46/88] Update docs --- docs/SUMMARY.md | 1 + docs/getting-started/quickstart-l2.md | 2 +- docs/l2/configuration.md | 21 -------- docs/l2/fundamentals/transaction_fees.md | 32 +++++++++++ docs/l2/running.md | 69 ------------------------ fixtures/genesis/l2.json | 4 +- 6 files changed, 36 insertions(+), 93 deletions(-) delete mode 100644 docs/l2/configuration.md create mode 100644 docs/l2/fundamentals/transaction_fees.md delete mode 100644 docs/l2/running.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index c462dbbdea5..a7a0441aea9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -54,6 +54,7 @@ - [CommonBridge]() - [L1MessageSender]() - [Based sequencing](./l2/fundamentals/based.md) + - [Fees](./l2/fundamentals/transaction_fees.md) # Ethrex for developers diff --git a/docs/getting-started/quickstart-l2.md b/docs/getting-started/quickstart-l2.md index 2d4d67f03cd..231a43bfa88 100644 --- a/docs/getting-started/quickstart-l2.md +++ b/docs/getting-started/quickstart-l2.md @@ -17,4 +17,4 @@ This will start a local L1 and L2 network. A JSON-RPC server compatible with Eth For more details and configuration options, see: - [Installation](./installation) -- [Advanced options and more details](../l2/introduction.md) +- [Advanced options and more details](../l2/deploy.md) diff --git a/docs/l2/configuration.md b/docs/l2/configuration.md deleted file mode 100644 index fd6779cbf79..00000000000 --- a/docs/l2/configuration.md +++ /dev/null @@ -1,21 +0,0 @@ -# Configuration - -This page covers the advanced configuration options for running an L2 node with ethrex. - -## Base fee Configuration - -You can configure the base fee behavior in ethrex. - -Set a fee vault address with: - -```sh -ethrex l2 --block-producer.fee-vault-address -``` - -When configured, the sequencer redirects collected base fees to the specified address instead of burning them. The sequencer may designate any address as the fee vault, including the coinbase address. - -> [!CAUTION] -> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. - -> [!CAUTION] -> Even though it may technically be possible to change the fee vault address or switch between burning and not burning fees from one batch to another, the feature was not designed to allow such behavior once the chain has been launched. diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md new file mode 100644 index 00000000000..2a4d1e8d061 --- /dev/null +++ b/docs/l2/fundamentals/transaction_fees.md @@ -0,0 +1,32 @@ +# Transaction Fees + +This page describes the different types of transaction fees that the Ethrex L2 rollup can charge and how they can be configured. + +> [!NOTE] +> Privileged transactions are exempt from all fees. + +## Execution Fees + +Execution fees are divided into two components: **base fee** and **priority fee**. + +### Base Fee + + +The base fee follows the same rules as the Ethereum L1 base fee. It adjusts dynamically depending on network congestion to ensure stable transaction pricing. +By default, base fees are burned. However a sequencer can configure a `fee vault` address to receive the collected base fees instead of burning them. + +```sh +ethrex l2 --block-producer.fee-vault-address +``` + +> [!CAUTION] +> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. + +### Priority Fee + +The priority fee works exactly the same way as on Ethereum L1. +It is an additional tip paid by the transaction sender to incentivize the sequencer to prioritize the inclusion of their transaction. The priority fee is always forwarded directly to the sequencer’s coinbase address. + +## Operator Fees + +## L1 Fees diff --git a/docs/l2/running.md b/docs/l2/running.md deleted file mode 100644 index ecdb6fa2284..00000000000 --- a/docs/l2/running.md +++ /dev/null @@ -1,69 +0,0 @@ -# Deploying a node - -## Prerequisites - -This guide assumes that you've deployed the contracts for the rollup to your chosen L1 network, and that you have a valid `genesis.json`. -The contract's solidity code can be downloaded from the [GitHub releases](https://github.com/lambdaclass/ethrex/releases) -or by running: - -``` -curl -L https://github.com/lambdaclass/ethrex/releases/latest/download/ethrex-contracts.tar.gz -``` - -## Starting the sequencer - -First we need to set some environment variables. - -#### Run the sequencer - -```sh - ethrex l2 \ - --network \ - --on_chain_proposer_address
\ - --bridge_address
\ - --rpc_url \ - --committer_l1_private_key \ - --proof_coordinator_l1_private_key \ - --block-producer.coinbase-address \ -``` - -For further configuration take a look at the [CLI document](../CLI.md#ethrex-l2) - -This will start an ethrex l2 sequencer with the RPC server listening at `http://localhost:1729` and the proof coordinator server listening at `http://localhost:3900` - - -## Starting a prover server - -```sh -ethrex l2 prover --proof-coordinators http://localhost:3900 -``` - -For further configuration take a look at the [CLI document](../CLI.md#ethrex-l2-prover) - -## Checking that everything is running - -After starting the sequencer and prover, you can verify that your L2 node is running correctly: - -- **Check the sequencer RPC:** - - You can request the latest block number: - - ```sh - curl http://localhost:1729 \ - -H 'content-type: application/json' \ - -d '{"jsonrpc":"2.0","method":"eth_blockNumber","id":"1","params":[]}' - ``` - - The answer should be like this, and advance every 5 seconds: - - ``` - {"id":"1","jsonrpc":"2.0","result":"0x1"} - ``` - -- **Check logs:** - - Review the terminal output or log files for any errors or warnings. - -If all endpoints respond and there are no errors in the logs, your L2 node is running successfully. - -> [!NOTE] -> For more information about the configuration options, see the [Configuration](./configuration.md) section. \ No newline at end of file diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 826087e0e5c..dc827b681f4 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea264697066735822122010851476c4e814cf2c1b0c475d8e57975f506c602b00f35324aa101478f25b5b64736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" From 4b536c2e7da538ec3b0a1852e15a05a3038d8f9c Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 14:14:43 -0300 Subject: [PATCH 47/88] Remove extra line --- docs/l2/fundamentals/transaction_fees.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md index 2a4d1e8d061..d50a9e3a169 100644 --- a/docs/l2/fundamentals/transaction_fees.md +++ b/docs/l2/fundamentals/transaction_fees.md @@ -11,7 +11,6 @@ Execution fees are divided into two components: **base fee** and **priority fee* ### Base Fee - The base fee follows the same rules as the Ethereum L1 base fee. It adjusts dynamically depending on network congestion to ensure stable transaction pricing. By default, base fees are burned. However a sequencer can configure a `fee vault` address to receive the collected base fees instead of burning them. From 39109f6ddfc1b3f5f628ed4d27262d7466a0e225 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 14:17:14 -0300 Subject: [PATCH 48/88] Update summary --- docs/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index a7a0441aea9..7dfcbf30814 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -54,7 +54,7 @@ - [CommonBridge]() - [L1MessageSender]() - [Based sequencing](./l2/fundamentals/based.md) - - [Fees](./l2/fundamentals/transaction_fees.md) + - [Transaction fees](./l2/fundamentals/transaction_fees.md) # Ethrex for developers From ddb9a9517efef1e47e9b8f0ff71874a102ccabd6 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 14:52:51 -0300 Subject: [PATCH 49/88] Restore replay --- cmd/ethrex_replay/src/cache.rs | 11 ++++-- cmd/ethrex_replay/src/cli.rs | 59 +++++--------------------------- cmd/ethrex_replay/src/fetcher.rs | 46 ++++--------------------- cmd/ethrex_replay/src/run.rs | 10 ++---- 4 files changed, 24 insertions(+), 102 deletions(-) diff --git a/cmd/ethrex_replay/src/cache.rs b/cmd/ethrex_replay/src/cache.rs index bcf19626d11..19d6fcd5ea5 100644 --- a/cmd/ethrex_replay/src/cache.rs +++ b/cmd/ethrex_replay/src/cache.rs @@ -1,7 +1,6 @@ use ethrex_common::types::Block; use ethrex_common::types::ChainConfig; use ethrex_common::types::blobs_bundle; -use ethrex_common::types::fee_config::FeeConfig; use ethrex_config::networks::Network; use ethrex_rpc::debug::execution_witness::RpcExecutionWitness; use eyre::OptionExt; @@ -23,7 +22,6 @@ pub struct L2Fields { pub blob_commitment: blobs_bundle::Commitment, #[serde_as(as = "[_; 48]")] pub blob_proof: blobs_bundle::Proof, - pub fee_config: FeeConfig, } /// Structure holding input data needed to execute or prove blocks. /// Optional fields are included only when relevant (e.g. L2 or custom chain). @@ -77,11 +75,18 @@ impl Cache { witness: RpcExecutionWitness, chain_config: ChainConfig, dir: PathBuf, - l2_fields: Option, ) -> Self { let network = network_from_chain_id(chain_config.chain_id); #[cfg(feature = "l2")] + let l2_fields = Some(L2Fields { + blob_commitment: [0u8; 48], + blob_proof: [0u8; 48], + }); + #[cfg(feature = "l2")] let chain_config = Some(chain_config); + + #[cfg(not(feature = "l2"))] + let l2_fields = None; #[cfg(not(feature = "l2"))] let chain_config = None; Self { diff --git a/cmd/ethrex_replay/src/cli.rs b/cmd/ethrex_replay/src/cli.rs index 99818cba1b3..7de14626e49 100644 --- a/cmd/ethrex_replay/src/cli.rs +++ b/cmd/ethrex_replay/src/cli.rs @@ -14,8 +14,6 @@ use ethrex_blockchain::{ fork_choice::apply_fork_choice, payload::{BuildPayloadArgs, PayloadBuildResult, create_payload}, }; -#[cfg(feature = "l2")] -use ethrex_common::types::fee_config::FeeConfig; use ethrex_common::{ Address, H256, types::{ @@ -23,8 +21,6 @@ use ethrex_common::{ ELASTICITY_MULTIPLIER, Receipt, block_execution_witness::GuestProgramState, }, }; -#[cfg(feature = "l2")] -use ethrex_l2_rpc::clients::get_fee_vault_address; use ethrex_prover_lib::backend::Backend; use ethrex_rlp::{decode::RLPDecode, encode::RLPEncode}; use ethrex_rpc::{ @@ -359,8 +355,6 @@ pub struct BatchOptions { pub struct CustomBlockOptions { #[command(flatten)] common: CommonOptions, - #[arg(long, help = "Fee vault address to use in L2 blocks.")] - fee_vault: Option
, } #[derive(Parser)] @@ -373,8 +367,6 @@ pub struct CustomBatchOptions { n_blocks: u64, #[command(flatten)] common: CommonOptions, - #[arg(long, help = "Fee vault address to use in L2 blocks.")] - fee_vault: Option
, } impl EthrexReplayCommand { @@ -517,12 +509,11 @@ impl EthrexReplayCommand { } } #[cfg(not(feature = "l2"))] - Self::Custom(CustomSubcommand::Block(CustomBlockOptions { common, fee_vault })) => { + Self::Custom(CustomSubcommand::Block(CustomBlockOptions { common })) => { Box::pin(async move { Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks: 1, common, - fee_vault, })) .run() .await @@ -530,11 +521,7 @@ impl EthrexReplayCommand { .await?; } #[cfg(not(feature = "l2"))] - Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { - n_blocks, - common, - fee_vault: _, - })) => { + Self::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks, common })) => { let opts = EthrexReplayOptions { rpc_url: Some(Url::parse("http://localhost:8545")?), cached: false, @@ -609,13 +596,7 @@ impl EthrexReplayCommand { let (eth_client, network) = setup_rpc(&opts).await?; - let fee_config = FeeConfig { - fee_vault: get_fee_vault_address(ð_client).await?, - ..Default::default() - }; - - let cache = - get_batchdata(eth_client, network, batch, opts.cache_dir, fee_config).await?; + let cache = get_batchdata(eth_client, network, batch, opts.cache_dir).await?; let backend = backend(&opts.common.zkvm)?; @@ -637,14 +618,12 @@ impl EthrexReplayCommand { #[cfg(feature = "l2")] Self::L2(L2Subcommand::Custom(CustomSubcommand::Block(CustomBlockOptions { common, - fee_vault, }))) => { Box::pin(async move { Self::L2(L2Subcommand::Custom(CustomSubcommand::Batch( CustomBatchOptions { n_blocks: 1, common, - fee_vault, }, ))) .run() @@ -656,7 +635,6 @@ impl EthrexReplayCommand { Self::L2(L2Subcommand::Custom(CustomSubcommand::Batch(CustomBatchOptions { n_blocks, common, - fee_vault, }))) => { let opts = EthrexReplayOptions { common, @@ -671,12 +649,7 @@ impl EthrexReplayCommand { network: None, }; - let fee_config = FeeConfig { - fee_vault: fee_vault, - ..Default::default() - }; - - let report = replay_custom_l2_blocks(max(1, n_blocks), fee_config, opts).await?; + let report = replay_custom_l2_blocks(max(1, n_blocks), opts).await?; println!("{report}"); } @@ -854,7 +827,6 @@ async fn replay_transaction(tx_opts: TransactionOpts) -> eyre::Result<()> { .get_transaction_by_hash(tx_hash) .await? .ok_or(eyre::Error::msg("error fetching transaction"))?; - get_blockdata(tx_opts.opts, Some(tx.block_number.as_u64())) .await? .0 @@ -1070,7 +1042,6 @@ pub async fn replay_custom_l1_blocks( RpcExecutionWitness::from(execution_witness), chain_config, opts.cache_dir, - None, ); let execution_result = exec(backend(&opts.common.zkvm)?, cache.clone()).await; @@ -1184,11 +1155,9 @@ use ethrex_vm::BlockExecutionResult; #[cfg(feature = "l2")] pub async fn replay_custom_l2_blocks( n_blocks: u64, - fee_config: FeeConfig, opts: EthrexReplayOptions, ) -> eyre::Result { - use crate::cache::L2Fields; - use ethrex_blockchain::{BlockchainOptions, BlockchainType, MAX_MEMPOOL_SIZE_DEFAULT}; + use ethrex_blockchain::{BlockchainOptions, BlockchainType}; let network = Network::LocalDevnetL2; @@ -1210,14 +1179,9 @@ pub async fn replay_custom_l2_blocks( rollup_store }; - let blockchain = Arc::new(Blockchain::new( - store.clone(), - BlockchainOptions { - max_mempool_size: MAX_MEMPOOL_SIZE_DEFAULT, - r#type: BlockchainType::L2(fee_config.clone()), - ..Default::default() - }, - )); + let mut blockchain_options = BlockchainOptions::default(); + blockchain_options.r#type = BlockchainType::L2; + let blockchain = Arc::new(Blockchain::new(store.clone(), blockchain_options)); let genesis_hash = genesis.get_block().hash(); @@ -1233,18 +1197,11 @@ pub async fn replay_custom_l2_blocks( let execution_witness = blockchain.generate_witness_for_blocks(&blocks).await?; - let l2_fields = Some(L2Fields { - blob_commitment: [0u8; 48], - blob_proof: [0u8; 48], - fee_config, - }); - let cache = Cache::new( blocks, RpcExecutionWitness::from(execution_witness), genesis.config, opts.cache_dir.clone(), - l2_fields, ); let backend = backend(&opts.common.zkvm)?; diff --git a/cmd/ethrex_replay/src/fetcher.rs b/cmd/ethrex_replay/src/fetcher.rs index 87bd31ea750..46b31bf70f9 100644 --- a/cmd/ethrex_replay/src/fetcher.rs +++ b/cmd/ethrex_replay/src/fetcher.rs @@ -1,6 +1,4 @@ -use ethrex_common::types::fee_config::FeeConfig; use ethrex_config::networks::Network; -use ethrex_l2_rpc::clients::get_fee_vault_address; use ethrex_levm::vm::VMType; use ethrex_rpc::{ EthClient, @@ -20,6 +18,7 @@ use crate::{ rpc::db::RpcDB, }; +#[cfg(feature = "l2")] use crate::cache::L2Fields; #[cfg(feature = "l2")] use crate::cache::get_batch_cache_file_name; @@ -148,15 +147,10 @@ async fn get_blockdata_rpc( Err(EthClientError::GetWitnessError(GetWitnessError::RPCError(_))) => { warn!("debug_executionWitness endpoint not implemented, using fallback eth_getProof"); - let vm_type = if cfg!(feature = "l2") { - let fee_config = FeeConfig { - fee_vault: get_fee_vault_address(ð_client).await?, - ..Default::default() - }; - VMType::L2(fee_config) - } else { - VMType::L1 - }; + #[cfg(feature = "l2")] + let vm_type = VMType::L2; + #[cfg(not(feature = "l2"))] + let vm_type = VMType::L1; info!( "Caching callers and recipients state for block {}", @@ -207,25 +201,11 @@ async fn get_blockdata_rpc( format_duration(&execution_witness_retrieval_duration) ); - let l2_fields = if cfg!(feature = "l2") { - Some(L2Fields { - blob_commitment: [0u8; 48], - blob_proof: [0u8; 48], - fee_config: FeeConfig { - fee_vault: get_fee_vault_address(ð_client).await?, - ..Default::default() - }, - }) - } else { - None - }; - Ok(Cache::new( vec![block], witness_rpc, chain_config, cache_dir, - l2_fields, )) } @@ -239,7 +219,6 @@ async fn fetch_rangedata_from_client( from: u64, to: u64, dir: PathBuf, - _fee_config: Option, ) -> eyre::Result { info!("Validating RPC chain ID"); @@ -306,17 +285,7 @@ async fn fetch_rangedata_from_client( format_duration(&execution_witness_retrieval_duration) ); - let l2_fields = if cfg!(feature = "l2") { - Some(L2Fields { - blob_commitment: [0u8; 48], - blob_proof: [0u8; 48], - fee_config: _fee_config.ok_or_else(|| eyre::eyre!("fee_config is required for L2"))?, - }) - } else { - None - }; - - let cache = Cache::new(blocks, witness_rpc, chain_config, dir, l2_fields); + let cache = Cache::new(blocks, witness_rpc, chain_config, dir); Ok(cache) } @@ -327,7 +296,6 @@ pub async fn get_batchdata( network: Network, batch_number: u64, cache_dir: PathBuf, - fee_config: FeeConfig, ) -> eyre::Result { use ethrex_l2_rpc::clients::get_batch_by_number; @@ -346,7 +314,6 @@ pub async fn get_batchdata( rpc_batch.batch.first_block, rpc_batch.batch.last_block, cache_dir, - Some(fee_config), ) .await?; @@ -364,7 +331,6 @@ pub async fn get_batchdata( .proofs .first() .unwrap_or(&[0_u8; 48]), - fee_config, }); cache.write()?; diff --git a/cmd/ethrex_replay/src/run.rs b/cmd/ethrex_replay/src/run.rs index a69c8d1239b..2cf2ac6d845 100644 --- a/cmd/ethrex_replay/src/run.rs +++ b/cmd/ethrex_replay/src/run.rs @@ -106,12 +106,7 @@ pub async fn run_tx(cache: Cache, tx_hash: H256) -> eyre::Result<(Receipt, Vec eyre::Result<(Receipt, Vec eyre::Result { elasticity_multiplier: ELASTICITY_MULTIPLIER, blob_commitment: l2_fields.blob_commitment, blob_proof: l2_fields.blob_proof, - fee_config: Some(l2_fields.fee_config), }) } From e765d7a82ea980055ee0fa71c9c1471812290b9d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 16:59:11 -0300 Subject: [PATCH 50/88] Update docs --- crates/l2/tests/tests.rs | 2 -- docs/l2/deploy.md | 3 ++- docs/l2/fundamentals/transaction_fees.md | 25 +++++++++++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index aa903fe6414..d82b08dd222 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -1961,10 +1961,8 @@ async fn get_fees_details_l2( .base_fee_per_gas .unwrap(); - // Base = base_fee * gas_used let base_fees: U256 = (base_fee_per_gas * gas_used).into(); - // Priority = (effective - base_fee) * gas_used let priority_fees: U256 = total_execution_fees - base_fees; FeesDetails { diff --git a/docs/l2/deploy.md b/docs/l2/deploy.md index 539eb4db56a..0b1eec28ccd 100644 --- a/docs/l2/deploy.md +++ b/docs/l2/deploy.md @@ -39,7 +39,8 @@ ethrex l2 deploy \ --aligned.aggregator-address \ --on-chain-proposer-owner \ --bridge-owner \ - --randomize-contract-deployment + --randomize-contract-deployment \ + --operator-fee ``` You can find a genesis example in the [repo](https://github.com/lambdaclass/ethrex/blob/main/fixtures/genesis/l2.json). diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md index d50a9e3a169..486c2e1a2df 100644 --- a/docs/l2/fundamentals/transaction_fees.md +++ b/docs/l2/fundamentals/transaction_fees.md @@ -7,7 +7,7 @@ This page describes the different types of transaction fees that the Ethrex L2 r ## Execution Fees -Execution fees are divided into two components: **base fee** and **priority fee**. +Execution fees consist of two components: **base fee** and **priority fee**. ### Base Fee @@ -28,4 +28,27 @@ It is an additional tip paid by the transaction sender to incentivize the sequen ## Operator Fees +Operator fees cover the operational costs of maintaining the L2 infrastructure. + +Unlike execution fees, this amount is fixed and does not depend on gas usage, state changes, or network congestion. +All collected operator fees are deposited into a dedicated `operator fee vault` address. + +The operator fee is specified during the contract deployment step. It is initialized in the `OnChainProposer` contract and used as a public input in batch verifications. + +To set the operator fee amount: + +``` +ethrex l2 deploy --operator-fee +``` + +To set the operator fee vault address: + +``` +ethrex l2 --block-producer.operator-fee-vault-address +``` + +> [!CAUTION] +> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. + + ## L1 Fees From 49b752547017e1c71117971a390a515568e413cb Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 17:21:53 -0300 Subject: [PATCH 51/88] Rename fee vault with base fee vault --- .github/workflows/main_prover.yaml | 2 +- .github/workflows/pr-main_l2.yaml | 6 +- cmd/ethrex/l2/initializers.rs | 5 +- cmd/ethrex/l2/options.rs | 11 ++- crates/common/types/l2/fee_config.rs | 2 +- crates/l2/docker-compose.yaml | 2 +- crates/l2/networking/rpc/clients.rs | 10 +-- .../l2/{fee_vault.rs => base_fee_vault.rs} | 13 ++-- crates/l2/networking/rpc/l2/mod.rs | 2 +- crates/l2/networking/rpc/rpc.rs | 2 +- crates/l2/sequencer/block_producer.rs | 8 +-- crates/l2/sequencer/configs.rs | 2 +- crates/l2/tests/tests.rs | 72 ++++++++++--------- crates/networking/rpc/clients/eth/errors.rs | 4 +- crates/vm/levm/src/hooks/l2_hook.rs | 12 ++-- docs/CLI.md | 7 +- docs/l2/fundamentals/transaction_fees.md | 6 +- fixtures/genesis/l2.json | 4 +- 18 files changed, 90 insertions(+), 80 deletions(-) rename crates/l2/networking/rpc/l2/{fee_vault.rs => base_fee_vault.rs} (65%) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index f348c825cfa..43b353cde88 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -80,7 +80,7 @@ jobs: ETHREX_PROPOSER_BLOCK_TIME=12000 \ ETHREX_COMMITTER_COMMIT_TIME=30000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ docker compose up --build --detach --no-deps ethrex_l2 diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 20b60e274e5..0331067f821 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -170,7 +170,7 @@ jobs: ETHREX_WATCHER_BLOCK_DELAY=0 \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 @@ -279,7 +279,7 @@ jobs: RUST_LOG=info,ethrex_prover_lib=debug make init-prover & docker logs --follow ethrex_l2 & PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ - INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true \ + INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK=true \ cargo test l2 --release -- --nocapture --test-threads=1 killall ethrex -s SIGINT @@ -358,7 +358,7 @@ jobs: ETHREX_WATCHER_WATCH_INTERVAL=1000 \ DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ ETHREX_PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ docker compose -f docker-compose.yaml -f docker-compose-l2-tdx.yaml up --detach --no-deps ethrex_l2 diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 109272f5045..800939386fe 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -163,7 +163,10 @@ pub async fn init_l2( let operator_fee_config = get_operator_fee_config(&opts.sequencer_opts).await?; let fee_config = FeeConfig { - fee_vault: opts.sequencer_opts.block_producer_opts.fee_vault_address, + base_fee_vault: opts + .sequencer_opts + .block_producer_opts + .base_fee_vault_address, operator_fee_config, }; diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 5b14f04d381..0c273fcf485 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -160,7 +160,7 @@ impl TryFrom for SequencerConfig { .block_producer_opts .coinbase_address .ok_or(SequencerOptionsError::NoCoinbaseAddress)?, - fee_vault_address: opts.block_producer_opts.fee_vault_address, + base_fee_vault_address: opts.block_producer_opts.base_fee_vault_address, operator_fee_vault_address: opts.block_producer_opts.operator_fee_vault_address, elasticity_multiplier: opts.block_producer_opts.elasticity_multiplier, block_gas_limit: opts.block_producer_opts.block_gas_limit, @@ -390,13 +390,12 @@ pub struct BlockProducerOptions { )] pub coinbase_address: Option
, #[arg( - long = "block-producer.fee-vault-address", + long = "block-producer.base-fee-vault-address", value_name = "ADDRESS", - env = "ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS", + env = "ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS", help_heading = "Block producer options" )] - pub fee_vault_address: Option
, - // TODO: rename fee_vault to base_fee_vault + pub base_fee_vault_address: Option
, #[arg( long = "block-producer.operator-fee-vault-address", value_name = "ADDRESS", @@ -432,7 +431,7 @@ impl Default for BlockProducerOptions { .parse() .unwrap(), ), - fee_vault_address: None, + base_fee_vault_address: None, operator_fee_vault_address: None, elasticity_multiplier: 2, block_gas_limit: DEFAULT_BUILDER_GAS_CEIL, diff --git a/crates/common/types/l2/fee_config.rs b/crates/common/types/l2/fee_config.rs index cee258d66b9..4e699768117 100644 --- a/crates/common/types/l2/fee_config.rs +++ b/crates/common/types/l2/fee_config.rs @@ -10,7 +10,7 @@ use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper, U256Wrapper}; pub struct FeeConfig { /// If set, the base fee is sent to this address instead of being burned. #[rkyv(with=OptionH160Wrapper)] - pub fee_vault: Option
, + pub base_fee_vault: Option
, pub operator_fee_config: Option, } diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index 0f00961f63a..8c4054bcbd3 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -79,7 +79,7 @@ services: - ETHREX_DEPLOYER_PICO_DEPLOY_VERIFIER=${ETHREX_DEPLOYER_PICO_DEPLOY_VERIFIER:-false} - ETHREX_WATCHER_BLOCK_DELAY=${ETHREX_WATCHER_BLOCK_DELAY:-0} - ETHREX_BASED=${ETHREX_BASED:-false} - - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS + - ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS - ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=${ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY:-0x0000000000000000000000000000000000000000} - ETHREX_COMMITTER_COMMIT_TIME=${ETHREX_COMMITTER_COMMIT_TIME:-60000} diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 3be8a8635b8..e6ee9c939e4 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -8,7 +8,7 @@ use ethrex_rpc::{ EthClientError, eth::{ RpcResponse, - errors::{GetBatchByNumberError, GetFeeVaultAddressError, GetMessageProofError}, + errors::{GetBaseFeeVaultAddressError, GetBatchByNumberError, GetMessageProofError}, }, }, utils::RpcRequest, @@ -49,15 +49,17 @@ pub async fn get_batch_by_number( } } -pub async fn get_fee_vault_address(client: &EthClient) -> Result, EthClientError> { +pub async fn get_base_fee_vault_address( + client: &EthClient, +) -> Result, EthClientError> { let request = RpcRequest::new("ethrex_getFeeVaultAddress", None); match client.send_request(request).await? { RpcResponse::Success(result) => serde_json::from_value(result.result) - .map_err(GetFeeVaultAddressError::SerdeJSONError) + .map_err(GetBaseFeeVaultAddressError::SerdeJSONError) .map_err(EthClientError::from), RpcResponse::Error(error_response) => { - Err(GetFeeVaultAddressError::RPCError(error_response.error.message).into()) + Err(GetBaseFeeVaultAddressError::RPCError(error_response.error.message).into()) } } } diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/base_fee_vault.rs similarity index 65% rename from crates/l2/networking/rpc/l2/fee_vault.rs rename to crates/l2/networking/rpc/l2/base_fee_vault.rs index 59d1132f366..de204830399 100644 --- a/crates/l2/networking/rpc/l2/fee_vault.rs +++ b/crates/l2/networking/rpc/l2/base_fee_vault.rs @@ -13,20 +13,19 @@ impl RpcHandler for GetFeeVaultAddress { } async fn handle(&self, context: RpcApiContext) -> Result { - let fee_vault_address = match context.l1_ctx.blockchain.options.r#type { + let base_fee_vault_address = match context.l1_ctx.blockchain.options.r#type { ethrex_blockchain::BlockchainType::L1 => None, - ethrex_blockchain::BlockchainType::L2(fee_config) => fee_config.fee_vault, + ethrex_blockchain::BlockchainType::L2(fee_config) => fee_config.base_fee_vault, }; Ok( - serde_json::to_value(fee_vault_address.map(|addr| format!("{:#x}", addr))).map_err( - |e| { + serde_json::to_value(base_fee_vault_address.map(|addr| format!("{:#x}", addr))) + .map_err(|e| { ethrex_rpc::RpcErr::Internal(format!( - "Failed to serialize fee vault address: {}", + "Failed to serialize base fee vault address: {}", e )) - }, - )?, + })?, ) } } diff --git a/crates/l2/networking/rpc/l2/mod.rs b/crates/l2/networking/rpc/l2/mod.rs index 7b3394e5d57..4abd6634b21 100644 --- a/crates/l2/networking/rpc/l2/mod.rs +++ b/crates/l2/networking/rpc/l2/mod.rs @@ -1,4 +1,4 @@ +pub mod base_fee_vault; pub mod batch; -pub mod fee_vault; pub mod l1_message; pub mod transaction; diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index c4b6f65744a..a5e239a8d1e 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -1,5 +1,5 @@ +use crate::l2::base_fee_vault::GetFeeVaultAddress; use crate::l2::batch::{BatchNumberRequest, GetBatchByBatchNumberRequest}; -use crate::l2::fee_vault::GetFeeVaultAddress; use crate::l2::l1_message::GetL1MessageProof; use crate::utils::{RpcErr, RpcNamespace, resolve_namespace}; use axum::extract::State; diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 0165fab7e2e..e87d75b7b53 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -83,16 +83,16 @@ impl BlockProducer { let BlockProducerConfig { block_time_ms, coinbase_address, - fee_vault_address, + base_fee_vault_address, operator_fee_vault_address, elasticity_multiplier, block_gas_limit, } = config; - if let Some(fee_vault) = fee_vault_address { - if fee_vault == coinbase_address { + if let Some(base_fee_vault) = base_fee_vault_address { + if base_fee_vault == coinbase_address { warn!( - "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", + "The coinbase address and base fee vault address are the same. Coinbase balance behavior will be affected.", ); } } diff --git a/crates/l2/sequencer/configs.rs b/crates/l2/sequencer/configs.rs index d72046190b8..87d13a97eb2 100644 --- a/crates/l2/sequencer/configs.rs +++ b/crates/l2/sequencer/configs.rs @@ -23,7 +23,7 @@ pub struct SequencerConfig { pub struct BlockProducerConfig { pub block_time_ms: u64, pub coinbase_address: Address, - pub fee_vault_address: Option
, + pub base_fee_vault_address: Option
, pub operator_fee_vault_address: Option
, pub elasticity_multiplier: u64, pub block_gas_limit: u64, diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index d82b08dd222..769d1c3dbba 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -57,7 +57,9 @@ use tokio::task::JoinSet; /// Contract addresses: /// ETHREX_WATCHER_BRIDGE_ADDRESS: The address of the l1 bridge contract /// INTEGRATION_TEST_PROPOSER_COINBASE_ADDRESS: The address of the l2 coinbase -/// INTEGRATION_TEST_PROPOSER_FEE_VAULT_ADDRESS: The address of the l2 fee_vault +/// INTEGRATION_TEST_PROPOSER_BASE_FEE_VAULT_ADDRESS: The address of the l2 base_fee_vault +/// INTEGRATION_TEST_PROPOSER_OPERATOR_FEE_VAULT_ADDRESS: The address of the l2 operator_fee_vault +/// INTEGRATION_TEST_OPERATOR_FEE_VAULT_ADDRESS /// /// Test parameters: /// @@ -82,7 +84,7 @@ const DEFAULT_PROPOSER_COINBASE_ADDRESS: Address = H160([ ]); // 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 -const DEFAULT_PROPOSER_FEE_VAULT_ADDRESS: Address = H160([ +const DEFAULT_PROPOSER_BASE_FEE_VAULT_ADDRESS: Address = H160([ 0x00, 0x0c, 0x0d, 0x6b, 0x7c, 0x45, 0x16, 0xa5, 0xb2, 0x74, 0xc5, 0x1e, 0xa3, 0x31, 0xa9, 0x41, 0x0f, 0xe6, 0x91, 0x27, ]); @@ -114,8 +116,8 @@ async fn l2_integration_test() -> Result<(), Box> { let coinbase_balance_before_tests = l2_client .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_before_tests = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_before_tests = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_fee_vault_balance_before_tests = l2_client .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) @@ -209,8 +211,8 @@ async fn l2_integration_test() -> Result<(), Box> { .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_after_tests = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_after_tests = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_fee_vault_balance_after_tests = l2_client @@ -225,11 +227,11 @@ async fn l2_integration_test() -> Result<(), Box> { "Coinbase is not correct after tests" ); - if std::env::var("INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK").is_err() { + if std::env::var("INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK").is_err() { assert_eq!( - fee_vault_balance_after_tests, - fee_vault_balance_before_tests + acc_base_fees, - "Fee vault is not correct after tests" + base_fee_vault_balance_after_tests, + base_fee_vault_balance_before_tests + acc_base_fees, + "Base fee vault is not correct after tests" ); } @@ -1023,7 +1025,7 @@ async fn test_send( } /// Test depositing ETH from L1 to L2 -/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and coinbase, fee vault and operator vault on L2 +/// 1. Fetch initial balances of depositor on L1, recipient on L2, bridge on L1 and coinbase, base and operator fee vault on L2 /// 2. Perform deposit from L1 to L2 /// 3. Check final balances. async fn test_deposit( @@ -1060,8 +1062,8 @@ async fn test_deposit( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_before_deposit = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_before_deposit = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_vault_balance_before_deposit = l2_client @@ -1131,8 +1133,8 @@ async fn test_deposit( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_after_deposit = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_after_deposit = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_fee_vault_balance_after_deposit = l2_client @@ -1145,8 +1147,8 @@ async fn test_deposit( ); assert_eq!( - fee_vault_balance_after_deposit, fee_vault_balance_before_deposit, - "Fee vault balance should not change after deposit" + base_fee_vault_balance_after_deposit, base_fee_vault_balance_before_deposit, + "Base fee vault balance should not change after deposit" ); assert_eq!( @@ -1509,8 +1511,8 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_before_withdrawal = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_before_withdrawal = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_fee_vault_balance_before_withdrawal = l2_client @@ -1583,8 +1585,8 @@ async fn test_n_withdraws( .get_balance(coinbase(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let fee_vault_balance_after_withdrawal = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance_after_withdrawal = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; let operator_fee_vault_balance_after_withdrawal = l2_client .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) @@ -1597,8 +1599,8 @@ async fn test_n_withdraws( ); assert_eq!( - fee_vault_balance_after_withdrawal, - fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.base_fees, + base_fee_vault_balance_after_withdrawal, + base_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.base_fees, "Coinbase balance didn't increase as expected after withdrawal" ); @@ -1696,11 +1698,11 @@ async fn test_total_eth_l2( println!("Coinbase balance: {coinbase_balance}"); - let fee_vault_balance = l2_client - .get_balance(fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) + let base_fee_vault_balance = l2_client + .get_balance(base_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - println!("Fee vault balance: {fee_vault_balance}"); + println!("Base fee vault balance: {base_fee_vault_balance}"); let operator_fee_vault_balance = l2_client .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) @@ -1708,11 +1710,13 @@ async fn test_total_eth_l2( println!("Operator fee vault balance: {operator_fee_vault_balance}"); - let total_eth_on_l2 = - rich_accounts_balance + coinbase_balance + fee_vault_balance + operator_fee_vault_balance; + let total_eth_on_l2 = rich_accounts_balance + + coinbase_balance + + base_fee_vault_balance + + operator_fee_vault_balance; println!( - "Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} + {fee_vault_balance} + {operator_fee_vault_balance} = {total_eth_on_l2}" + "Total ETH on L2: {rich_accounts_balance} + {coinbase_balance} + {base_fee_vault_balance} + {operator_fee_vault_balance} = {total_eth_on_l2}" ); println!("Checking locked ETH on CommonBridge"); @@ -1723,7 +1727,7 @@ async fn test_total_eth_l2( println!("Bridge locked ETH: {bridge_locked_eth}"); - if std::env::var("INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK").is_err() { + if std::env::var("INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK").is_err() { assert!( total_eth_on_l2 == bridge_locked_eth, "Total ETH on L2 ({total_eth_on_l2}) differs from bridge locked ETH ({bridge_locked_eth})" @@ -1988,14 +1992,14 @@ fn coinbase() -> Address { .unwrap_or(DEFAULT_PROPOSER_COINBASE_ADDRESS) } -fn fee_vault() -> Address { - std::env::var("INTEGRATION_TEST_PROPOSER_FEE_VAULT_ADDRESS") +fn base_fee_vault() -> Address { + std::env::var("INTEGRATION_TEST_PROPOSER_BASE_FEE_VAULT_ADDRESS") .map(|address| address.parse().expect("Invalid proposer coinbase address")) - .unwrap_or(DEFAULT_PROPOSER_FEE_VAULT_ADDRESS) + .unwrap_or(DEFAULT_PROPOSER_BASE_FEE_VAULT_ADDRESS) } fn operator_fee_vault() -> Address { - std::env::var("INTEGRATION_TEST_OPERATOR_FEE_VAULT_ADDRESS") + std::env::var("INTEGRATION_TEST_PROPOSER_OPERATOR_FEE_VAULT_ADDRESS") .map(|address| address.parse().expect("Invalid proposer coinbase address")) .unwrap_or(DEFAULT_OPERATOR_FEE_VAULT_ADDRESS) } diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index 52d92b8c33f..07b276189c3 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -70,7 +70,7 @@ pub enum EthClientError { #[error("Failed to parse hex string: {0}")] FromStrRadixError(#[from] FromStrRadixErr), #[error("ethrex_getFeeVaultAddress request error: {0}")] - GetFeeVaultAddressError(#[from] GetFeeVaultAddressError), + GetFeeVaultAddressError(#[from] GetBaseFeeVaultAddressError), } #[derive(Debug, thiserror::Error)] @@ -306,7 +306,7 @@ pub enum GetBatchByNumberError { } #[derive(Debug, thiserror::Error)] -pub enum GetFeeVaultAddressError { +pub enum GetBaseFeeVaultAddressError { #[error("{0}")] SerdeJSONError(#[from] serde_json::Error), #[error("{0}")] diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 276c1fa7507..37c79377000 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -120,7 +120,7 @@ impl Hook for L2Hook { // Different from L1: // Base fee is not burned - pay_fee_vault(vm, ctx_result.gas_used, self.fee_config.fee_vault)?; + pay_base_fee_vault(vm, ctx_result.gas_used, self.fee_config.base_fee_vault)?; // Operator fee is paid to the chain operator pay_operator_fee(vm, self.fee_config.operator_fee_config)?; @@ -155,13 +155,13 @@ fn deduct_operator_fee( Ok(()) } -fn pay_fee_vault( +fn pay_base_fee_vault( vm: &mut VM<'_>, gas_to_pay: u64, - fee_vault: Option
, + base_fee_vault: Option
, ) -> Result<(), crate::errors::VMError> { - let Some(fee_vault) = fee_vault else { - // No fee vault configured, base fee is effectively burned + let Some(base_fee_vault) = base_fee_vault else { + // No base fee vault configured, base fee is effectively burned return Ok(()); }; @@ -169,7 +169,7 @@ fn pay_fee_vault( .checked_mul(vm.env.base_fee_per_gas) .ok_or(InternalError::Overflow)?; - vm.increase_account_balance(fee_vault, base_fee)?; + vm.increase_account_balance(base_fee_vault, base_fee)?; Ok(()) } diff --git a/docs/CLI.md b/docs/CLI.md index 3ef281081c8..e9ea69b4bb4 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -293,8 +293,11 @@ Block producer options: --block-producer.coinbase-address
[env: ETHREX_BLOCK_PRODUCER_COINBASE_ADDRESS=] - --block-producer.fee-vault-address
- [env: ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=] + --block-producer.base-fee-vault-address
+ [env: ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=] + + --block-producer.operator-fee-vault-address
+ [env: ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=] --block-producer.block-gas-limit Maximum gas limit for the L2 blocks. diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md index 486c2e1a2df..841e4ad1b26 100644 --- a/docs/l2/fundamentals/transaction_fees.md +++ b/docs/l2/fundamentals/transaction_fees.md @@ -12,14 +12,14 @@ Execution fees consist of two components: **base fee** and **priority fee**. ### Base Fee The base fee follows the same rules as the Ethereum L1 base fee. It adjusts dynamically depending on network congestion to ensure stable transaction pricing. -By default, base fees are burned. However a sequencer can configure a `fee vault` address to receive the collected base fees instead of burning them. +By default, base fees are burned. However a sequencer can configure a `base fee vault` address to receive the collected base fees instead of burning them. ```sh ethrex l2 --block-producer.fee-vault-address ``` > [!CAUTION] -> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. +> If the base fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. ### Priority Fee @@ -48,7 +48,7 @@ ethrex l2 --block-producer.operator-fee-vault-address [!CAUTION] -> If the fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. +> If the operator fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. ## L1 Fees diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 07ed719fd8f..dad0fcd6e1b 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -71,8 +71,8 @@ "0x000000000000000000000000000000000000fffe": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212209320d315fdfe2f853582ea0526056692aaf3b1824836cff06f482eb1b9c4d24664736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" From 2537cce8f46600ecf35b57751e1321f6d9174c08 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 17:26:05 -0300 Subject: [PATCH 52/88] Fix based deployment --- .github/workflows/pr-main_l2.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 0331067f821..8deab40d347 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -227,6 +227,7 @@ jobs: ETHREX_DEPLOYER_RISC0_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true \ COMPILE_CONTRACTS=true \ + ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x0 \ docker compose up contract_deployer - name: Copy env to host From e955f21e0d63a0a6786833a3c544e34e26965597 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 3 Oct 2025 18:33:59 -0300 Subject: [PATCH 53/88] Continue renaming fee vault to base fee vault --- crates/l2/Makefile | 2 +- crates/l2/docker-compose-l2-store.overrides.yaml | 2 +- crates/l2/docker-compose-l2-web3signer.yaml | 2 +- docs/l2/architecture/aligned_mode.md | 2 +- docs/l2/fundamentals/transaction_fees.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/l2/Makefile b/crates/l2/Makefile index 213da595c13..5993f0a64a8 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -134,7 +134,7 @@ init-l2: ## 🚀 Initializes an L2 Lambda ethrex Client --l1.on-chain-proposer-address ${DEFAULT_ON_CHAIN_PROPOSER_ADDRESS} \ --eth.rpc-url ${L1_RPC_URL} \ --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d \ - --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + --block-producer.base-fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ --block-producer.operator-fee-vault-address 0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 \ --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d \ diff --git a/crates/l2/docker-compose-l2-store.overrides.yaml b/crates/l2/docker-compose-l2-store.overrides.yaml index ec1bcbc1162..e4d333091b8 100644 --- a/crates/l2/docker-compose-l2-store.overrides.yaml +++ b/crates/l2/docker-compose-l2-store.overrides.yaml @@ -11,7 +11,7 @@ services: --datadir /store --proof-coordinator.addr 0.0.0.0 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d - --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 + --block-producer.base-fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --no-monitor diff --git a/crates/l2/docker-compose-l2-web3signer.yaml b/crates/l2/docker-compose-l2-web3signer.yaml index 76e2efae7ba..cc323489feb 100644 --- a/crates/l2/docker-compose-l2-web3signer.yaml +++ b/crates/l2/docker-compose-l2-web3signer.yaml @@ -18,7 +18,7 @@ services: --authrpc.port 8552 --proof-coordinator.addr 0.0.0.0 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d - --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 + --block-producer.base-fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.remote-signer-url http://web3signer:9000 --committer.remote-signer-public-key 02eadbea0cdb17fda8d56fc9c51df8a6158c2ab157aabf2ca57c3a32cd69f98bbc --proof-coordinator.remote-signer-url http://web3signer:9000 diff --git a/docs/l2/architecture/aligned_mode.md b/docs/l2/architecture/aligned_mode.md index 6690ed88965..ad14b727d2d 100644 --- a/docs/l2/architecture/aligned_mode.md +++ b/docs/l2/architecture/aligned_mode.md @@ -221,7 +221,7 @@ cargo run deposit-to-batcher \ ``` cd ethrex/crates/l2 -cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d --block-producer.fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf +cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features "l2" -- l2 --watcher.block-delay 0 --network ../../fixtures/genesis/l2.json --http.port 1729 --http.addr 0.0.0.0 --datadir dev_ethrex_l2 --l1.bridge-address --l1.on-chain-proposer-address --eth.rpc-url http://localhost:8545 --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d --block-producer.base-fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d --proof-coordinator.addr 127.0.0.1 --aligned --aligned.beacon-url http://127.0.0.1:58801 --aligned-network devnet --aligned-sp1-elf-path prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-elf ``` > [!IMPORTANT] diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md index 841e4ad1b26..e503d36249a 100644 --- a/docs/l2/fundamentals/transaction_fees.md +++ b/docs/l2/fundamentals/transaction_fees.md @@ -15,7 +15,7 @@ The base fee follows the same rules as the Ethereum L1 base fee. It adjusts dyna By default, base fees are burned. However a sequencer can configure a `base fee vault` address to receive the collected base fees instead of burning them. ```sh -ethrex l2 --block-producer.fee-vault-address +ethrex l2 --block-producer.base-fee-vault-address ``` > [!CAUTION] From 7b6480164fc7f4744ef32d4422541d683b3009f0 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sun, 5 Oct 2025 17:48:41 -0300 Subject: [PATCH 54/88] Don't call operator fee if based mode is enabled --- cmd/ethrex/l2/initializers.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 800939386fe..c5baeac06a6 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -301,6 +301,11 @@ pub async fn init_l2( pub async fn get_operator_fee_config( sequencer_opts: &SequencerOptions, ) -> eyre::Result> { + if sequencer_opts.based { + // If based is enabled, operator fee is not applicable + return Ok(None); + } + // Fetch operator fee from the on-chain proposer contract let operator_fee = fetch_operator_fee( sequencer_opts.eth_opts.rpc_url.clone(), From 9abd6371892636e2fdd57b3f90fe65813d8102c0 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sun, 5 Oct 2025 17:58:35 -0300 Subject: [PATCH 55/88] Skip operator fee in tests --- .github/workflows/pr-main_l2.yaml | 1 + crates/l2/tests/tests.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 8deab40d347..8f32c5002f1 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -281,6 +281,7 @@ jobs: docker logs --follow ethrex_l2 & PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK=true \ + INTEGRATION_TEST_OPERATOR_FEE_DISABLED=true \ cargo test l2 --release -- --nocapture --test-threads=1 killall ethrex -s SIGINT diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 769d1c3dbba..179e1ac4e17 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -19,8 +19,7 @@ use ethrex_l2_sdk::{ wait_for_transaction_receipt, }; use ethrex_l2_sdk::{ - build_generic_tx, get_last_verified_batch, get_operator_fee, send_generic_transaction, - wait_for_message_proof, + build_generic_tx, get_last_verified_batch, send_generic_transaction, wait_for_message_proof, }; use ethrex_rpc::{ clients::eth::{EthClient, Overrides}, @@ -68,6 +67,7 @@ use tokio::task::JoinSet; /// INTEGRATION_TEST_WITHDRAW_VALUE: amount in wei to withdraw from the l2 back to the l1 from L1_RICH_WALLET_PRIVATE_KEY this will be done INTEGRATION_TEST_WITHDRAW_COUNT times /// INTEGRATION_TEST_WITHDRAW_COUNT: amount of withdraw transactions to send /// INTEGRATION_TEST_SKIP_TEST_TOTAL_ETH: if set the integration test will not check for total eth in the chain, only to be used if we don't know all the accounts that exist in l2 +/// INTEGRATION_TEST_OPERATOR_FEE_DISABLED: if set the integration test will assume the operator fee is 0, useful for local tests without operator fee set (based) const DEFAULT_L1_RPC: &str = "http://localhost:8545"; const DEFAULT_L2_RPC: &str = "http://localhost:1729"; @@ -2210,3 +2210,10 @@ async fn wait_for_verified_proof( proof } + +async fn get_operator_fee(l1_client: &EthClient, proposer_address: Address) -> Result { + if std::env::var("INTEGRATION_TEST_OPERATOR_FEE_DISABLED").is_err() { + return Ok(U256::zero()); + } + Ok(ethrex_l2_sdk::get_operator_fee(l1_client, proposer_address).await?) +} From fd2a5e1ca8603451e539b5a1752d549cc4289463 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sun, 5 Oct 2025 18:25:24 -0300 Subject: [PATCH 56/88] Fix tests --- crates/l2/tests/tests.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 179e1ac4e17..f4a4f07b335 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -1598,11 +1598,13 @@ async fn test_n_withdraws( "Coinbase balance didn't increase as expected after withdrawal" ); - assert_eq!( - base_fee_vault_balance_after_withdrawal, - base_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.base_fees, - "Coinbase balance didn't increase as expected after withdrawal" - ); + if std::env::var("INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK").is_err() { + assert_eq!( + base_fee_vault_balance_after_withdrawal, + base_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.base_fees, + "Coinbase balance didn't increase as expected after withdrawal" + ); + } assert_eq!( operator_fee_vault_balance_after_withdrawal, @@ -2213,7 +2215,7 @@ async fn wait_for_verified_proof( async fn get_operator_fee(l1_client: &EthClient, proposer_address: Address) -> Result { if std::env::var("INTEGRATION_TEST_OPERATOR_FEE_DISABLED").is_err() { - return Ok(U256::zero()); + return Ok(ethrex_l2_sdk::get_operator_fee(l1_client, proposer_address).await?); } - Ok(ethrex_l2_sdk::get_operator_fee(l1_client, proposer_address).await?) + Ok(U256::zero()) } From ca0ce929533fe6ed877c7b0161769bf76e746d17 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sat, 11 Oct 2025 15:36:03 -0300 Subject: [PATCH 57/88] restore MAX_MEMPOOL_SIZE_DEFAULT --- crates/blockchain/blockchain.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/blockchain/blockchain.rs b/crates/blockchain/blockchain.rs index bcb8160b727..909423aed6e 100644 --- a/crates/blockchain/blockchain.rs +++ b/crates/blockchain/blockchain.rs @@ -49,7 +49,7 @@ use ethrex_metrics::metrics_blocks::METRICS_BLOCKS; use ethrex_common::types::BlobsBundle; const MAX_PAYLOADS: usize = 10; -pub const MAX_MEMPOOL_SIZE_DEFAULT: usize = 10_000; +const MAX_MEMPOOL_SIZE_DEFAULT: usize = 10_000; //TODO: Implement a struct Chain or BlockChain to encapsulate //functionality and canonical chain state and config From 717274827cad6dcb4e567199a136da4fc9d2b970 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sat, 11 Oct 2025 15:47:18 -0300 Subject: [PATCH 58/88] Fix clippy --- crates/l2/sequencer/block_producer.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 4a7ffc7de29..b4ed16a9202 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -88,12 +88,10 @@ impl BlockProducer { block_gas_limit, } = config; - if let Some(fee_vault) = fee_vault_address { - if fee_vault == coinbase_address { - warn!( - "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", - ); - } + if fee_vault_address.is_some_and(|fee_vault| fee_vault == coinbase_address) { + warn!( + "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", + ); } Self { From 652fa08d1f72b2225c2550a4cb4a24cac9a8a93d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sat, 11 Oct 2025 15:49:55 -0300 Subject: [PATCH 59/88] Restore genesis --- crates/l2/sequencer/block_producer.rs | 2 +- fixtures/genesis/l2.json | 40 ++++++++++----------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index b4ed16a9202..9a58965d280 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -88,7 +88,7 @@ impl BlockProducer { block_gas_limit, } = config; - if fee_vault_address.is_some_and(|fee_vault| fee_vault == coinbase_address) { + if fee_vault_address.is_some_and(|fee_vault| fee_vault == *coinbase_address) { warn!( "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", ); diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 07ed719fd8f..297493b1e65 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -20,29 +20,19 @@ "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa", "blobSchedule": { "cancun": { - "baseFeeUpdateFraction": 3338477, + "target": 3, "max": 6, - "target": 3 + "baseFeeUpdateFraction": 3338477 }, "prague": { - "baseFeeUpdateFraction": 5007716, + "target": 6, "max": 9, - "target": 6 + "baseFeeUpdateFraction": 5007716 }, "osaka": { - "baseFeeUpdateFraction": 5007716, + "target": 6, "max": 9, - "target": 6 - }, - "bpo1": { - "baseFeeUpdateFraction": 8346193, - "max": 15, - "target": 10 - }, - "bpo2": { - "baseFeeUpdateFraction": 11684671, - "max": 21, - "target": 14 + "baseFeeUpdateFraction": 5007716 } }, "mergeNetsplitBlock": 0, @@ -57,37 +47,37 @@ "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea264697066735822122052595471799e2ab3206407d25fa9f12184de13fc52c19811fa404f8d70dadf5864736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea26469706673582212204396f246249f52e780861cf7c8e99ebc34211e11586f573a735d1178cc6f3e8664736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea264697066735822122011dacca1d1b5f77189e7620b1c8f8bae9819e083df3392f0d94ce3b23d25107a64736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220ba047060ba3574875cd782f062d08240871ba803894074a664b4df16b994741164736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212209320d315fdfe2f853582ea0526056692aaf3b1824836cff06f482eb1b9c4d24664736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fdfea26469706673582212209320d315fdfe2f853582ea0526056692aaf3b1824836cff06f482eb1b9c4d24664736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" }, "balance": "0x0", "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea2646970667358221220a477ca37e15ea0dd573bfa394faaa39a6d7b9a1b184789ce9da7e70e9f9c8c8d64736f6c634300081d0033a26469706673582212203158f63c237a4e0884d8e826c0094400dae259cb3de30fa711c3d931e5222e0b64736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea26469706673582212203dcabd569808849d0e409a052e5e7d1fa1624dd221cdb5cd5d9cbed0d5bd521b64736f6c634300081d0033a2646970667358221220c9ee82b3796a8b1e888ae9b0f1244e703b889a0a49a1fc2f76e48ff4436c7a1564736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" From 4eafeb44b102770f34871b2c81c6eb58c41f0b04 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Sat, 11 Oct 2025 15:55:44 -0300 Subject: [PATCH 60/88] register default fee vault pk --- crates/l2/tests/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index b23a0982f7b..fb1f601a5cb 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -87,6 +87,7 @@ const DEFAULT_ON_CHAIN_PROPOSER_ADDRESS: Address = H160([ ]); // 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 +// pk: 0xe9ea73e0ca433882aa9d4e2311ecc4e17286121e6bd8e600e5d25d4243b2baa3 const DEFAULT_PROPOSER_FEE_VAULT_ADDRESS: Address = H160([ 0x00, 0x0c, 0x0d, 0x6b, 0x7c, 0x45, 0x16, 0xa5, 0xb2, 0x74, 0xc5, 0x1e, 0xa3, 0x31, 0xa9, 0x41, 0x0f, 0xe6, 0x91, 0x27, From 950540e656f37caca49b2f2025784b7959afd58a Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 13 Oct 2025 10:32:35 -0300 Subject: [PATCH 61/88] Skip fee vault check in l2 dev tests --- .github/workflows/pr-main_l2.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 191e284e47d..09f503bfb06 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -463,11 +463,13 @@ jobs: - name: Init prover run: | target/release/ethrex l2 prover --proof-coordinators http://localhost:3900 & - + - name: Run test run: | cd crates/l2 - PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d cargo test l2 --release -- --nocapture --test-threads=1 + INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true \ + PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ + cargo test l2 --release -- --nocapture --test-threads=1 # The purpose of this job is to add it as a required check in GitHub so that we don't have to add every individual job as a required check all-tests: From c22ffc2590119576b93dea5a73649ca201d845b7 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 13 Oct 2025 17:21:59 -0300 Subject: [PATCH 62/88] Free disk space in based --- .github/workflows/pr-main_l2.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index b1caeebfd36..57b99dc8d60 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -165,7 +165,7 @@ jobs: cd rex git checkout 18466ec1c3dbcbbf22a68fc1f850d660cb2fbf1f make cli - echo "rex install successfully at $(which rex)" + echo "rex install successfully at $(which rex)" - name: Deploy native token if: matrix.use_native_token @@ -221,6 +221,12 @@ jobs: runs-on: ubuntu-latest needs: build-docker steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + large-packages: false + - name: Checkout sources uses: actions/checkout@v4 - name: Setup Rust Environment From 29cacdf858cbf307f22a97e99a6ce901301d3c08 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Mon, 13 Oct 2025 17:46:39 -0300 Subject: [PATCH 63/88] Restore based workflow --- .github/workflows/pr-main_l2.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 57b99dc8d60..b1caeebfd36 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -165,7 +165,7 @@ jobs: cd rex git checkout 18466ec1c3dbcbbf22a68fc1f850d660cb2fbf1f make cli - echo "rex install successfully at $(which rex)" + echo "rex install successfully at $(which rex)" - name: Deploy native token if: matrix.use_native_token @@ -221,12 +221,6 @@ jobs: runs-on: ubuntu-latest needs: build-docker steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@v1.3.1 - with: - tool-cache: false - large-packages: false - - name: Checkout sources uses: actions/checkout@v4 - name: Setup Rust Environment From 26e34c01585880bf52d4b43bf951bf9be5c3629d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 10:51:14 -0300 Subject: [PATCH 64/88] Merge based workflow in matrix --- .github/workflows/pr-main_l2.yaml | 127 ++++++++---------------------- 1 file changed, 32 insertions(+), 95 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index b1caeebfd36..79acd72a70a 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -96,22 +96,32 @@ jobs: validium: true web3signer: false use_native_token: false + based: false compose_targets: [docker-compose.yaml] - name: "Vanilla" validium: false web3signer: false use_native_token: false + based: false compose_targets: [docker-compose.yaml] - name: "Vanilla with Web3signer" validium: false web3signer: true use_native_token: false + based: false compose_targets: [docker-compose.yaml, docker-compose-l2-web3signer.yaml] - name: "ERC20 as Native Token" validium: false web3signer: false use_native_token: true + based: false + compose_targets: [docker-compose.yaml] + - name: "Based" + validium: false + web3signer: false + use_native_token: false + based: true compose_targets: [docker-compose.yaml] steps: - name: Checkout sources @@ -165,7 +175,7 @@ jobs: cd rex git checkout 18466ec1c3dbcbbf22a68fc1f850d660cb2fbf1f make cli - echo "rex install successfully at $(which rex)" + echo "rex install successfully at $(which rex)" - name: Deploy native token if: matrix.use_native_token @@ -181,7 +191,10 @@ jobs: else export ETHREX_NATIVE_TOKEN_L1_ADDRESS=0x0000000000000000000000000000000000000000 fi - + if [ "${{ matrix.based }}" = true ]; then + export ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true + export COMPILE_CONTRACTS=true + fi DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ @@ -196,87 +209,8 @@ jobs: docker cp contract_deployer:/env/.env cmd/.env cat cmd/.env - - name: Start Sequencer - run: | - cd crates/l2 - DOCKER_ETHREX_WORKDIR=/usr/local/bin \ - ETHREX_L2_VALIDIUM=${{ matrix.validium }} \ - ETHREX_WATCHER_BLOCK_DELAY=0 \ - ETHREX_COMMITTER_COMMIT_TIME=15000 \ - ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ - docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 - - - name: Run test - run: | - sudo chmod -R a+rw crates/l2 - cd crates/l2 - RUST_LOG=info,ethrex_prover_lib=debug make init-prover & - docker logs --follow ethrex_l2 & - PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d cargo test l2 --release -- --nocapture --test-threads=1 - killall ethrex -s SIGINT - - integration-test-based: - name: Integration Test - Based - runs-on: ubuntu-latest - needs: build-docker - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - name: Setup Rust Environment - uses: ./.github/actions/setup-rust - - - name: Install solc - uses: lambdaclass/get-solc@master - with: - version: v0.8.29 - token: ${{ secrets.GITHUB_TOKEN || '' }} - - - name: Download ethrex image artifact - uses: actions/download-artifact@v4 - with: - name: ethrex_image - path: /tmp - - - name: Load ethrex image - run: | - docker load --input /tmp/ethrex_image.tar - - # also creates empty verification keys (as workflow runs with exec backend) - - name: Build prover - run: | - cd crates/l2 - make build-prover - mkdir -p prover/src/guest_program/src/sp1/out && touch prover/src/guest_program/src/sp1/out/riscv32im-succinct-zkvm-vk - - - name: Start L1 & Deploy contracts - run: | - touch cmd/.env - cd crates/l2 - DOCKER_ETHREX_WORKDIR=/usr/local/bin \ - ETHREX_DEPLOYER_DEPLOY_RICH=true \ - ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ - ETHREX_DEPLOYER_SP1_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ - ETHREX_DEPLOYER_RISC0_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ - ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true \ - COMPILE_CONTRACTS=true \ - docker compose up contract_deployer - - - name: Copy env to host - run: | - docker cp contract_deployer:/env/.env cmd/.env - cat cmd/.env - - - name: Install rex - run: | - cd .. - git clone https://github.com/lambdaclass/rex.git - cd rex - git checkout 18466ec1c3dbcbbf22a68fc1f850d660cb2fbf1f - make cli - echo "rex install successfully at $(which rex)" - - name: Register sequencer + if: matrix.based run: | cd cmd SEQUENCER_REGISTRY=$(grep ETHREX_DEPLOYER_SEQUENCER_REGISTRY .env | cut -d= -f2) @@ -291,29 +225,32 @@ jobs: - name: Start Sequencer run: | - cd cmd - SEQUENCER_REGISTRY=$(grep ETHREX_DEPLOYER_SEQUENCER_REGISTRY .env | cut -d= -f2) - export SEQUENCER_REGISTRY - cd ../crates/l2 - + if [ "${{ matrix.based }}" = true ]; then + cd cmd + ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=$(grep ETHREX_DEPLOYER_SEQUENCER_REGISTRY .env | cut -d= -f2) + export ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY + export ETHREX_BASED=true + cd .. + fi + cd crates/l2 DOCKER_ETHREX_WORKDIR=/usr/local/bin \ - ETHREX_COMMITTER_VALIDIUM=false \ - ETHREX_COMMITTER_COMMIT_TIME=15000 \ + ETHREX_L2_VALIDIUM=${{ matrix.validium }} \ ETHREX_WATCHER_BLOCK_DELAY=0 \ - ETHREX_BASED=true \ - ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY="$SEQUENCER_REGISTRY" \ + ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - docker compose up --detach --no-deps ethrex_l2 + ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ + docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 - name: Run test run: | + if [ "${{ matrix.based }}" = true ]; then + export INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true + fi sudo chmod -R a+rw crates/l2 cd crates/l2 RUST_LOG=info,ethrex_prover_lib=debug make init-prover & docker logs --follow ethrex_l2 & - PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ - INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true \ - cargo test l2 --release -- --nocapture --test-threads=1 + PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d cargo test l2 --release -- --nocapture --test-threads=1 killall ethrex -s SIGINT integration-test-tdx: From 704d9e6db2aac730dd2a6a95625405c318d293a2 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 10:55:09 -0300 Subject: [PATCH 65/88] Removed based from all-test --- .github/workflows/pr-main_l2.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 79acd72a70a..f7551fb9753 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -452,12 +452,11 @@ jobs: [ integration-test, state-diff-test, - integration-test-based, integration-test-tdx, integration-test-l2-dev, ] # Make sure this job runs even if the previous jobs failed or were skipped - if: ${{ always() && needs.integration-test.result != 'skipped' && needs.state-diff-test.result != 'skipped' && needs.integration-test-based.result != 'skipped' && needs.integration-test-tdx.result != 'skipped' && needs.integration-test-l2-dev.result != 'skipped' }} + if: ${{ always() && needs.integration-test.result != 'skipped' && needs.state-diff-test.result != 'skipped' && needs.integration-test-tdx.result != 'skipped' && needs.integration-test-l2-dev.result != 'skipped' }} steps: - name: Check if any job failed run: | @@ -471,11 +470,6 @@ jobs: exit 1 fi - if [ "${{ needs.integration-test-based.result }}" != "success" ]; then - echo "Job Integration Tests Based failed" - exit 1 - fi - if [ "${{ needs.integration-test-l2-dev.result }}" != "success" ]; then echo "Job Integration Tests L2 Dev failed" exit 1 From e0981746ab877a6c606b452917381c1352dee350 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 11:10:14 -0300 Subject: [PATCH 66/88] Install rex in based --- .github/workflows/pr-main_l2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index f7551fb9753..bd53fea94f8 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -168,7 +168,7 @@ jobs: docker compose up --detach ethrex_l1 - name: Install rex - if: matrix.use_native_token + if: ${{ matrix.use_native_token || matrix.based }} run: | cd .. git clone https://github.com/lambdaclass/rex.git From e034fdcff1ce0c7d731269c00bd9e1cc0a92a5eb Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 11:36:40 -0300 Subject: [PATCH 67/88] Don't set fee vault in based --- .github/workflows/pr-main_l2.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index bd53fea94f8..589220e5855 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -231,6 +231,8 @@ jobs: export ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY export ETHREX_BASED=true cd .. + else + export ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 fi cd crates/l2 DOCKER_ETHREX_WORKDIR=/usr/local/bin \ @@ -238,7 +240,6 @@ jobs: ETHREX_WATCHER_BLOCK_DELAY=0 \ ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_WATCHER_WATCH_INTERVAL=1000 \ - ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ docker compose -f ${{ join(matrix.compose_targets, ' -f ') }} up --detach --no-deps ethrex_l2 - name: Run test From 0b965c81ffae5d111840c09f7cc2ea0bd7143632 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 12:06:09 -0300 Subject: [PATCH 68/88] Fix clippy --- crates/l2/sequencer/block_producer.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index c3cbb7db736..b020fba7a89 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -89,9 +89,10 @@ impl BlockProducer { block_gas_limit, } = config; - if fee_vault_address.is_some_and(|fee_vault| fee_vault == *coinbase_address) { + if base_fee_vault_address.is_some_and(|base_fee_vault| base_fee_vault == *coinbase_address) + { warn!( - "The coinbase address and fee vault address are the same. Coinbase balance behavior will be affected.", + "The coinbase address and base fee vault address are the same. Coinbase balance behavior will be affected.", ); } if operator_fee_vault_address From f95a173604cfae526b9a30e0277919485bba45cd Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 18:05:03 -0300 Subject: [PATCH 69/88] remove operator fee from onChainProposer --- .github/workflows/main_prover.yaml | 2 +- .github/workflows/pr-main_l2.yaml | 11 +++---- cmd/ethrex/cli.rs | 2 +- cmd/ethrex/l2/deployer.rs | 12 +------ cmd/ethrex/l2/initializers.rs | 31 +++--------------- cmd/ethrex/l2/options.rs | 11 +++++++ crates/common/types/l2/fee_config.rs | 2 +- crates/l2/Makefile | 6 ++-- .../l2/contracts/src/l1/OnChainProposer.sol | 15 ++------- crates/l2/docker-compose.yaml | 2 +- crates/l2/networking/rpc/l2/base_fee_vault.rs | 8 ++--- crates/l2/networking/rpc/l2/fee_vault.rs | 32 ------------------- crates/l2/networking/rpc/l2/mod.rs | 1 - crates/l2/networking/rpc/rpc.rs | 5 ++- .../prover/src/guest_program/src/execution.rs | 11 ------- .../l2/prover/src/guest_program/src/output.rs | 3 -- crates/l2/sdk/src/sdk.rs | 19 ----------- crates/vm/levm/src/hooks/l2_hook.rs | 7 ++-- docs/l2/deploy.md | 3 +- fixtures/genesis/l2.json | 2 +- 20 files changed, 42 insertions(+), 143 deletions(-) delete mode 100644 crates/l2/networking/rpc/l2/fee_vault.rs diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 43b353cde88..34c7ce37f7f 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -66,7 +66,6 @@ jobs: DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_SP1_DEPLOY_VERIFIER=true \ - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 \ docker compose up --build contract_deployer - name: Ensure admin permissions in _work @@ -82,6 +81,7 @@ jobs: ETHREX_WATCHER_WATCH_INTERVAL=1000 \ ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ docker compose up --build --detach --no-deps ethrex_l2 - name: Copy env to host diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index a250e3f9e18..8f752843b43 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -194,9 +194,6 @@ jobs: if [ "${{ matrix.based }}" = true ]; then export ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true export COMPILE_CONTRACTS=true - else - export ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 - fi DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ @@ -234,8 +231,9 @@ jobs: export ETHREX_BASED=true cd .. else - export ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 - export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 + export ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 + export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 + export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 fi cd crates/l2 DOCKER_ETHREX_WORKDIR=/usr/local/bin \ @@ -322,7 +320,6 @@ jobs: ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_TDX_DEPLOY_VERIFIER=true \ ETHREX_TDX_DEV_MODE=true \ - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x3B9ACA00 \ make deploy-l1 - name: Start Sequencer @@ -334,6 +331,7 @@ jobs: ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ ETHREX_PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ docker compose -f docker-compose.yaml -f docker-compose-l2-tdx.yaml up --detach --no-deps ethrex_l2 @@ -391,7 +389,6 @@ jobs: ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_SP1_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ ETHREX_DEPLOYER_RISC0_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE=0x0 \ COMPILE_CONTRACTS=true \ docker compose up contract_deployer diff --git a/cmd/ethrex/cli.rs b/cmd/ethrex/cli.rs index 04d1ceeeb90..18ad18e821f 100644 --- a/cmd/ethrex/cli.rs +++ b/cmd/ethrex/cli.rs @@ -7,7 +7,7 @@ use std::{ use clap::{ArgAction, Parser as ClapParser, Subcommand as ClapSubcommand}; use ethrex_blockchain::{BlockchainOptions, BlockchainType, error::ChainError}; -use ethrex_common::types::{Block, Genesis, fee_config::FeeConfig, fee_config::FeeConfig}; +use ethrex_common::types::{Block, Genesis, fee_config::FeeConfig}; use ethrex_p2p::{sync::SyncMode, tx_broadcaster::BROADCAST_INTERVAL_MS, types::Node}; use ethrex_rlp::encode::RLPEncode; use ethrex_storage::error::StoreError; diff --git a/cmd/ethrex/l2/deployer.rs b/cmd/ethrex/l2/deployer.rs index 48f8dc3e6b4..ffb86e50717 100644 --- a/cmd/ethrex/l2/deployer.rs +++ b/cmd/ethrex/l2/deployer.rs @@ -333,14 +333,6 @@ pub struct DeployerOptions { help = "The L1 address of the L2 native token (e.g., USDC, USDT, DAI, etc. Use address(0) for ETH)" )] pub native_token_l1_address: Address, - #[arg( - long, - value_name = "UINT256", - env = "ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE", - help_heading = "Deployer options", - help = "Fee that the operator will receive for each transaction included in a block." - )] - pub operator_fee: U256, } impl Default for DeployerOptions { @@ -424,7 +416,6 @@ impl Default for DeployerOptions { inclusion_max_wait: 3000, use_compiled_genesis: true, native_token_l1_address: H160::zero(), - operator_fee: U256::zero(), } } } @@ -504,7 +495,7 @@ const SP1_VERIFIER_BYTECODE: &[u8] = include_bytes!(concat!( )); const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE_BASED: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address,uint256)"; -const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address[],uint256,uint256)"; +const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE: &str = "initialize(bool,address,address,address,address,address,bytes32,bytes32,bytes32,address[],uint256)"; const INITIALIZE_BRIDGE_ADDRESS_SIGNATURE: &str = "initializeBridgeAddress(address)"; const TRANSFER_OWNERSHIP_SIGNATURE: &str = "transferOwnership(address)"; @@ -859,7 +850,6 @@ async fn initialize_contracts( Value::Address(opts.proof_sender_l1_address), ]), Value::Uint(genesis.config.chain_id.into()), - Value::Uint(opts.operator_fee), ]; trace!(calldata_values = ?calldata_values, "OnChainProposer initialization calldata values"); let on_chain_proposer_initialization_calldata = diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 88bf6024016..4edeb50c2ac 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -11,7 +11,7 @@ use ethrex_blockchain::{Blockchain, BlockchainType}; use ethrex_common::U256; use ethrex_common::types::fee_config::{FeeConfig, OperatorFeeConfig}; use ethrex_common::{Address, types::DEFAULT_BUILDER_GAS_CEIL}; -use ethrex_l2::SequencerConfig; +use ethrex_l2::{SequencerConfig, sequencer}; use ethrex_l2_sdk::get_operator_fee; use ethrex_p2p::{ discv4::peer_table::PeerTable, @@ -306,42 +306,19 @@ pub async fn get_operator_fee_config( return Ok(None); } - // Fetch operator fee from the on-chain proposer contract - let operator_fee = fetch_operator_fee( - sequencer_opts.eth_opts.rpc_url.clone(), - sequencer_opts.committer_opts.on_chain_proposer_address, - ) - .await?; + let operator_fee = sequencer_opts.block_producer_opts.operator_fee_per_gas; - // Check if operator fee vault address is provided in the config let operator_address = sequencer_opts .block_producer_opts .operator_fee_vault_address; - let operator_fee_config = if let Some(address) = operator_address { + let operator_fee_config = if let (Some(address), Some(fee)) = (operator_address, operator_fee) { Some(OperatorFeeConfig { - operator_fee, + operator_fee_per_gas: fee, operator_fee_vault: address, }) } else { - if !operator_fee.is_zero() { - error!( - "The operator fee is set on-chain, but no operator fee vault address is provided in the configuration." - ); - return Err(eyre::eyre!("Missing operator fee vault address")); - } None }; Ok(operator_fee_config) } - -pub async fn fetch_operator_fee( - rpc_urls: Vec, - on_chain_proposer_address: Option
, -) -> Result { - let contract_address = on_chain_proposer_address.ok_or(EthClientError::Custom( - "on_chain_proposer_address not set in config".to_string(), - ))?; - let eth_client = EthClient::new_with_multiple_urls(rpc_urls)?; - get_operator_fee(ð_client, contract_address).await -} diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 0c273fcf485..863f3b6c186 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -399,10 +399,20 @@ pub struct BlockProducerOptions { #[arg( long = "block-producer.operator-fee-vault-address", value_name = "ADDRESS", + requires = "operator_fee_per_gas", env = "ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS", help_heading = "Block producer options" )] pub operator_fee_vault_address: Option
, + #[arg( + long, + value_name = "UINT256", + env = "ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS", + requires = "operator_fee_vault_address", + help_heading = "Block producer options", + help = "Fee per gas that the operator will receive for each transaction included in a block." + )] + pub operator_fee_per_gas: Option, #[arg( long, default_value = "2", @@ -433,6 +443,7 @@ impl Default for BlockProducerOptions { ), base_fee_vault_address: None, operator_fee_vault_address: None, + operator_fee_per_gas: None, elasticity_multiplier: 2, block_gas_limit: DEFAULT_BUILDER_GAS_CEIL, } diff --git a/crates/common/types/l2/fee_config.rs b/crates/common/types/l2/fee_config.rs index 4e699768117..128fd9540e9 100644 --- a/crates/common/types/l2/fee_config.rs +++ b/crates/common/types/l2/fee_config.rs @@ -23,5 +23,5 @@ pub struct OperatorFeeConfig { #[rkyv(with=H160Wrapper)] pub operator_fee_vault: Address, #[rkyv(with=U256Wrapper)] - pub operator_fee: U256, + pub operator_fee_per_gas: u64, } diff --git a/crates/l2/Makefile b/crates/l2/Makefile index 5993f0a64a8..30ab59f94d8 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -45,7 +45,7 @@ L1_AUTH_PORT=8551 L1_RPC_ADDRESS=0.0.0.0 L2_RPC_ADDRESS=0.0.0.0 PROOF_COORDINATOR_ADDRESS?=127.0.0.1 -ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE?=0x3B9ACA00 \ +ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS?=0x3B9ACA00 \ # Matches the ports used by the blockchain/metrics dir L2_PROMETHEUS_METRICS_PORT = 3702 @@ -95,8 +95,7 @@ deploy-l1: ## 📜 Deploys the L1 contracts --deposit-rich \ --private-keys-file-path ../../fixtures/keys/private_keys_l1.txt \ --genesis-l1-path ../../fixtures/genesis/l1-dev.json \ - --genesis-l2-path ../../fixtures/genesis/l2.json \ - --operator-fee ${ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE} + --genesis-l2-path ../../fixtures/genesis/l2.json ## Same as deploy-l1 but deploys the SP1 verifier deploy-l1-sp1: ## 📜 Deploys the L1 contracts @@ -136,6 +135,7 @@ init-l2: ## 🚀 Initializes an L2 Lambda ethrex Client --block-producer.coinbase-address 0x0007a881CD95B1484fca47615B64803dad620C8d \ --block-producer.base-fee-vault-address 0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ --block-producer.operator-fee-vault-address 0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ + --block-producer.operator-fee ${ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS} \ --committer.l1-private-key 0x385c546456b6a603a1cfcaa9ec9494ba4832da08dd6bcf4de9a71e4a01b74924 \ --proof-coordinator.l1-private-key 0x39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d \ --proof-coordinator.addr ${PROOF_COORDINATOR_ADDRESS} diff --git a/crates/l2/contracts/src/l1/OnChainProposer.sol b/crates/l2/contracts/src/l1/OnChainProposer.sol index 763c3ffea8a..4a2d8ef711e 100644 --- a/crates/l2/contracts/src/l1/OnChainProposer.sol +++ b/crates/l2/contracts/src/l1/OnChainProposer.sol @@ -91,9 +91,6 @@ contract OnChainProposer is /// @notice Chain ID of the network uint256 public CHAIN_ID; - /// @notice Fee in wei to be paid to the operator fee vault on each transaction - uint256 public OPERATOR_FEE; - modifier onlySequencer() { require( authorizedSequencerAddresses[msg.sender], @@ -120,8 +117,7 @@ contract OnChainProposer is bytes32 risc0Vk, bytes32 genesisStateRoot, address[] calldata sequencerAddresses, - uint256 chainId, - uint256 operatorFee + uint256 chainId ) public initializer { VALIDIUM = _validium; @@ -170,7 +166,6 @@ contract OnChainProposer is } CHAIN_ID = chainId; - OPERATOR_FEE = operatorFee; OwnableUpgradeable.__Ownable_init(owner); } @@ -476,7 +471,7 @@ contract OnChainProposer is uint256 batchNumber, bytes calldata publicData ) internal view returns (string memory) { - if (publicData.length != 288) { + if (publicData.length != 256) { return "invalid public data length"; } bytes32 initialStateRoot = bytes32(publicData[0:32]); @@ -535,12 +530,6 @@ contract OnChainProposer is return "exceeded privileged transaction inclusion deadline, can't include non-privileged transactions"; } - - uint256 operatorFee = uint256(bytes32(publicData[256:288])); - if (OPERATOR_FEE != operatorFee) { - return - "operator fee public input does not match with the configured operator fee"; - } return ""; } diff --git a/crates/l2/docker-compose.yaml b/crates/l2/docker-compose.yaml index d21433862e5..6da14f40469 100644 --- a/crates/l2/docker-compose.yaml +++ b/crates/l2/docker-compose.yaml @@ -50,7 +50,6 @@ services: - ETHREX_BRIDGE_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_SEQUENCER_REGISTRY_OWNER=0x4417092b70a3e5f10dc504d0947dd256b965fc62 - ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=${ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS:-false} - - ETHREX_ON_CHAIN_PROPOSER_OPERATOR_FEE - ETHREX_L2_VALIDIUM=${ETHREX_L2_VALIDIUM:-false} - ETHREX_NATIVE_TOKEN_L1_ADDRESS=${ETHREX_NATIVE_TOKEN_L1_ADDRESS:-0x0000000000000000000000000000000000000000} - COMPILE_CONTRACTS=true @@ -82,6 +81,7 @@ services: - ETHREX_BASED=${ETHREX_BASED:-false} - ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS + - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS - ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY=${ETHREX_STATE_UPDATER_SEQUENCER_REGISTRY:-0x0000000000000000000000000000000000000000} - ETHREX_COMMITTER_COMMIT_TIME=${ETHREX_COMMITTER_COMMIT_TIME:-60000} - ETHREX_WATCHER_WATCH_INTERVAL=${ETHREX_WATCHER_WATCH_INTERVAL:-12000} diff --git a/crates/l2/networking/rpc/l2/base_fee_vault.rs b/crates/l2/networking/rpc/l2/base_fee_vault.rs index de204830399..603db2bf559 100644 --- a/crates/l2/networking/rpc/l2/base_fee_vault.rs +++ b/crates/l2/networking/rpc/l2/base_fee_vault.rs @@ -5,11 +5,11 @@ use crate::{ utils::RpcErr, }; -pub struct GetFeeVaultAddress; +pub struct GetBaseFeeVaultAddress; -impl RpcHandler for GetFeeVaultAddress { - fn parse(_params: &Option>) -> Result { - Ok(GetFeeVaultAddress) +impl RpcHandler for GetBaseFeeVaultAddress { + fn parse(_params: &Option>) -> Result { + Ok(GetBaseFeeVaultAddress) } async fn handle(&self, context: RpcApiContext) -> Result { diff --git a/crates/l2/networking/rpc/l2/fee_vault.rs b/crates/l2/networking/rpc/l2/fee_vault.rs deleted file mode 100644 index 59d1132f366..00000000000 --- a/crates/l2/networking/rpc/l2/fee_vault.rs +++ /dev/null @@ -1,32 +0,0 @@ -use serde_json::Value; - -use crate::{ - rpc::{RpcApiContext, RpcHandler}, - utils::RpcErr, -}; - -pub struct GetFeeVaultAddress; - -impl RpcHandler for GetFeeVaultAddress { - fn parse(_params: &Option>) -> Result { - Ok(GetFeeVaultAddress) - } - - async fn handle(&self, context: RpcApiContext) -> Result { - let fee_vault_address = match context.l1_ctx.blockchain.options.r#type { - ethrex_blockchain::BlockchainType::L1 => None, - ethrex_blockchain::BlockchainType::L2(fee_config) => fee_config.fee_vault, - }; - - Ok( - serde_json::to_value(fee_vault_address.map(|addr| format!("{:#x}", addr))).map_err( - |e| { - ethrex_rpc::RpcErr::Internal(format!( - "Failed to serialize fee vault address: {}", - e - )) - }, - )?, - ) - } -} diff --git a/crates/l2/networking/rpc/l2/mod.rs b/crates/l2/networking/rpc/l2/mod.rs index ecda135732d..4abd6634b21 100644 --- a/crates/l2/networking/rpc/l2/mod.rs +++ b/crates/l2/networking/rpc/l2/mod.rs @@ -1,5 +1,4 @@ pub mod base_fee_vault; pub mod batch; -pub mod fee_vault; pub mod l1_message; pub mod transaction; diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index 70a00764f74..53e2df87e1b 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -1,6 +1,5 @@ -use crate::l2::base_fee_vault::GetFeeVaultAddress; +use crate::l2::base_fee_vault::GetBaseFeeVaultAddress; use crate::l2::batch::{BatchNumberRequest, GetBatchByBatchNumberRequest}; -use crate::l2::fee_vault::GetFeeVaultAddress; use crate::l2::l1_message::GetL1MessageProof; use crate::utils::{RpcErr, RpcNamespace, resolve_namespace}; use axum::extract::State; @@ -218,7 +217,7 @@ pub async fn map_l2_requests(req: &RpcRequest, context: RpcApiContext) -> Result "ethrex_getMessageProof" => GetL1MessageProof::call(req, context).await, "ethrex_batchNumber" => BatchNumberRequest::call(req, context).await, "ethrex_getBatchByNumber" => GetBatchByBatchNumberRequest::call(req, context).await, - "ethrex_getFeeVaultAddress" => GetFeeVaultAddress::call(req, context).await, + "ethrex_getFeeVaultAddress" => GetBaseFeeVaultAddress::call(req, context).await, unknown_ethrex_l2_method => { Err(ethrex_rpc::RpcErr::MethodNotFound(unknown_ethrex_l2_method.to_owned()).into()) } diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index d56c6368981..34846b9c1c3 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -137,7 +137,6 @@ pub fn stateless_validation_l1( final_state_hash, last_block_hash, non_privileged_count, - operator_fee, .. } = execute_stateless(blocks, execution_witness, elasticity_multiplier, None)?; @@ -153,7 +152,6 @@ pub fn stateless_validation_l1( last_block_hash, chain_id: chain_id.into(), non_privileged_count, - operator_fee, }) } @@ -177,7 +175,6 @@ pub fn stateless_validation_l2( last_block_header, last_block_hash, non_privileged_count, - operator_fee, nodes_hashed, codes_hashed, parent_block_header, @@ -238,7 +235,6 @@ pub fn stateless_validation_l2( last_block_hash, chain_id: chain_id.into(), non_privileged_count, - operator_fee, }) } @@ -250,7 +246,6 @@ struct StatelessResult { last_block_header: BlockHeader, last_block_hash: H256, non_privileged_count: U256, - operator_fee: U256, // These fields are only used in L2 to validate state diff blobs. // We return them to avoid recomputing when comparing the initial state @@ -377,10 +372,6 @@ fn execute_stateless( parent_block_header = &block.header; } - let operator_fee = fee_config - .and_then(|fc| fc.operator_fee_config.map(|oc| oc.operator_fee)) - .unwrap_or_else(U256::zero); - // Calculate final state root hash and check let last_block = blocks .last() @@ -403,8 +394,6 @@ fn execute_stateless( last_block_header: last_block.header.clone(), last_block_hash, non_privileged_count: non_privileged_count.into(), - operator_fee, - #[cfg(feature = "l2")] nodes_hashed, #[cfg(feature = "l2")] diff --git a/crates/l2/prover/src/guest_program/src/output.rs b/crates/l2/prover/src/guest_program/src/output.rs index 9dcf7ff60a4..611314eb9a6 100644 --- a/crates/l2/prover/src/guest_program/src/output.rs +++ b/crates/l2/prover/src/guest_program/src/output.rs @@ -24,8 +24,6 @@ pub struct ProgramOutput { pub chain_id: U256, /// amount of non-privileged transactions pub non_privileged_count: U256, - /// fee that the operator will receive for each transaction included in a block - pub operator_fee: U256, } impl ProgramOutput { @@ -42,7 +40,6 @@ impl ProgramOutput { self.last_block_hash.to_fixed_bytes(), self.chain_id.to_big_endian(), self.non_privileged_count.to_big_endian(), - self.operator_fee.to_big_endian(), ] .concat() } diff --git a/crates/l2/sdk/src/sdk.rs b/crates/l2/sdk/src/sdk.rs index 3293be2982c..5625b922439 100644 --- a/crates/l2/sdk/src/sdk.rs +++ b/crates/l2/sdk/src/sdk.rs @@ -953,13 +953,6 @@ pub async fn get_last_verified_batch( _call_u64_variable(client, b"lastVerifiedBatch()", on_chain_proposer_address).await } -pub async fn get_operator_fee( - client: &EthClient, - on_chain_proposer_address: Address, -) -> Result { - _call_u256_variable(client, b"OPERATOR_FEE()", on_chain_proposer_address).await -} - pub async fn get_sp1_vk( client: &EthClient, on_chain_proposer_address: Address, @@ -1027,18 +1020,6 @@ async fn _call_u64_variable( Ok(value) } -async fn _call_u256_variable( - client: &EthClient, - selector: &[u8], - contract_address: Address, -) -> Result { - let hex_string = _generic_call(client, selector, contract_address).await?; - - let value = U256::from_str_radix(hex_string.trim_start_matches("0x"), 16)?; - - Ok(value) -} - async fn _call_address_variable( eth_client: &EthClient, selector: &[u8], diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index 37c79377000..ce3264cb126 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -150,7 +150,7 @@ fn deduct_operator_fee( }; let sender_address = vm.env.origin; - vm.decrease_account_balance(sender_address, fee_config.operator_fee) + vm.decrease_account_balance(sender_address, fee_config.operator_fee_per_gas) .map_err(|_| TxValidationError::InsufficientAccountFunds)?; Ok(()) } @@ -182,6 +182,9 @@ fn pay_operator_fee( return Ok(()); }; - vm.increase_account_balance(fee_config.operator_fee_vault, fee_config.operator_fee)?; + vm.increase_account_balance( + fee_config.operator_fee_vault, + fee_config.operator_fee_per_gas, + )?; Ok(()) } diff --git a/docs/l2/deploy.md b/docs/l2/deploy.md index 0b1eec28ccd..539eb4db56a 100644 --- a/docs/l2/deploy.md +++ b/docs/l2/deploy.md @@ -39,8 +39,7 @@ ethrex l2 deploy \ --aligned.aggregator-address \ --on-chain-proposer-owner \ --bridge-owner \ - --randomize-contract-deployment \ - --operator-fee + --randomize-contract-deployment ``` You can find a genesis example in the [repo](https://github.com/lambdaclass/ethrex/blob/main/fixtures/genesis/l2.json). diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 8553a77a0dc..91d36411f65 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -110,4 +110,4 @@ "nonce": "0x1" } } -} \ No newline at end of file +} From c0652ab65de8d1779d5c18c656ba72a361660573 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Tue, 14 Oct 2025 18:21:09 -0300 Subject: [PATCH 70/88] Minor improvements --- .github/workflows/pr-main_l2.yaml | 1 + cmd/ethrex/l2/initializers.rs | 21 +++++++++++---------- crates/vm/levm/src/utils.rs | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index 8f752843b43..2b896ad63e3 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -194,6 +194,7 @@ jobs: if [ "${{ matrix.based }}" = true ]; then export ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true export COMPILE_CONTRACTS=true + fi DOCKER_ETHREX_WORKDIR=/usr/local/bin \ ETHREX_DEPLOYER_DEPLOY_RICH=true \ ETHREX_DEPLOYER_PICO_CONTRACT_ADDRESS=0x00000000000000000000000000000000000000aa \ diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 4edeb50c2ac..dcbc1f7e5a3 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -306,19 +306,20 @@ pub async fn get_operator_fee_config( return Ok(None); } - let operator_fee = sequencer_opts.block_producer_opts.operator_fee_per_gas; + let fee = sequencer_opts.block_producer_opts.operator_fee_per_gas; - let operator_address = sequencer_opts + let address = sequencer_opts .block_producer_opts .operator_fee_vault_address; - let operator_fee_config = if let (Some(address), Some(fee)) = (operator_address, operator_fee) { - Some(OperatorFeeConfig { - operator_fee_per_gas: fee, - operator_fee_vault: address, - }) - } else { - None - }; + let operator_fee_config = + if let (Some(operator_fee_per_gas), Some(operator_fee_vault)) = (address, fee) { + Some(OperatorFeeConfig { + operator_fee_per_gas, + operator_fee_vault, + }) + } else { + None + }; Ok(operator_fee_config) } diff --git a/crates/vm/levm/src/utils.rs b/crates/vm/levm/src/utils.rs index 6aefc59c3f6..450cbbef1e7 100644 --- a/crates/vm/levm/src/utils.rs +++ b/crates/vm/levm/src/utils.rs @@ -201,7 +201,7 @@ pub fn get_max_blob_gas_price( Ok(max_blob_gas_cost) } -/// Caltulate the actual blob gas cost. +/// Calculate the actual blob gas cost. pub fn calculate_blob_gas_cost( tx_blob_hashes: &[H256], block_excess_blob_gas: Option, From a4ebd379b8e19c1ad32efe3f219cbc99ee779973 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 15 Oct 2025 17:42:34 -0300 Subject: [PATCH 71/88] Change l2 hook behavior --- cmd/ethrex/l2/initializers.rs | 10 +- cmd/ethrex/l2/options.rs | 2 +- crates/common/types/l2/fee_config.rs | 5 +- crates/l2/networking/rpc/clients.rs | 40 ++++- crates/l2/networking/rpc/l2/base_fee_vault.rs | 31 ---- crates/l2/networking/rpc/l2/fees.rs | 163 ++++++++++++++++++ crates/l2/networking/rpc/l2/mod.rs | 2 +- crates/l2/networking/rpc/rpc.rs | 6 +- crates/l2/storage/src/api.rs | 13 +- crates/l2/storage/src/store.rs | 18 +- crates/l2/storage/src/store_db/in_memory.rs | 26 ++- crates/l2/storage/src/store_db/sql.rs | 42 ++++- crates/networking/rpc/clients/eth/errors.rs | 20 ++- crates/networking/rpc/eth/gas_price.rs | 10 +- crates/vm/backends/levm/mod.rs | 48 +++++- crates/vm/backends/levm/tracing.rs | 1 + crates/vm/levm/src/hooks/l2_hook.rs | 94 ++++++++-- fixtures/genesis/l2.json | 42 +++-- 18 files changed, 479 insertions(+), 94 deletions(-) delete mode 100644 crates/l2/networking/rpc/l2/base_fee_vault.rs create mode 100644 crates/l2/networking/rpc/l2/fees.rs diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index dcbc1f7e5a3..1b9d0c820c6 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -8,11 +8,9 @@ use crate::utils::{ NodeConfigFile, get_client_version, init_datadir, read_jwtsecret_file, store_node_config_file, }; use ethrex_blockchain::{Blockchain, BlockchainType}; -use ethrex_common::U256; use ethrex_common::types::fee_config::{FeeConfig, OperatorFeeConfig}; use ethrex_common::{Address, types::DEFAULT_BUILDER_GAS_CEIL}; -use ethrex_l2::{SequencerConfig, sequencer}; -use ethrex_l2_sdk::get_operator_fee; +use ethrex_l2::SequencerConfig; use ethrex_p2p::{ discv4::peer_table::PeerTable, peer_handler::PeerHandler, @@ -20,8 +18,6 @@ use ethrex_p2p::{ sync_manager::SyncManager, types::{Node, NodeRecord}, }; -use ethrex_rpc::EthClient; -use ethrex_rpc::clients::EthClientError; use ethrex_storage::Store; use ethrex_storage_rollup::{EngineTypeRollup, StoreRollup}; use secp256k1::SecretKey; @@ -313,10 +309,10 @@ pub async fn get_operator_fee_config( .operator_fee_vault_address; let operator_fee_config = - if let (Some(operator_fee_per_gas), Some(operator_fee_vault)) = (address, fee) { + if let (Some(operator_fee_vault), Some(operator_fee_per_gas)) = (address, fee) { Some(OperatorFeeConfig { - operator_fee_per_gas, operator_fee_vault, + operator_fee_per_gas, }) } else { None diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 863f3b6c186..d371c3f7a06 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -412,7 +412,7 @@ pub struct BlockProducerOptions { help_heading = "Block producer options", help = "Fee per gas that the operator will receive for each transaction included in a block." )] - pub operator_fee_per_gas: Option, + pub operator_fee_per_gas: Option, #[arg( long, default_value = "2", diff --git a/crates/common/types/l2/fee_config.rs b/crates/common/types/l2/fee_config.rs index 128fd9540e9..9aecc43444c 100644 --- a/crates/common/types/l2/fee_config.rs +++ b/crates/common/types/l2/fee_config.rs @@ -1,8 +1,8 @@ -use ethereum_types::{Address, U256}; +use ethereum_types::Address; use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; use serde::{Deserialize, Serialize}; -use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper, U256Wrapper}; +use crate::rkyv_utils::{H160Wrapper, OptionH160Wrapper}; #[derive( Serialize, Deserialize, RDeserialize, RSerialize, Archive, Clone, Copy, Debug, Default, @@ -22,6 +22,5 @@ pub struct FeeConfig { pub struct OperatorFeeConfig { #[rkyv(with=H160Wrapper)] pub operator_fee_vault: Address, - #[rkyv(with=U256Wrapper)] pub operator_fee_per_gas: u64, } diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index e6ee9c939e4..cb391a282f8 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -51,8 +51,44 @@ pub async fn get_batch_by_number( pub async fn get_base_fee_vault_address( client: &EthClient, -) -> Result, EthClientError> { - let request = RpcRequest::new("ethrex_getFeeVaultAddress", None); + block_number: u64, +) -> Result { + let params = Some(vec![json!(format!("{block_number:#x}"))]); + let request = RpcRequest::new("ethrex_getBaseFeeVaultAddress", params); + + match client.send_request(request).await? { + RpcResponse::Success(result) => serde_json::from_value(result.result) + .map_err(GetBaseFeeVaultAddressError::SerdeJSONError) + .map_err(EthClientError::from), + RpcResponse::Error(error_response) => { + Err(GetBaseFeeVaultAddressError::RPCError(error_response.error.message).into()) + } + } +} + +pub async fn get_operator_fee_vault_address( + client: &EthClient, + block_number: u64, +) -> Result { + let params = Some(vec![json!(format!("{block_number:#x}"))]); + let request = RpcRequest::new("ethrex_getOperatorFeeVaultAddress", params); + + match client.send_request(request).await? { + RpcResponse::Success(result) => serde_json::from_value(result.result) + .map_err(GetBaseFeeVaultAddressError::SerdeJSONError) + .map_err(EthClientError::from), + RpcResponse::Error(error_response) => { + Err(GetBaseFeeVaultAddressError::RPCError(error_response.error.message).into()) + } + } +} + +pub async fn get_operator_fee( + client: &EthClient, + block_number: u64, +) -> Result { + let params = Some(vec![json!(format!("{block_number:#x}"))]); + let request = RpcRequest::new("ethrex_getOperatorFee", params); match client.send_request(request).await? { RpcResponse::Success(result) => serde_json::from_value(result.result) diff --git a/crates/l2/networking/rpc/l2/base_fee_vault.rs b/crates/l2/networking/rpc/l2/base_fee_vault.rs deleted file mode 100644 index 603db2bf559..00000000000 --- a/crates/l2/networking/rpc/l2/base_fee_vault.rs +++ /dev/null @@ -1,31 +0,0 @@ -use serde_json::Value; - -use crate::{ - rpc::{RpcApiContext, RpcHandler}, - utils::RpcErr, -}; - -pub struct GetBaseFeeVaultAddress; - -impl RpcHandler for GetBaseFeeVaultAddress { - fn parse(_params: &Option>) -> Result { - Ok(GetBaseFeeVaultAddress) - } - - async fn handle(&self, context: RpcApiContext) -> Result { - let base_fee_vault_address = match context.l1_ctx.blockchain.options.r#type { - ethrex_blockchain::BlockchainType::L1 => None, - ethrex_blockchain::BlockchainType::L2(fee_config) => fee_config.base_fee_vault, - }; - - Ok( - serde_json::to_value(base_fee_vault_address.map(|addr| format!("{:#x}", addr))) - .map_err(|e| { - ethrex_rpc::RpcErr::Internal(format!( - "Failed to serialize base fee vault address: {}", - e - )) - })?, - ) - } -} diff --git a/crates/l2/networking/rpc/l2/fees.rs b/crates/l2/networking/rpc/l2/fees.rs new file mode 100644 index 00000000000..d49b82d3c42 --- /dev/null +++ b/crates/l2/networking/rpc/l2/fees.rs @@ -0,0 +1,163 @@ +use serde_json::Value; +use tracing::debug; + +use crate::{ + rpc::{RpcApiContext, RpcHandler}, + utils::RpcErr, +}; + +pub struct GetBaseFeeVaultAddress { + pub block_number: u64, +} + +impl RpcHandler for GetBaseFeeVaultAddress { + fn parse(params: &Option>) -> Result { + let params = params.as_ref().ok_or(ethrex_rpc::RpcErr::BadParams( + "No params provided".to_owned(), + ))?; + if params.len() != 1 { + return Err(ethrex_rpc::RpcErr::BadParams( + "Expected 1 params".to_owned(), + ))?; + }; + // Parse BlockNumber + let hex_str = serde_json::from_value::(params[0].clone()) + .map_err(|e| ethrex_rpc::RpcErr::BadParams(e.to_string()))?; + + // Check that the BlockNumber is 0x prefixed + let hex_str = hex_str + .strip_prefix("0x") + .ok_or(ethrex_rpc::RpcErr::BadHexFormat(0))?; + + // Parse hex string + let block_number = + u64::from_str_radix(hex_str, 16).map_err(|_| ethrex_rpc::RpcErr::BadHexFormat(0))?; + + Ok(GetBaseFeeVaultAddress { block_number }) + } + + async fn handle(&self, context: RpcApiContext) -> Result { + debug!( + "Requested BaseFeeVault with block number: {}", + self.block_number + ); + let base_fee_vault_address = context + .rollup_store + .get_fee_config_by_block(self.block_number) + .await? + .and_then(|fc| fc.base_fee_vault); + + Ok( + serde_json::to_value(base_fee_vault_address.map(|addr| format!("{:#x}", addr))) + .map_err(|e| { + ethrex_rpc::RpcErr::Internal(format!( + "Failed to serialize base fee vault address: {}", + e + )) + })?, + ) + } +} + +pub struct GetOperatorFeeVaultAddress { + pub block_number: u64, +} + +impl RpcHandler for GetOperatorFeeVaultAddress { + fn parse(params: &Option>) -> Result { + let params = params.as_ref().ok_or(ethrex_rpc::RpcErr::BadParams( + "No params provided".to_owned(), + ))?; + if params.len() != 1 { + return Err(ethrex_rpc::RpcErr::BadParams( + "Expected 1 params".to_owned(), + ))?; + }; + // Parse BlockNumber + let hex_str = serde_json::from_value::(params[0].clone()) + .map_err(|e| ethrex_rpc::RpcErr::BadParams(e.to_string()))?; + + // Check that the BlockNumber is 0x prefixed + let hex_str = hex_str + .strip_prefix("0x") + .ok_or(ethrex_rpc::RpcErr::BadHexFormat(0))?; + + // Parse hex string + let block_number = + u64::from_str_radix(hex_str, 16).map_err(|_| ethrex_rpc::RpcErr::BadHexFormat(0))?; + + Ok(GetOperatorFeeVaultAddress { block_number }) + } + + async fn handle(&self, context: RpcApiContext) -> Result { + debug!( + "Requested OperatorFeeVault with block number: {}", + self.block_number + ); + let operator_fee_config = context + .rollup_store + .get_fee_config_by_block(self.block_number) + .await? + .and_then(|fc| fc.operator_fee_config); + + Ok(serde_json::to_value( + operator_fee_config.map(|config| format!("{:#x}", config.operator_fee_vault)), + ) + .map_err(|e| { + ethrex_rpc::RpcErr::Internal(format!( + "Failed to serialize base fee vault address: {}", + e + )) + })?) + } +} + +pub struct GetOperatorFee { + pub block_number: u64, +} + +impl RpcHandler for GetOperatorFee { + fn parse(params: &Option>) -> Result { + let params = params.as_ref().ok_or(ethrex_rpc::RpcErr::BadParams( + "No params provided".to_owned(), + ))?; + if params.len() != 1 { + return Err(ethrex_rpc::RpcErr::BadParams( + "Expected 1 params".to_owned(), + ))?; + }; + // Parse BlockNumber + let hex_str = serde_json::from_value::(params[0].clone()) + .map_err(|e| ethrex_rpc::RpcErr::BadParams(e.to_string()))?; + + // Check that the BlockNumber is 0x prefixed + let hex_str = hex_str + .strip_prefix("0x") + .ok_or(ethrex_rpc::RpcErr::BadHexFormat(0))?; + + // Parse hex string + let block_number = + u64::from_str_radix(hex_str, 16).map_err(|_| ethrex_rpc::RpcErr::BadHexFormat(0))?; + + Ok(GetOperatorFee { block_number }) + } + + async fn handle(&self, context: RpcApiContext) -> Result { + debug!( + "Requested OperatorFee with block number: {}", + self.block_number + ); + let operator_fee_config = context + .rollup_store + .get_fee_config_by_block(self.block_number) + .await? + .and_then(|fc| fc.operator_fee_config); + + Ok(serde_json::to_value( + operator_fee_config.map(|config| format!("{:#x}", config.operator_fee_vault)), + ) + .map_err(|e| { + ethrex_rpc::RpcErr::Internal(format!("Failed to serialize operator fee : {}", e)) + })?) + } +} diff --git a/crates/l2/networking/rpc/l2/mod.rs b/crates/l2/networking/rpc/l2/mod.rs index 4abd6634b21..7ee748e885a 100644 --- a/crates/l2/networking/rpc/l2/mod.rs +++ b/crates/l2/networking/rpc/l2/mod.rs @@ -1,4 +1,4 @@ -pub mod base_fee_vault; pub mod batch; +pub mod fees; pub mod l1_message; pub mod transaction; diff --git a/crates/l2/networking/rpc/rpc.rs b/crates/l2/networking/rpc/rpc.rs index 53e2df87e1b..aeeacc9ebea 100644 --- a/crates/l2/networking/rpc/rpc.rs +++ b/crates/l2/networking/rpc/rpc.rs @@ -1,5 +1,5 @@ -use crate::l2::base_fee_vault::GetBaseFeeVaultAddress; use crate::l2::batch::{BatchNumberRequest, GetBatchByBatchNumberRequest}; +use crate::l2::fees::{GetBaseFeeVaultAddress, GetOperatorFee, GetOperatorFeeVaultAddress}; use crate::l2::l1_message::GetL1MessageProof; use crate::utils::{RpcErr, RpcNamespace, resolve_namespace}; use axum::extract::State; @@ -217,7 +217,9 @@ pub async fn map_l2_requests(req: &RpcRequest, context: RpcApiContext) -> Result "ethrex_getMessageProof" => GetL1MessageProof::call(req, context).await, "ethrex_batchNumber" => BatchNumberRequest::call(req, context).await, "ethrex_getBatchByNumber" => GetBatchByBatchNumberRequest::call(req, context).await, - "ethrex_getFeeVaultAddress" => GetBaseFeeVaultAddress::call(req, context).await, + "ethrex_getBaseFeeVaultAddress" => GetBaseFeeVaultAddress::call(req, context).await, + "ethrex_getOperatorFeeVaultAddress" => GetOperatorFeeVaultAddress::call(req, context).await, + "ethrex_getOperatorFee" => GetOperatorFee::call(req, context).await, unknown_ethrex_l2_method => { Err(ethrex_rpc::RpcErr::MethodNotFound(unknown_ethrex_l2_method.to_owned()).into()) } diff --git a/crates/l2/storage/src/api.rs b/crates/l2/storage/src/api.rs index d16c0ff88ad..c654e763ed3 100644 --- a/crates/l2/storage/src/api.rs +++ b/crates/l2/storage/src/api.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use ethrex_common::{ H256, - types::{AccountUpdate, Blob, BlockNumber, batch::Batch}, + types::{AccountUpdate, Blob, BlockNumber, batch::Batch, fee_config::FeeConfig}, }; use ethrex_l2_common::prover::{BatchProof, ProverType}; @@ -147,4 +147,15 @@ pub trait StoreEngineRollup: Debug + Send + Sync { ) -> Result<(), RollupStoreError>; async fn revert_to_batch(&self, batch_number: u64) -> Result<(), RollupStoreError>; + + async fn store_fee_config_by_block( + &self, + block_number: BlockNumber, + fee_config: FeeConfig, + ) -> Result<(), RollupStoreError>; + + async fn get_fee_config_by_block( + &self, + block_number: BlockNumber, + ) -> Result, RollupStoreError>; } diff --git a/crates/l2/storage/src/store.rs b/crates/l2/storage/src/store.rs index 62df78a2a9a..1d155d5a031 100644 --- a/crates/l2/storage/src/store.rs +++ b/crates/l2/storage/src/store.rs @@ -7,7 +7,7 @@ use crate::store_db::in_memory::Store as InMemoryStore; use crate::store_db::sql::SQLStore; use ethrex_common::{ H256, - types::{AccountUpdate, Blob, BlobsBundle, BlockNumber, batch::Batch}, + types::{AccountUpdate, Blob, BlobsBundle, BlockNumber, batch::Batch, fee_config::FeeConfig}, }; use ethrex_l2_common::prover::{BatchProof, ProverType}; use tracing::info; @@ -355,4 +355,20 @@ impl Store { .delete_proof_by_batch_and_type(batch_number, proof_type) .await } + + pub async fn store_fee_config_by_block( + &self, + block_number: BlockNumber, + fee_config: FeeConfig, + ) -> Result<(), RollupStoreError> { + self.engine + .store_fee_config_by_block(block_number, fee_config) + .await + } + pub async fn get_fee_config_by_block( + &self, + block_number: BlockNumber, + ) -> Result, RollupStoreError> { + self.engine.get_fee_config_by_block(block_number).await + } } diff --git a/crates/l2/storage/src/store_db/in_memory.rs b/crates/l2/storage/src/store_db/in_memory.rs index b5cfeeeb9a9..f59713a05b8 100644 --- a/crates/l2/storage/src/store_db/in_memory.rs +++ b/crates/l2/storage/src/store_db/in_memory.rs @@ -7,7 +7,7 @@ use std::{ use crate::error::RollupStoreError; use ethrex_common::{ H256, - types::{AccountUpdate, Blob, BlockNumber, batch::Batch}, + types::{AccountUpdate, Blob, BlockNumber, batch::Batch, fee_config::FeeConfig}, }; use ethrex_l2_common::prover::{BatchProof, ProverType}; @@ -46,6 +46,8 @@ struct StoreInner { commit_txs: HashMap, /// Map of batch number to verify transaction hash verify_txs: HashMap, + /// Map of block number to FeeConfig + fee_config_by_block: HashMap, } impl Store { @@ -334,6 +336,28 @@ impl StoreEngineRollup for Store { async fn get_last_batch_number(&self) -> Result, RollupStoreError> { Ok(self.inner()?.state_roots.keys().max().cloned()) } + + async fn store_fee_config_by_block( + &self, + block_number: BlockNumber, + fee_config: FeeConfig, + ) -> Result<(), RollupStoreError> { + self.inner()? + .fee_config_by_block + .insert(block_number, fee_config); + Ok(()) + } + + async fn get_fee_config_by_block( + &self, + block_number: BlockNumber, + ) -> Result, RollupStoreError> { + Ok(self + .inner()? + .fee_config_by_block + .get(&block_number) + .cloned()) + } } impl Debug for Store { diff --git a/crates/l2/storage/src/store_db/sql.rs b/crates/l2/storage/src/store_db/sql.rs index 8c38a0b57b6..f83014ea0cc 100644 --- a/crates/l2/storage/src/store_db/sql.rs +++ b/crates/l2/storage/src/store_db/sql.rs @@ -4,7 +4,7 @@ use tokio::sync::Mutex; use crate::{RollupStoreError, api::StoreEngineRollup}; use ethrex_common::{ H256, - types::{AccountUpdate, Blob, BlockNumber, batch::Batch}, + types::{AccountUpdate, Blob, BlockNumber, batch::Batch, fee_config::FeeConfig}, }; use ethrex_l2_common::prover::{BatchProof, ProverType}; @@ -28,7 +28,7 @@ impl Debug for SQLStore { } } -const DB_SCHEMA: [&str; 15] = [ +const DB_SCHEMA: [&str; 16] = [ "CREATE TABLE blocks (block_number INT PRIMARY KEY, batch INT)", "CREATE TABLE messages (batch INT, idx INT, message_hash BLOB, PRIMARY KEY (batch, idx))", "CREATE TABLE privileged_transactions (batch INT PRIMARY KEY, transactions_hash BLOB)", @@ -44,6 +44,7 @@ const DB_SCHEMA: [&str; 15] = [ "CREATE TABLE batch_proofs (batch INT, prover_type INT, proof BLOB, PRIMARY KEY (batch, prover_type))", "CREATE TABLE block_signatures (block_hash BLOB PRIMARY KEY, signature BLOB)", "CREATE TABLE batch_signatures (batch INT PRIMARY KEY, signature BLOB)", + "CREATE TABLE fee_config (block_number INT PRIMARY KEY, fee_config BLOB)", ]; impl SQLStore { @@ -781,6 +782,43 @@ impl StoreEngineRollup for SQLStore { .map(|row| read_from_row_int(&row, 0)) .transpose() } + + async fn store_fee_config_by_block( + &self, + block_number: BlockNumber, + fee_config: FeeConfig, + ) -> Result<(), RollupStoreError> { + let serialized = bincode::serialize(&fee_config)?; + let queries = vec![ + ( + "DELETE FROM fee_config WHERE block_number = ?1", + vec![block_number].into_params()?, + ), + ( + "INSERT INTO fee_config VALUES (?1, ?2)", + (block_number, serialized).into_params()?, + ), + ]; + self.execute_in_tx(queries, None).await + } + + async fn get_fee_config_by_block( + &self, + block_number: BlockNumber, + ) -> Result, RollupStoreError> { + let mut rows = self + .query( + "SELECT fee_config FROM fee_config WHERE block_number = ?1", + vec![block_number], + ) + .await?; + + if let Some(row) = rows.next().await? { + let vec = read_from_row_blob(&row, 1)?; + return Ok(Some(bincode::deserialize(&vec)?)); + } + Ok(None) + } } #[cfg(test)] diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index 142dd649fba..b7e35199293 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -69,8 +69,12 @@ pub enum EthClientError { GenericTransactionError(#[from] GenericTransactionError), #[error("Failed to parse hex string: {0}")] FromStrRadixError(#[from] FromStrRadixErr), - #[error("ethrex_getFeeVaultAddress request error: {0}")] + #[error("ethrex_getBaseFeeVaultAddress request error: {0}")] GetBaseFeeVaultAddressError(#[from] GetBaseFeeVaultAddressError), + #[error("ethrex_getOperatorFeeVaultAddress request error: {0}")] + GetOperatorFeeVaultAddressError(#[from] GetOperatorFeeVaultAddressError), + #[error("ethrex_getOperatorFee request error: {0}")] + GetOperatorFeeError(#[from] GetOperatorFeeError), } #[derive(Debug, thiserror::Error)] @@ -312,3 +316,17 @@ pub enum GetBaseFeeVaultAddressError { #[error("{0}")] RPCError(String), } +#[derive(Debug, thiserror::Error)] +pub enum GetOperatorFeeVaultAddressError { + #[error("{0}")] + SerdeJSONError(#[from] serde_json::Error), + #[error("{0}")] + RPCError(String), +} +#[derive(Debug, thiserror::Error)] +pub enum GetOperatorFeeError { + #[error("{0}")] + SerdeJSONError(#[from] serde_json::Error), + #[error("{0}")] + RPCError(String), +} diff --git a/crates/networking/rpc/eth/gas_price.rs b/crates/networking/rpc/eth/gas_price.rs index 237264fb7ee..fa6637c07c6 100644 --- a/crates/networking/rpc/eth/gas_price.rs +++ b/crates/networking/rpc/eth/gas_price.rs @@ -1,5 +1,6 @@ use crate::rpc::{RpcApiContext, RpcHandler}; use crate::utils::RpcErr; +use ethrex_blockchain::BlockchainType; use serde_json::Value; // TODO: This does not need a struct, @@ -35,7 +36,14 @@ impl RpcHandler for GasPrice { .estimate_gas_tip(&context.storage) .await?; // To complete the gas price, we need to add the base fee to the estimated gas tip. - let gas_price = base_fee + estimated_gas_tip; + let mut gas_price = base_fee + estimated_gas_tip; + + // Add the operator fee to the gas price if configured + if let BlockchainType::L2(fee_config) = &context.blockchain.options.r#type + && let Some(operator_fee_config) = &fee_config.operator_fee_config + { + gas_price += operator_fee_config.operator_fee_per_gas; + } let gas_as_hex = format!("0x{gas_price:x}"); Ok(serde_json::Value::String(gas_as_hex)) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index debcc85aee9..dc043762785 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -84,14 +84,14 @@ impl LEVM { tx_sender: Address, block_header: &BlockHeader, db: &mut GeneralizedDatabase, + vm_type: VMType, ) -> Result { let chain_config = db.store.get_chain_config()?; - let gas_price: U256 = tx - .effective_gas_price(block_header.base_fee_per_gas) - .ok_or(VMError::TxValidation( - TxValidationError::InsufficientMaxFeePerGas, - ))? - .into(); + let gas_price: U256 = claculate_gas_price_for_tx( + tx, + block_header.base_fee_per_gas.unwrap_or_default(), + &vm_type, + )?; let config = EVMConfig::new_from_chain_config(&chain_config, block_header); let env = Environment { @@ -130,7 +130,7 @@ impl LEVM { db: &mut GeneralizedDatabase, vm_type: VMType, ) -> Result { - let env = Self::setup_env(tx, tx_sender, block_header, db)?; + let env = Self::setup_env(tx, tx_sender, block_header, db, vm_type)?; let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?; vm.execute().map_err(VMError::into) @@ -464,7 +464,7 @@ pub fn extract_all_requests_levm( /// Calculating gas_price according to EIP-1559 rules /// See https://github.com/ethereum/go-ethereum/blob/7ee9a6e89f59cee21b5852f5f6ffa2bcfc05a25f/internal/ethapi/transaction_args.go#L430 -pub fn calculate_gas_price(tx: &GenericTransaction, basefee: u64) -> U256 { +pub fn calculate_gas_price_for_generic(tx: &GenericTransaction, basefee: u64) -> U256 { if tx.gas_price != 0 { // Legacy gas field was specified, use it tx.gas_price.into() @@ -478,6 +478,35 @@ pub fn calculate_gas_price(tx: &GenericTransaction, basefee: u64) -> U256 { } } +pub fn claculate_gas_price_for_tx( + tx: &Transaction, + mut fee_per_gas: u64, + vm_type: &VMType, +) -> Result { + let Some(max_priority_fee) = tx.max_priority_fee() else { + // Legacy transaction + return Ok(tx.gas_price().into()); + }; + + let max_fee_per_gas = tx.max_fee_per_gas().ok_or(VMError::TxValidation( + TxValidationError::InsufficientMaxFeePerGas, + ))?; + + if let VMType::L2(fee_config) = vm_type + && let Some(operator_fee_config) = &fee_config.operator_fee_config + { + fee_per_gas += operator_fee_config.operator_fee_per_gas; + } + + if fee_per_gas > max_fee_per_gas { + return Err(VMError::TxValidation( + TxValidationError::InsufficientMaxFeePerGas, + )); + } + + Ok(min(max_priority_fee + fee_per_gas, max_fee_per_gas).into()) +} + /// When basefee tracking is disabled (ie. env.disable_base_fee = true; env.disable_block_gas_limit = true;) /// and no gas prices were specified, lower the basefee to 0 to avoid breaking EVM invariants (basefee < feecap) /// See https://github.com/ethereum/go-ethereum/blob/00294e9d28151122e955c7db4344f06724295ec5/core/vm/evm.go#L137 @@ -503,7 +532,8 @@ fn env_from_generic( db: &GeneralizedDatabase, ) -> Result { let chain_config = db.store.get_chain_config()?; - let gas_price = calculate_gas_price(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); + let gas_price = + calculate_gas_price_for_generic(tx, header.base_fee_per_gas.unwrap_or(INITIAL_BASE_FEE)); let config = EVMConfig::new_from_chain_config(&chain_config, header); Ok(Environment { origin: tx.from.0.into(), diff --git a/crates/vm/backends/levm/tracing.rs b/crates/vm/backends/levm/tracing.rs index 8ad2269645b..8a0fe0b9277 100644 --- a/crates/vm/backends/levm/tracing.rs +++ b/crates/vm/backends/levm/tracing.rs @@ -57,6 +57,7 @@ impl LEVM { })?, block_header, db, + vm_type, )?; let mut vm = VM::new( env, diff --git a/crates/vm/levm/src/hooks/l2_hook.rs b/crates/vm/levm/src/hooks/l2_hook.rs index ce3264cb126..b4ee1204408 100644 --- a/crates/vm/levm/src/hooks/l2_hook.rs +++ b/crates/vm/levm/src/hooks/l2_hook.rs @@ -1,6 +1,13 @@ use crate::{ errors::{ContextResult, InternalError, TxValidationError}, - hooks::{DefaultHook, default_hook, hook::Hook}, + hooks::{ + DefaultHook, + default_hook::{ + self, compute_actual_gas_used, compute_gas_refunded, delete_self_destruct_accounts, + pay_coinbase, refund_sender, undo_value_transfer, + }, + hook::Hook, + }, opcodes::Opcode, vm::VM, }; @@ -23,9 +30,12 @@ impl Hook for L2Hook { fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { DefaultHook.prepare_execution(vm)?; + // Different from L1: - // Operator fee is deducted from the sender before execution - deduct_operator_fee(vm, &self.fee_config.operator_fee_config)?; + + // Max fee per gas must be sufficient to cover base fee + operator fee + validate_sufficient_max_fee_per_gas_l2(vm, &self.fee_config.operator_fee_config)?; + return Ok(()); } @@ -116,14 +126,33 @@ impl Hook for L2Hook { ctx_result: &mut ContextResult, ) -> Result<(), crate::errors::VMError> { if !vm.env.is_privileged { - DefaultHook.finalize_execution(vm, ctx_result)?; + if !ctx_result.is_success() { + undo_value_transfer(vm)?; + } + + let gas_refunded: u64 = compute_gas_refunded(vm, ctx_result)?; + let actual_gas_used = compute_actual_gas_used(vm, gas_refunded, ctx_result.gas_used)?; + refund_sender(vm, ctx_result, gas_refunded, actual_gas_used)?; + + delete_self_destruct_accounts(vm)?; + // Different from L1: + pay_coinbase_l2( + vm, + ctx_result.gas_used, + &self.fee_config.operator_fee_config, + )?; + // Base fee is not burned pay_base_fee_vault(vm, ctx_result.gas_used, self.fee_config.base_fee_vault)?; // Operator fee is paid to the chain operator - pay_operator_fee(vm, self.fee_config.operator_fee_config)?; + pay_operator_fee( + vm, + ctx_result.gas_used, + &self.fee_config.operator_fee_config, + )?; return Ok(()); } @@ -140,18 +169,51 @@ impl Hook for L2Hook { } } -fn deduct_operator_fee( +fn validate_sufficient_max_fee_per_gas_l2( vm: &mut VM<'_>, operator_fee_config: &Option, +) -> Result<(), TxValidationError> { + let Some(fee_config) = operator_fee_config else { + // No operator fee configured, this check was done in default hook + return Ok(()); + }; + + let total_fee = vm + .env + .base_fee_per_gas + .checked_add(U256::from(fee_config.operator_fee_per_gas)) + .ok_or(TxValidationError::InsufficientMaxFeePerGas)?; + + if vm.env.tx_max_fee_per_gas.unwrap_or(vm.env.gas_price) < total_fee { + return Err(TxValidationError::InsufficientMaxFeePerGas); + } + Ok(()) +} + +fn pay_coinbase_l2( + vm: &mut VM<'_>, + gas_to_pay: u64, + operator_fee_config: &Option, ) -> Result<(), crate::errors::VMError> { let Some(fee_config) = operator_fee_config else { // No operator fee configured, operator fee is not paid - return Ok(()); + return pay_coinbase(vm, gas_to_pay); }; - let sender_address = vm.env.origin; - vm.decrease_account_balance(sender_address, fee_config.operator_fee_per_gas) - .map_err(|_| TxValidationError::InsufficientAccountFunds)?; + let priority_fee_per_gas = vm + .env + .gas_price + .checked_sub(vm.env.base_fee_per_gas) + .ok_or(InternalError::Underflow)? + .checked_sub(U256::from(fee_config.operator_fee_per_gas)) + .ok_or(InternalError::Underflow)?; + + let coinbase_fee = U256::from(gas_to_pay) + .checked_mul(priority_fee_per_gas) + .ok_or(InternalError::Overflow)?; + + vm.increase_account_balance(vm.env.coinbase, coinbase_fee)?; + Ok(()) } @@ -175,16 +237,18 @@ fn pay_base_fee_vault( fn pay_operator_fee( vm: &mut VM<'_>, - operator_fee_config: Option, + gas_to_pay: u64, + operator_fee_config: &Option, ) -> Result<(), crate::errors::VMError> { let Some(fee_config) = operator_fee_config else { // No operator fee configured, operator fee is not paid return Ok(()); }; - vm.increase_account_balance( - fee_config.operator_fee_vault, - fee_config.operator_fee_per_gas, - )?; + let operator_fee = U256::from(gas_to_pay) + .checked_mul(U256::from(fee_config.operator_fee_per_gas)) + .ok_or(InternalError::Overflow)?; + + vm.increase_account_balance(fee_config.operator_fee_vault, operator_fee)?; Ok(()) } diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 91d36411f65..73c898f5921 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -20,19 +20,29 @@ "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa", "blobSchedule": { "cancun": { - "target": 3, + "baseFeeUpdateFraction": 3338477, "max": 6, - "baseFeeUpdateFraction": 3338477 + "target": 3 }, "prague": { - "target": 6, + "baseFeeUpdateFraction": 5007716, "max": 9, - "baseFeeUpdateFraction": 5007716 + "target": 6 }, "osaka": { - "target": 6, + "baseFeeUpdateFraction": 5007716, "max": 9, - "baseFeeUpdateFraction": 5007716 + "target": 6 + }, + "bpo1": { + "baseFeeUpdateFraction": 8346193, + "max": 15, + "target": 10 + }, + "bpo2": { + "baseFeeUpdateFraction": 11684671, + "max": 21, + "target": 14 } }, "mergeNetsplitBlock": 0, @@ -53,13 +63,13 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea26469706673582212204396f246249f52e780861cf7c8e99ebc34211e11586f573a735d1178cc6f3e8664736f6c634300081d0033", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220ba047060ba3574875cd782f062d08240871ba803894074a664b4df16b994741164736f6c634300081d0033", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b80632f7fd3951461009757806351cff8d91461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b610196565b61011b565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f9103126100ba57565b6100ac565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6100df6100bf565b90565b60018060a01b031690565b6100f6906100e2565b90565b610102906100ed565b9052565b9190610119905f602085019401906100f9565b565b3461014b5761012b3660046100b0565b6101476101366100d7565b61013e6100a2565b91829182610106565b0390f35b6100a8565b610159816100ed565b0361016057565b5f80fd5b9050359061017182610150565b565b9060208282031261018c57610189915f01610164565b90565b6100ac565b5f0190565b6101a96101a4366004610173565b610710565b6101b16100a2565b806101bb81610191565b0390f35b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f8301610164565b9261022361020c8460208501610164565b9361021a8160408601610164565b936060016101d6565b90565b6100ac565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610191565b0390f35b6100a8565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610191565b0390f35b6100a8565b61fffe90565b6102a7610299565b90565b346102da576102ba3660046100b0565b6102d66102c561029f565b6102cd6100a2565b91829182610106565b0390f35b6100a8565b6102f26102ed366004610173565b610cf7565b6102fa6100a2565b8061030481610191565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610191565b0390f35b6100a8565b5f90565b61034b61033f565b90565b3461037e5761035e3660046100b0565b61037a610369610343565b6103716100a2565b91829182610106565b0390f35b6100a8565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100e2565b61038a565b6100e2565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100ed565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100ac565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610191565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de6100bf565b6108006107e96100bf565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100ed565b916100ed565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f8701906100f9565b60208501906100f9565b60408301906100f9565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100ed565b916100ed565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b6882610150565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100ac565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f8301906100f9565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610191565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100ed565b916100ed565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610106565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256", "storage": {}, "balance": "0x0", "nonce": "0x1" @@ -74,25 +84,25 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" }, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea26469706673582212203dcabd569808849d0e409a052e5e7d1fa1624dd221cdb5cd5d9cbed0d5bd521b64736f6c634300081d0033a2646970667358221220c9ee82b3796a8b1e888ae9b0f1244e703b889a0a49a1fc2f76e48ff4436c7a1564736f6c634300081d0033", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f0919061027f916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61025461002b823961025490f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356", "storage": {}, "balance": "0x0", "nonce": "0x1" @@ -110,4 +120,4 @@ "nonce": "0x1" } } -} +} \ No newline at end of file From 71290b6d22ca65ea7d4c0d547e1f5d8f3671f45d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 15 Oct 2025 19:30:18 -0300 Subject: [PATCH 72/88] Update tests --- crates/l2/networking/rpc/clients.rs | 13 ++-- crates/l2/networking/rpc/l2/fees.rs | 14 ++-- crates/l2/tests/tests.rs | 101 ++++++++++++---------------- fixtures/genesis/l2.json | 4 +- 4 files changed, 59 insertions(+), 73 deletions(-) diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index cb391a282f8..934cb985eb1 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -2,6 +2,7 @@ use crate::l2::batch::RpcBatch; use ethrex_common::Address; use ethrex_common::H256; use ethrex_l2_common::l1_messages::L1MessageProof; +use ethrex_rpc::types::block_identifier::BlockIdentifier; use ethrex_rpc::{ EthClient, clients::{ @@ -51,9 +52,9 @@ pub async fn get_batch_by_number( pub async fn get_base_fee_vault_address( client: &EthClient, - block_number: u64, + block: BlockIdentifier, ) -> Result { - let params = Some(vec![json!(format!("{block_number:#x}"))]); + let params = Some(vec![block.into()]); let request = RpcRequest::new("ethrex_getBaseFeeVaultAddress", params); match client.send_request(request).await? { @@ -68,9 +69,9 @@ pub async fn get_base_fee_vault_address( pub async fn get_operator_fee_vault_address( client: &EthClient, - block_number: u64, + block: BlockIdentifier, ) -> Result { - let params = Some(vec![json!(format!("{block_number:#x}"))]); + let params = Some(vec![block.into()]); let request = RpcRequest::new("ethrex_getOperatorFeeVaultAddress", params); match client.send_request(request).await? { @@ -85,9 +86,9 @@ pub async fn get_operator_fee_vault_address( pub async fn get_operator_fee( client: &EthClient, - block_number: u64, + block: BlockIdentifier, ) -> Result { - let params = Some(vec![json!(format!("{block_number:#x}"))]); + let params = Some(vec![block.into()]); let request = RpcRequest::new("ethrex_getOperatorFee", params); match client.send_request(request).await? { diff --git a/crates/l2/networking/rpc/l2/fees.rs b/crates/l2/networking/rpc/l2/fees.rs index d49b82d3c42..eb5136c783b 100644 --- a/crates/l2/networking/rpc/l2/fees.rs +++ b/crates/l2/networking/rpc/l2/fees.rs @@ -147,17 +147,15 @@ impl RpcHandler for GetOperatorFee { "Requested OperatorFee with block number: {}", self.block_number ); - let operator_fee_config = context + let operator_fee_per_gas = context .rollup_store .get_fee_config_by_block(self.block_number) .await? - .and_then(|fc| fc.operator_fee_config); + .and_then(|fc| fc.operator_fee_config) + .map(|config| config.operator_fee_per_gas) + .unwrap_or(0); - Ok(serde_json::to_value( - operator_fee_config.map(|config| format!("{:#x}", config.operator_fee_vault)), - ) - .map_err(|e| { - ethrex_rpc::RpcErr::Internal(format!("Failed to serialize operator fee : {}", e)) - })?) + let operator_fee_hex = format!("0x{operator_fee_per_gas:x}"); + Ok(serde_json::Value::String(operator_fee_hex)) } } diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 2bb89730fc1..ee4fb59b2f2 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -11,6 +11,7 @@ use ethrex_l2::sequencer::l1_watcher::PrivilegedTransactionData; use ethrex_l2_common::calldata::Value; use ethrex_l2_common::l1_messages::L1MessageProof; use ethrex_l2_common::utils::get_address_from_secret_key; +use ethrex_l2_rpc::clients::get_operator_fee; use ethrex_l2_rpc::signer::{LocalSigner, Signer}; use ethrex_l2_sdk::{ COMMON_BRIDGE_L2_ADDRESS, bridge_address, calldata::encode_calldata, claim_erc20withdraw, @@ -30,6 +31,7 @@ use ethrex_rpc::{ }; use hex::FromHexError; use secp256k1::SecretKey; +use std::cmp::min; use std::ops::{Add, AddAssign}; use std::{ fs::{File, read_to_string}, @@ -65,7 +67,6 @@ use tokio::task::JoinSet; /// INTEGRATION_TEST_WITHDRAW_VALUE: amount in wei to withdraw from the l2 back to the l1 from L1_RICH_WALLET_PRIVATE_KEY this will be done INTEGRATION_TEST_WITHDRAW_COUNT times /// INTEGRATION_TEST_WITHDRAW_COUNT: amount of withdraw transactions to send /// INTEGRATION_TEST_SKIP_TEST_TOTAL_ETH: if set the integration test will not check for total eth in the chain, only to be used if we don't know all the accounts that exist in l2 -/// INTEGRATION_TEST_OPERATOR_FEE_DISABLED: if set the integration test will assume the operator fee is 0, useful for local tests without operator fee set (based) const DEFAULT_L1_RPC: &str = "http://localhost:8545"; const DEFAULT_L2_RPC: &str = "http://localhost:1729"; @@ -137,7 +138,6 @@ async fn l2_integration_test() -> Result<(), Box> { let operator_fee_vault_balance_before_tests = l2_client .get_balance(operator_fee_vault(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; let mut set = JoinSet::new(); @@ -147,7 +147,6 @@ async fn l2_integration_test() -> Result<(), Box> { l2_client.clone(), private_keys.pop().unwrap(), private_keys.pop().unwrap(), - operator_fee, )); set.spawn(test_privileged_tx_with_contract_call( @@ -213,14 +212,14 @@ async fn l2_integration_test() -> Result<(), Box> { private_keys.pop().unwrap(), )); - let mut acc_priority_fees = U256::zero(); - let mut acc_base_fees = U256::zero(); - let mut acc_operator_fee = U256::zero(); + let mut acc_priority_fees = 0; + let mut acc_base_fees = 0; + let mut acc_operator_fee = 0; while let Some(res) = set.join_next().await { let fees_details = res??; acc_priority_fees += fees_details.priority_fees; acc_base_fees += fees_details.base_fees; - acc_operator_fee += fees_details.operator_fee; + acc_operator_fee += fees_details.operator_fees; } let coinbase_balance_after_tests = l2_client @@ -285,7 +284,6 @@ async fn l2_integration_test() -> Result<(), Box> { async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result { println!("Testing upgrade"); let bridge_owner_private_key = bridge_owner_private_key(); - let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; println!("test_upgrade: Downloading openzeppelin contracts"); let contracts_path = Path::new("contracts"); @@ -313,7 +311,6 @@ async fn test_upgrade(l1_client: EthClient, l2_client: EthClient) -> Result Result { let token_amount: U256 = U256::from(100); - let operator_fee = get_operator_fee(&l1_client, on_chain_proposer_address()).await?; let rich_wallet_signer: Signer = LocalSigner::new(rich_wallet_private_key).into(); let rich_address = rich_wallet_signer.address(); @@ -578,7 +570,6 @@ async fn test_erc20_roundtrip( &init_code_l2, &rich_wallet_private_key, "test_erc20_roundtrip", - operator_fee, ) .await?; @@ -650,7 +641,7 @@ async fn test_erc20_roundtrip( ) .await?; - let approve_fees = get_fees_details_l2(&approve_receipt, &l2_client, operator_fee).await; + let approve_fees = get_fees_details_l2(&approve_receipt, &l2_client).await; let withdraw_receipt = test_send( &l2_client, @@ -667,7 +658,7 @@ async fn test_erc20_roundtrip( ) .await?; - let withdraw_fees = get_fees_details_l2(&withdraw_receipt, &l2_client, operator_fee).await; + let withdraw_fees = get_fees_details_l2(&withdraw_receipt, &l2_client).await; let withdrawal_tx_hash = withdraw_receipt.tx_info.transaction_hash; assert_eq!( @@ -1305,7 +1296,6 @@ async fn test_transfer( l2_client: EthClient, transferer_private_key: SecretKey, returnerer_private_key: SecretKey, - operator_fee: U256, ) -> Result { println!("test_transfer: Transferring funds on L2"); let transferer_address = get_address_from_secret_key(&transferer_private_key).unwrap(); @@ -1320,7 +1310,6 @@ async fn test_transfer( &transferer_private_key, returner_address, transfer_value(), - operator_fee, "test_transfer", ) .await?; @@ -1338,7 +1327,6 @@ async fn test_transfer( &returnerer_private_key, transferer_address, return_amount, - operator_fee, "test_transfer", ) .await?; @@ -1512,7 +1500,6 @@ async fn perform_transfer( transferer_private_key: &SecretKey, transfer_recipient_address: Address, transfer_value: U256, - operator_fee: U256, test: &str, ) -> Result { let transferer_address = get_address_from_secret_key(transferer_private_key).unwrap(); @@ -1522,7 +1509,7 @@ async fn perform_transfer( .await?; assert!( - transferer_initial_l2_balance >= transfer_value + operator_fee, + transferer_initial_l2_balance >= transfer_value, "L2 transferer doesn't have enough balance to transfer" ); @@ -1533,7 +1520,7 @@ async fn perform_transfer( ) .await?; - let transfer_tx = ethrex_l2_sdk::transfer( + let transfer_tx_hash = ethrex_l2_sdk::transfer( transfer_value, transferer_address, transfer_recipient_address, @@ -1543,16 +1530,15 @@ async fn perform_transfer( .await?; let transfer_tx_receipt = - ethrex_l2_sdk::wait_for_transaction_receipt(transfer_tx, l2_client, 10000).await?; + ethrex_l2_sdk::wait_for_transaction_receipt(transfer_tx_hash, l2_client, 10000).await?; assert!( transfer_tx_receipt.receipt.status, "Transfer transaction failed" ); - let transfer_fees = get_fees_details_l2(&transfer_tx_receipt, l2_client, operator_fee).await; - let total_fees = - transfer_fees.base_fees + transfer_fees.priority_fees + transfer_fees.operator_fee; + let transfer_fees = get_fees_details_l2(&transfer_tx_receipt, l2_client).await; + let total_fees = transfer_fees.total(); println!("{test}: Checking balances on L2 after transfer"); @@ -1593,7 +1579,6 @@ async fn test_n_withdraws( native_token_l1_address: Address, ) -> Result<(), Box> { let native_token_is_eth = native_token_l1_address == Address::zero(); - let operator_fee = get_operator_fee(l1_client, on_chain_proposer_address()).await?; println!("test_n_withdraws: Withdrawing funds from L2 to L1"); let withdrawer_address = get_address_from_secret_key(withdrawer_private_key)?; let withdraw_value = std::env::var("INTEGRATION_TEST_WITHDRAW_VALUE") @@ -1684,7 +1669,7 @@ async fn test_n_withdraws( // Compute actual total L2 gas paid by the withdrawer from receipts let mut total_withdraw_fees_l2 = FeesDetails::default(); for receipt in &receipts { - total_withdraw_fees_l2 += get_fees_details_l2(receipt, l2_client, operator_fee).await; + total_withdraw_fees_l2 += get_fees_details_l2(receipt, l2_client).await; } // Now assert exact balance movement on L2: value + gas @@ -1741,7 +1726,7 @@ async fn test_n_withdraws( assert_eq!( operator_fee_vault_balance_after_withdrawal, - operator_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.operator_fee, + operator_fee_vault_balance_before_withdrawal + total_withdraw_fees_l2.operator_fees, "Coinbase balance didn't increase as expected after withdrawal" ); @@ -1917,7 +1902,6 @@ async fn test_deploy( init_code: &[u8], deployer_private_key: &SecretKey, test_name: &str, - operator_fee: U256, ) -> Result<(Address, FeesDetails)> { println!("{test_name}: Deploying contract on L2"); @@ -1943,13 +1927,13 @@ async fn test_deploy( "{test_name}: Deploy transaction failed" ); - let deploy_fees = get_fees_details_l2(&deploy_tx_receipt, l2_client, operator_fee).await; + let deploy_fees = get_fees_details_l2(&deploy_tx_receipt, l2_client).await; let deployer_balance_after_deploy = l2_client .get_balance(deployer.address(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let total_fees = deploy_fees.base_fees + deploy_fees.priority_fees + deploy_fees.operator_fee; + let total_fees = deploy_fees.base_fees + deploy_fees.priority_fees + deploy_fees.operator_fees; assert_eq!( deployer_balance_after_deploy, @@ -2080,14 +2064,14 @@ fn bridge_owner_private_key() -> SecretKey { #[derive(Debug, Default)] struct FeesDetails { - base_fees: U256, - priority_fees: U256, - operator_fee: U256, + base_fees: u64, + priority_fees: u64, + operator_fees: u64, } impl FeesDetails { - fn total(&self) -> U256 { - self.base_fees + self.priority_fees + self.operator_fee + fn total(&self) -> u64 { + self.base_fees + self.priority_fees + self.operator_fees } } @@ -2098,7 +2082,7 @@ impl Add for FeesDetails { Self { base_fees: self.base_fees + other.base_fees, priority_fees: self.priority_fees + other.priority_fees, - operator_fee: self.operator_fee + other.operator_fee, + operator_fees: self.operator_fees + other.operator_fees, } } } @@ -2107,18 +2091,19 @@ impl AddAssign for FeesDetails { fn add_assign(&mut self, other: Self) { self.base_fees += other.base_fees; self.priority_fees += other.priority_fees; - self.operator_fee += other.operator_fee; + self.operator_fees += other.operator_fees; } } -async fn get_fees_details_l2( - tx_receipt: &RpcReceipt, - l2_client: &EthClient, - operator_fee: U256, -) -> FeesDetails { +async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> FeesDetails { + let tx = l2_client + .get_transaction_by_hash(tx_receipt.tx_info.transaction_hash) + .await + .unwrap() + .unwrap(); let gas_used = tx_receipt.tx_info.gas_used; - let effective_gas_price = tx_receipt.tx_info.effective_gas_price; - let total_execution_fees: U256 = (effective_gas_price * gas_used).into(); + let max_fee_per_gas = tx.max_fee_per_gas; + let max_priority_fee_per_gas = tx.max_priority_fee_per_gas; let base_fee_per_gas = l2_client .get_block_by_number( @@ -2131,14 +2116,23 @@ async fn get_fees_details_l2( .base_fee_per_gas .unwrap(); - let base_fees: U256 = (base_fee_per_gas * gas_used).into(); + let operator_fee_per_gas = get_operator_fee( + l2_client, + BlockIdentifier::Number(tx_receipt.block_info.block_number), + ) + .await + .unwrap(); + + let priority_fees = + min(max_priority_fee_per_gas, max_fee_per_gas - base_fee_per_gas) * gas_used; - let priority_fees: U256 = total_execution_fees - base_fees; + let operator_fees = operator_fee_per_gas * gas_used; + let base_fees = base_fee_per_gas * gas_used; FeesDetails { base_fees, priority_fees, - operator_fee, + operator_fees, } } @@ -2379,10 +2373,3 @@ async fn wait_for_verified_proof( proof } - -async fn get_operator_fee(l1_client: &EthClient, proposer_address: Address) -> Result { - if std::env::var("INTEGRATION_TEST_OPERATOR_FEE_DISABLED").is_err() { - return Ok(ethrex_l2_sdk::get_operator_fee(l1_client, proposer_address).await?); - } - Ok(U256::zero()) -} diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 73c898f5921..2e381b591d9 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -77,8 +77,8 @@ "0x000000000000000000000000000000000000fffd": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffd", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffd" }, "balance": "0x0", "nonce": "0x1" From df3bb70384f063924811b9a4f246496fd14ede23 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 15 Oct 2025 19:48:06 -0300 Subject: [PATCH 73/88] Fix workflow linter --- .github/workflows/pr-main_l2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index d2eb1f9dd1a..f40745429a2 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -333,7 +333,7 @@ jobs: ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ ETHREX_PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ docker compose -f docker-compose.yaml -f docker-compose-l2-tdx.yaml up --detach --no-deps ethrex_l2 From a894ce99bee92932ec4b57db6edec6c2a1bb538f Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 15 Oct 2025 19:57:53 -0300 Subject: [PATCH 74/88] Fix clippy --- crates/vm/backends/levm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index dc043762785..e020df8b439 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -485,7 +485,7 @@ pub fn claculate_gas_price_for_tx( ) -> Result { let Some(max_priority_fee) = tx.max_priority_fee() else { // Legacy transaction - return Ok(tx.gas_price().into()); + return Ok(tx.gas_price()); }; let max_fee_per_gas = tx.max_fee_per_gas().ok_or(VMError::TxValidation( From c7bcf608e17d125c1ce9b9fd06ceab3e20efbbe7 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 15 Oct 2025 22:00:06 -0300 Subject: [PATCH 75/88] fix endpoint --- crates/l2/networking/rpc/clients.rs | 13 ++++++++----- crates/l2/tests/tests.rs | 4 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 934cb985eb1..29a01717d4f 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -1,7 +1,10 @@ use crate::l2::batch::RpcBatch; use ethrex_common::Address; use ethrex_common::H256; +use ethrex_common::U256; use ethrex_l2_common::l1_messages::L1MessageProof; +use ethrex_rpc::clients::eth::errors::GetOperatorFeeError; +use ethrex_rpc::clients::eth::errors::GetOperatorFeeVaultAddressError; use ethrex_rpc::types::block_identifier::BlockIdentifier; use ethrex_rpc::{ EthClient, @@ -76,10 +79,10 @@ pub async fn get_operator_fee_vault_address( match client.send_request(request).await? { RpcResponse::Success(result) => serde_json::from_value(result.result) - .map_err(GetBaseFeeVaultAddressError::SerdeJSONError) + .map_err(GetOperatorFeeVaultAddressError::SerdeJSONError) .map_err(EthClientError::from), RpcResponse::Error(error_response) => { - Err(GetBaseFeeVaultAddressError::RPCError(error_response.error.message).into()) + Err(GetOperatorFeeVaultAddressError::RPCError(error_response.error.message).into()) } } } @@ -87,16 +90,16 @@ pub async fn get_operator_fee_vault_address( pub async fn get_operator_fee( client: &EthClient, block: BlockIdentifier, -) -> Result { +) -> Result { let params = Some(vec![block.into()]); let request = RpcRequest::new("ethrex_getOperatorFee", params); match client.send_request(request).await? { RpcResponse::Success(result) => serde_json::from_value(result.result) - .map_err(GetBaseFeeVaultAddressError::SerdeJSONError) + .map_err(GetOperatorFeeError::SerdeJSONError) .map_err(EthClientError::from), RpcResponse::Error(error_response) => { - Err(GetBaseFeeVaultAddressError::RPCError(error_response.error.message).into()) + Err(GetOperatorFeeError::RPCError(error_response.error.message).into()) } } } diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index c63cf89abf0..9a34f64781e 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -2117,11 +2117,13 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> .base_fee_per_gas .unwrap(); - let operator_fee_per_gas = get_operator_fee( + let operator_fee_per_gas: u64 = get_operator_fee( l2_client, BlockIdentifier::Number(tx_receipt.block_info.block_number), ) .await + .unwrap() + .try_into() .unwrap(); let priority_fees = From e413c0650574206ad13489c624672bd192382d83 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 16 Oct 2025 00:12:46 -0300 Subject: [PATCH 76/88] Fix integration tests --- .github/workflows/pr-main_l2.yaml | 2 +- cmd/ethrex/l2/command.rs | 5 +---- cmd/ethrex/l2/initializers.rs | 21 ++++++++++++--------- cmd/ethrex/l2/options.rs | 4 ++-- crates/l2/based/block_fetcher.rs | 4 +++- crates/l2/sequencer/block_producer.rs | 14 +++++++++++++- crates/l2/storage/src/store_db/sql.rs | 2 +- crates/l2/tests/tests.rs | 14 ++++++++------ crates/networking/rpc/clients/eth/mod.rs | 3 ++- 9 files changed, 43 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index f40745429a2..cbb93fe8376 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -233,7 +233,7 @@ jobs: export ETHREX_BASED=true cd .. else - export ETHREX_BLOCK_PRODUCER_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 + export ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 fi diff --git a/cmd/ethrex/l2/command.rs b/cmd/ethrex/l2/command.rs index 984588ae02d..336d7a51083 100644 --- a/cmd/ethrex/l2/command.rs +++ b/cmd/ethrex/l2/command.rs @@ -348,10 +348,7 @@ impl Command { "Transaction {:#x} not found", log.transaction_hash ))?; - l2_blob_hashes.extend(tx.blob_versioned_hashes.ok_or_eyre(format!( - "Blobs not found in transaction {:#x}", - log.transaction_hash - ))?); + l2_blob_hashes.extend(tx.tx.blob_versioned_hashes()); } // Get blobs from block's slot and only keep L2 commitment's blobs diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index a2c3a706bd9..f92c44d670f 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -308,14 +308,17 @@ pub async fn get_operator_fee_config( .block_producer_opts .operator_fee_vault_address; - let operator_fee_config = - if let (Some(operator_fee_vault), Some(operator_fee_per_gas)) = (address, fee) { - Some(OperatorFeeConfig { - operator_fee_vault, - operator_fee_per_gas, - }) - } else { - None - }; + let operator_fee_config = if let (Some(operator_fee_vault), Some(operator_fee)) = (address, fee) + { + let operator_fee_per_gas = operator_fee + .try_into() + .map_err(|_| eyre::eyre!("Failed to convert operator_fee_per_gas to u64"))?; + Some(OperatorFeeConfig { + operator_fee_vault, + operator_fee_per_gas, + }) + } else { + None + }; Ok(operator_fee_config) } diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index a40e75aaf5b..39fcb54c333 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -3,7 +3,7 @@ use crate::{ utils::{self}, }; use clap::Parser; -use ethrex_common::{Address, types::DEFAULT_BUILDER_GAS_CEIL}; +use ethrex_common::{Address, U256, types::DEFAULT_BUILDER_GAS_CEIL}; use ethrex_l2::{ BasedConfig, BlockFetcherConfig, BlockProducerConfig, CommitterConfig, EthConfig, L1WatcherConfig, ProofCoordinatorConfig, SequencerConfig, StateUpdaterConfig, @@ -460,7 +460,7 @@ pub struct BlockProducerOptions { help_heading = "Block producer options", help = "Fee per gas that the operator will receive for each transaction included in a block." )] - pub operator_fee_per_gas: Option, + pub operator_fee_per_gas: Option, #[arg( long, default_value = "2", diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 15240974da6..4e808df829d 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -255,7 +255,9 @@ impl BlockFetcher { "Failed to get the receipt for transaction {:x}", batch_committed_log.transaction_hash )))? - .data; + .tx + .data() + .clone(); let batch = decode_batch_from_calldata(&batch_commit_tx_calldata)?; diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index 6affaf2d95e..3831b17b813 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -6,7 +6,7 @@ use std::{ use bytes::Bytes; use ethrex_blockchain::{ - Blockchain, + Blockchain, BlockchainType, error::ChainError, fork_choice::apply_fork_choice, payload::{BuildPayloadArgs, create_payload}, @@ -210,6 +210,7 @@ impl BlockProducer { let transactions_count = block.body.transactions.len(); let block_number = block.header.number; let block_hash = block.hash(); + self.store_fee_config_by_block(block.header.number).await?; self.blockchain .store_block(block, account_updates_list, execution_result) .await?; @@ -235,6 +236,17 @@ impl BlockProducer { Ok(()) } + async fn store_fee_config_by_block(&self, block_number: u64) -> Result<(), BlockProducerError> { + let BlockchainType::L2(fee_config) = self.blockchain.options.r#type else { + error!("Invalid blockchain type. Expected L2."); + return Err(BlockProducerError::Custom("Invalid blockchain type".into())); + }; + + self.rollup_store + .store_fee_config_by_block(block_number, fee_config) + .await?; + Ok(()) + } } impl GenServer for BlockProducer { diff --git a/crates/l2/storage/src/store_db/sql.rs b/crates/l2/storage/src/store_db/sql.rs index f83014ea0cc..badb8c41138 100644 --- a/crates/l2/storage/src/store_db/sql.rs +++ b/crates/l2/storage/src/store_db/sql.rs @@ -808,7 +808,7 @@ impl StoreEngineRollup for SQLStore { ) -> Result, RollupStoreError> { let mut rows = self .query( - "SELECT fee_config FROM fee_config WHERE block_number = ?1", + "SELECT * FROM fee_config WHERE block_number = ?1", vec![block_number], ) .await?; diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 9a34f64781e..85fbd34e4b7 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -1934,7 +1934,7 @@ async fn test_deploy( .get_balance(deployer.address(), BlockIdentifier::Tag(BlockTag::Latest)) .await?; - let total_fees = deploy_fees.base_fees + deploy_fees.priority_fees + deploy_fees.operator_fees; + let total_fees = deploy_fees.total(); assert_eq!( deployer_balance_after_deploy, @@ -2097,14 +2097,14 @@ impl AddAssign for FeesDetails { } async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> FeesDetails { - let tx = l2_client + let rpc_tx = l2_client .get_transaction_by_hash(tx_receipt.tx_info.transaction_hash) .await .unwrap() .unwrap(); let gas_used = tx_receipt.tx_info.gas_used; - let max_fee_per_gas = tx.max_fee_per_gas; - let max_priority_fee_per_gas = tx.max_priority_fee_per_gas; + let max_fee_per_gas = rpc_tx.tx.max_fee_per_gas().unwrap(); + let max_priority_fee_per_gas: u64 = rpc_tx.tx.max_priority_fee().unwrap().try_into().unwrap(); let base_fee_per_gas = l2_client .get_block_by_number( @@ -2126,8 +2126,10 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> .try_into() .unwrap(); - let priority_fees = - min(max_priority_fee_per_gas, max_fee_per_gas - base_fee_per_gas) * gas_used; + let priority_fees = min( + max_priority_fee_per_gas, + max_fee_per_gas - base_fee_per_gas - operator_fee_per_gas, + ) * gas_used; let operator_fees = operator_fee_per_gas * gas_used; let base_fees = base_fee_per_gas * gas_used; diff --git a/crates/networking/rpc/clients/eth/mod.rs b/crates/networking/rpc/clients/eth/mod.rs index d5595ce11df..9953203f52a 100644 --- a/crates/networking/rpc/clients/eth/mod.rs +++ b/crates/networking/rpc/clients/eth/mod.rs @@ -8,6 +8,7 @@ use crate::{ block::RpcBlock, block_identifier::BlockIdentifier, receipt::{RpcLog, RpcReceipt}, + transaction::RpcTransaction, }, utils::{RpcErrorResponse, RpcRequest, RpcSuccessResponse}, }; @@ -611,7 +612,7 @@ impl EthClient { pub async fn get_transaction_by_hash( &self, tx_hash: H256, - ) -> Result, EthClientError> { + ) -> Result, EthClientError> { let params = Some(vec![json!(format!("{tx_hash:#x}"))]); let request = RpcRequest::new("eth_getTransactionByHash", params); From df4dc98156803c6eb8d481b205c995ca9b63f07e Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 16 Oct 2025 00:51:29 -0300 Subject: [PATCH 77/88] Update docs --- docs/l2/fundamentals/transaction_fees.md | 73 ++++++++++++++++++------ 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/docs/l2/fundamentals/transaction_fees.md b/docs/l2/fundamentals/transaction_fees.md index e503d36249a..92a52328579 100644 --- a/docs/l2/fundamentals/transaction_fees.md +++ b/docs/l2/fundamentals/transaction_fees.md @@ -5,14 +5,16 @@ This page describes the different types of transaction fees that the Ethrex L2 r > [!NOTE] > Privileged transactions are exempt from all fees. -## Execution Fees +## Priority Fee -Execution fees consist of two components: **base fee** and **priority fee**. +The priority fee works exactly the same way as on Ethereum L1. +It is an additional tip paid by the transaction sender to incentivize the sequencer to prioritize the inclusion of their transaction. +The priority fee is always forwarded directly to the sequencer’s coinbase address. -### Base Fee +## Base Fee The base fee follows the same rules as the Ethereum L1 base fee. It adjusts dynamically depending on network congestion to ensure stable transaction pricing. -By default, base fees are burned. However a sequencer can configure a `base fee vault` address to receive the collected base fees instead of burning them. +By default, base fees are burned. However, a sequencer can configure a `base fee vault` address to receive the collected base fees instead of burning them. ```sh ethrex l2 --block-producer.base-fee-vault-address @@ -21,29 +23,23 @@ ethrex l2 --block-producer.base-fee-vault-address > [!CAUTION] > If the base fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. -### Priority Fee - -The priority fee works exactly the same way as on Ethereum L1. -It is an additional tip paid by the transaction sender to incentivize the sequencer to prioritize the inclusion of their transaction. The priority fee is always forwarded directly to the sequencer’s coinbase address. -## Operator Fees +## Operator Fee -Operator fees cover the operational costs of maintaining the L2 infrastructure. +The operator fee represents an additional per-gas cost charged by the sequencer to cover the operational costs of maintaining the L2 infrastructure. -Unlike execution fees, this amount is fixed and does not depend on gas usage, state changes, or network congestion. +This fee works similarly to the base fee — it is **multiplied by the gas used** for each transaction. All collected operator fees are deposited into a dedicated `operator fee vault` address. -The operator fee is specified during the contract deployment step. It is initialized in the `OnChainProposer` contract and used as a public input in batch verifications. - To set the operator fee amount: -``` -ethrex l2 deploy --operator-fee +```sh +ethrex l2 --block-producer.operator-fee ``` To set the operator fee vault address: -``` +```sh ethrex l2 --block-producer.operator-fee-vault-address ``` @@ -51,4 +47,49 @@ ethrex l2 --block-producer.operator-fee-vault-address If the operator fee vault and coinbase addresses are the same, its balance will change in a way that differs from the standard L1 behavior, which may break assumptions about EVM compatibility. +--- + +## Fee Calculation + +When executing a transaction, all gas-related fees are subject to the **`max_fee_per_gas`** value defined in the transaction. +This value acts as an absolute cap over the **sum of all fee components**. + +This means that the **effective priority fee** is capped to ensure the total does not exceed `max_fee_per_gas`. +Specifically: + +``` +effective_priority_fee_per_gas = min( + max_priority_fee_per_gas, + max_fee_per_gas - base_fee_per_gas - operator_fee_per_gas +) +``` + +Then, the total fees are calculated as: + +```sh +total_fees = (base_fee_per_gas + operator_fee_per_gas + priority_fee_per_gas) * gas_used +``` + +This behavior ensures that transaction senders **never pay more than `max_fee_per_gas * gas_used`**, even when the operator fee is enabled. + +> [!IMPORTANT] +> The current `effective_gas_price` field in the transaction receipt **does not include** the operator fee component. +> Therefore, `effective_gas_price * gas_used` will only reflect the **base + priority** portions of the total cost. + +> [!IMPORTANT] +> The `eth_gasPrice` RPC endpoint has been **modified** to include the `operator_fee_per_gas` value when the operator fee mechanism is active. +> This means that the value returned by `eth_gasPrice` corresponds to `base_fee_per_gas + operator_fee_per_gas + estimated_gas_tip`. + +## Useful RPC Methods + +The following custom RPC methods are available to query fee-related parameters directly from the L2 node. +Each method accepts a single argument: the **`block_number`** to query historical or current values. + +| Method Name | Description | Example | +|--------------|-------------|----------| +| `ethrex_getBaseFeeVaultAddress` | Returns the address configured to receive the **base fees** collected in the specified block. | ```ethrex_getBaseFeeVaultAddress {"block_number": 12345}``` | +| `ethrex_getOperatorFeeVaultAddress` | Returns the address configured as the **operator fee vault** in the specified block. | ```ethrex_getOperatorFeeVaultAddress {"block_number": 12345}``` | +| `ethrex_getOperatorFee` | Returns the **operator fee per gas** value active at the specified block. | ```ethrex_getOperatorFee {"block_number": 12345}``` | + + ## L1 Fees From 0fd9b2a588ded17ffa713008de3d2264b57e8e6d Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 16 Oct 2025 00:53:56 -0300 Subject: [PATCH 78/88] Correct env var --- .github/workflows/pr-main_l2.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index cbb93fe8376..811ed73c811 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -248,7 +248,7 @@ jobs: - name: Run test run: | if [ "${{ matrix.based }}" = true ]; then - export INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true + export INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK=true fi sudo chmod -R a+rw crates/l2 cd crates/l2 @@ -445,7 +445,7 @@ jobs: - name: Run test run: | cd crates/l2 - INTEGRATION_TEST_SKIP_FEE_VAULT_CHECK=true \ + INTEGRATION_TEST_SKIP_BASE_FEE_VAULT_CHECK=true \ PROPOSER_COINBASE_ADDRESS=0x0007a881CD95B1484fca47615B64803dad620C8d \ cargo test l2 --release -- --nocapture --test-threads=1 From 64be8db50814e1b67311f49129c211c22a5e4d6a Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 16 Oct 2025 10:37:31 -0300 Subject: [PATCH 79/88] Fix clippy --- crates/l2/tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/l2/tests/tests.rs b/crates/l2/tests/tests.rs index 85fbd34e4b7..e3d2bb62011 100644 --- a/crates/l2/tests/tests.rs +++ b/crates/l2/tests/tests.rs @@ -2104,7 +2104,7 @@ async fn get_fees_details_l2(tx_receipt: &RpcReceipt, l2_client: &EthClient) -> .unwrap(); let gas_used = tx_receipt.tx_info.gas_used; let max_fee_per_gas = rpc_tx.tx.max_fee_per_gas().unwrap(); - let max_priority_fee_per_gas: u64 = rpc_tx.tx.max_priority_fee().unwrap().try_into().unwrap(); + let max_priority_fee_per_gas: u64 = rpc_tx.tx.max_priority_fee().unwrap(); let base_fee_per_gas = l2_client .get_block_by_number( From 120698aff8c6db0fdb387df5ff182ed1f7f72e54 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 16 Oct 2025 13:26:53 -0300 Subject: [PATCH 80/88] Update prover to work with multiple fee configs --- .../prover/src/guest_program/src/execution.rs | 25 +++++++--- .../l2/prover/src/guest_program/src/input.rs | 6 +-- crates/l2/prover/src/prover.rs | 2 +- crates/l2/sequencer/proof_coordinator.rs | 33 +++++++------ crates/l2/tee/quote-gen/src/sender.rs | 2 +- fixtures/genesis/l2.json | 46 ++++++++----------- 6 files changed, 61 insertions(+), 53 deletions(-) diff --git a/crates/l2/prover/src/guest_program/src/execution.rs b/crates/l2/prover/src/guest_program/src/execution.rs index 34846b9c1c3..b50b52fe29d 100644 --- a/crates/l2/prover/src/guest_program/src/execution.rs +++ b/crates/l2/prover/src/guest_program/src/execution.rs @@ -101,7 +101,7 @@ pub fn execution_program(input: ProgramInput) -> Result Result, + fee_configs: Option>, blob_commitment: Commitment, blob_proof: Proof, chain_id: u64, @@ -178,7 +178,12 @@ pub fn stateless_validation_l2( nodes_hashed, codes_hashed, parent_block_header, - } = execute_stateless(blocks, execution_witness, elasticity_multiplier, fee_config)?; + } = execute_stateless( + blocks, + execution_witness, + elasticity_multiplier, + fee_configs, + )?; let (l1messages, privileged_transactions) = get_batch_l1messages_and_privileged_transactions(blocks, &receipts)?; @@ -262,7 +267,7 @@ fn execute_stateless( blocks: &[Block], execution_witness: ExecutionWitness, elasticity_multiplier: u64, - fee_config: Option, + fee_configs: Option>, ) -> Result { let guest_program_state: GuestProgramState = execution_witness .try_into() @@ -277,6 +282,8 @@ fn execute_stateless( let codes_hashed = guest_program_state.codes_hashed.clone(); #[cfg(feature = "l2")] let parent_block_header_clone = guest_program_state.parent_block_header.clone(); + #[cfg(feature = "l2")] + let fee_configs = fee_configs.ok_or_else(|| StatelessExecutionError::FeeConfigNotFound)?; let mut wrapped_db = GuestProgramStateWrapper::new(guest_program_state); let chain_config = wrapped_db.get_chain_config().map_err(|_| { @@ -316,7 +323,8 @@ fn execute_stateless( let mut acc_account_updates: HashMap = HashMap::new(); let mut acc_receipts = Vec::new(); let mut non_privileged_count = 0; - for block in blocks { + + for (i, block) in blocks.iter().enumerate() { // Validate the block validate_block( block, @@ -330,7 +338,10 @@ fn execute_stateless( #[cfg(feature = "l2")] let mut vm = Evm::new_for_l2( wrapped_db.clone(), - fee_config.ok_or_else(|| StatelessExecutionError::FeeConfigNotFound)?, + fee_configs + .get(i) + .cloned() + .ok_or_else(|| StatelessExecutionError::FeeConfigNotFound)?, )?; #[cfg(not(feature = "l2"))] let mut vm = Evm::new_for_l1(wrapped_db.clone()); diff --git a/crates/l2/prover/src/guest_program/src/input.rs b/crates/l2/prover/src/guest_program/src/input.rs index 31bb3989843..ae00592a4c3 100644 --- a/crates/l2/prover/src/guest_program/src/input.rs +++ b/crates/l2/prover/src/guest_program/src/input.rs @@ -18,8 +18,8 @@ pub struct ProgramInput { pub execution_witness: ExecutionWitness, /// value used to calculate base fee pub elasticity_multiplier: u64, - /// Configuration for L2 fees - pub fee_config: Option, + /// Configuration for L2 fees used for each block + pub fee_configs: Option>, #[cfg(feature = "l2")] /// KZG commitment to the blob data #[serde_as(as = "[_; 48]")] @@ -36,7 +36,7 @@ impl Default for ProgramInput { blocks: Default::default(), execution_witness: ExecutionWitness::default(), elasticity_multiplier: Default::default(), - fee_config: None, + fee_configs: None, #[cfg(feature = "l2")] blob_commitment: [0; 48], #[cfg(feature = "l2")] diff --git a/crates/l2/prover/src/prover.rs b/crates/l2/prover/src/prover.rs index 8894f3dcc98..246bd313bff 100644 --- a/crates/l2/prover/src/prover.rs +++ b/crates/l2/prover/src/prover.rs @@ -130,7 +130,7 @@ impl Prover { blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, - fee_config: Some(input.fee_config), + fee_configs: Some(input.fee_configs), }, })) } diff --git a/crates/l2/sequencer/proof_coordinator.rs b/crates/l2/sequencer/proof_coordinator.rs index c360e6eb3e6..f359908ecdd 100644 --- a/crates/l2/sequencer/proof_coordinator.rs +++ b/crates/l2/sequencer/proof_coordinator.rs @@ -5,7 +5,7 @@ use crate::{ BlockProducerConfig, CommitterConfig, EthConfig, ProofCoordinatorConfig, SequencerConfig, }; use bytes::Bytes; -use ethrex_blockchain::{Blockchain, BlockchainType}; +use ethrex_blockchain::Blockchain; use ethrex_common::types::BlobsBundle; use ethrex_common::types::block_execution_witness::ExecutionWitness; use ethrex_common::types::fee_config::FeeConfig; @@ -50,7 +50,7 @@ pub struct ProverInputData { #[cfg(feature = "l2")] #[serde_as(as = "[_; 48]")] pub blob_proof: blobs_bundle::Proof, - pub fee_config: FeeConfig, + pub fee_configs: Vec, } /// Enum for the ProverServer <--> ProverClient Communication Protocol. @@ -473,7 +473,9 @@ impl ProofCoordinator { ))); }; - let blocks = self.fetch_blocks(block_numbers).await?; + let (blocks, fee_configs) = self + .fetch_blocks_with_respective_fee_configs(block_numbers) + .await?; let witness = self .blockchain @@ -503,12 +505,6 @@ impl ProofCoordinator { debug!("Created prover input for batch {batch_number}"); - let BlockchainType::L2(fee_config) = self.blockchain.options.r#type else { - return Err(ProofCoordinatorError::InternalError( - "Invalid blockchain type, expected L2".to_string(), - )); - }; - Ok(ProverInputData { execution_witness: witness, blocks, @@ -517,15 +513,16 @@ impl ProofCoordinator { blob_commitment, #[cfg(feature = "l2")] blob_proof, - fee_config, + fee_configs, }) } - async fn fetch_blocks( + async fn fetch_blocks_with_respective_fee_configs( &mut self, block_numbers: Vec, - ) -> Result, ProofCoordinatorError> { + ) -> Result<(Vec, Vec), ProofCoordinatorError> { let mut blocks = vec![]; + let mut fee_configs = vec![]; for block_number in block_numbers { let header = self .store @@ -537,8 +534,18 @@ impl ProofCoordinator { .await? .ok_or(ProofCoordinatorError::StorageDataIsNone)?; blocks.push(Block::new(header, body)); + // Fetch the L1 fee per blob gas used for this block + let fee_config = self + .rollup_store + .get_fee_config_by_block(block_number) + .await? + .ok_or(ProofCoordinatorError::InternalError( + "L1 blob base fee not found".to_string(), + ))?; + + fee_configs.push(fee_config); } - Ok(blocks) + Ok((blocks, fee_configs)) } } diff --git a/crates/l2/tee/quote-gen/src/sender.rs b/crates/l2/tee/quote-gen/src/sender.rs index a26c83cb14e..756723e46a4 100644 --- a/crates/l2/tee/quote-gen/src/sender.rs +++ b/crates/l2/tee/quote-gen/src/sender.rs @@ -33,7 +33,7 @@ pub async fn get_batch(commit_hash: String) -> Result<(u64, ProgramInput), Strin blob_commitment: input.blob_commitment, #[cfg(feature = "l2")] blob_proof: input.blob_proof, - fee_config: Some(input.fee_config), + fee_configs: Some(input.fee_configs), }, )), _ => Err("No blocks to prove.".to_owned()), diff --git a/fixtures/genesis/l2.json b/fixtures/genesis/l2.json index 2e381b591d9..91d36411f65 100644 --- a/fixtures/genesis/l2.json +++ b/fixtures/genesis/l2.json @@ -20,29 +20,19 @@ "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa", "blobSchedule": { "cancun": { - "baseFeeUpdateFraction": 3338477, + "target": 3, "max": 6, - "target": 3 + "baseFeeUpdateFraction": 3338477 }, "prague": { - "baseFeeUpdateFraction": 5007716, + "target": 6, "max": 9, - "target": 6 + "baseFeeUpdateFraction": 5007716 }, "osaka": { - "baseFeeUpdateFraction": 5007716, + "target": 6, "max": 9, - "target": 6 - }, - "bpo1": { - "baseFeeUpdateFraction": 8346193, - "max": 15, - "target": 10 - }, - "bpo2": { - "baseFeeUpdateFraction": 11684671, - "max": 21, - "target": 14 + "baseFeeUpdateFraction": 5007716 } }, "mergeNetsplitBlock": 0, @@ -63,13 +53,13 @@ "nonce": "0x1" }, "0x000000000000000000000000000000000000effe": { - "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456", + "code": "0x60806040526004361015610013575b61016f565b61001d5f3561003b565b8062cffbe514610036576360206aab0361000e5761013a565b610098565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61005b8161004f565b0361006257565b5f80fd5b9050359061007382610052565b565b9060208282031261008e5761008b915f01610066565b90565b61004b565b5f0190565b346100c6576100b06100ab366004610075565b610299565b6100b8610041565b806100c281610093565b0390f35b610047565b5f9103126100d557565b61004b565b1c90565b90565b6100f19060086100f693026100da565b6100de565b90565b9061010491546100e1565b90565b6101125f5f906100f9565b90565b90565b61012190610115565b9052565b9190610138905f60208501940190610118565b565b3461016a5761014a3660046100cb565b610166610155610107565b61015d610041565b91829182610125565b0390f35b610047565b5f80fd5b90565b90565b61018d61018861019292610173565b610176565b610115565b90565b5f1c90565b6101a66101ab91610195565b6100de565b90565b6101b8905461019a565b90565b634e487b7160e01b5f52601160045260245ffd5b6101de6101e491939293610115565b92610115565b82018092116101ef57565b6101bb565b5f1b90565b906102055f19916101f4565b9181191691161790565b61022361021e61022892610115565b610176565b610115565b90565b90565b9061024361023e61024a9261020f565b61022b565b82546101f9565b9055565b60018060a01b031690565b61026d6102686102729261024e565b610176565b61024e565b90565b61027e90610259565b90565b61028a90610275565b90565b6102969061004f565b90565b6102bd6102b76102a96001610179565b6102b25f6101ae565b6101cf565b5f61022e565b33906102c85f6101ae565b906103056102ff6102f97f18d7b705344d616d1b61daa6a8ccfcf9f10c27ade007cc45cf870d1e121f1a9d95610281565b9261028d565b9261020f565b9261030e610041565b8061031881610093565b0390a456fea26469706673582212204396f246249f52e780861cf7c8e99ebc34211e11586f573a735d1178cc6f3e8664736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000efff": { - "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b80632f7fd3951461009757806351cff8d91461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b610196565b61011b565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f9103126100ba57565b6100ac565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b6100df6100bf565b90565b60018060a01b031690565b6100f6906100e2565b90565b610102906100ed565b9052565b9190610119905f602085019401906100f9565b565b3461014b5761012b3660046100b0565b6101476101366100d7565b61013e6100a2565b91829182610106565b0390f35b6100a8565b610159816100ed565b0361016057565b5f80fd5b9050359061017182610150565b565b9060208282031261018c57610189915f01610164565b90565b6100ac565b5f0190565b6101a96101a4366004610173565b610710565b6101b16100a2565b806101bb81610191565b0390f35b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f8301610164565b9261022361020c8460208501610164565b9361021a8160408601610164565b936060016101d6565b90565b6100ac565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610191565b0390f35b6100a8565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610191565b0390f35b6100a8565b61fffe90565b6102a7610299565b90565b346102da576102ba3660046100b0565b6102d66102c561029f565b6102cd6100a2565b91829182610106565b0390f35b6100a8565b6102f26102ed366004610173565b610cf7565b6102fa6100a2565b8061030481610191565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610191565b0390f35b6100a8565b5f90565b61034b61033f565b90565b3461037e5761035e3660046100b0565b61037a610369610343565b6103716100a2565b91829182610106565b0390f35b6100a8565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100e2565b61038a565b6100e2565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100ed565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100ac565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610191565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de6100bf565b6108006107e96100bf565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100ed565b916100ed565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f8701906100f9565b60208501906100f9565b60408301906100f9565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100ed565b916100ed565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b6882610150565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100ac565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f8301906100f9565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610191565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100ed565b916100ed565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610106565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256", + "code": "0x60806040526004361015610013575b610383565b61001d5f3561009c565b806351cff8d91461009757806358bc83371461009257806379204fe01461008d57806379c0cdef146100885780637e1233a914610083578063b0f4d3951461007e578063d23061db146100795763fccc28130361000e5761034e565b610308565b6102df565b6102aa565b610262565b61022b565b61018a565b610109565b60e01c90565b60405190565b5f80fd5b60018060a01b031690565b6100c0906100ac565b90565b6100cc816100b7565b036100d357565b5f80fd5b905035906100e4826100c3565b565b906020828203126100ff576100fc915f016100d7565b90565b6100a8565b5f0190565b61011c6101173660046100e6565b610710565b6101246100a2565b8061012e81610104565b0390f35b5f80fd5b5f91031261014057565b6100a8565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b610165610145565b90565b610171906100b7565b9052565b9190610188905f60208501940190610168565b565b346101ba5761019a366004610136565b6101b66101a561015d565b6101ad6100a2565b91829182610175565b0390f35b610132565b90565b6101cb816101bf565b036101d257565b5f80fd5b905035906101e3826101c2565b565b608081830312610226576101fb825f83016100d7565b9261022361020c84602085016100d7565b9361021a81604086016100d7565b936060016101d6565b90565b6100a8565b3461025d5761024761023e3660046101e5565b92919091610af7565b61024f6100a2565b8061025981610104565b0390f35b610132565b346102945761027e6102753660046101e5565b92919091610ce9565b6102866100a2565b8061029081610104565b0390f35b610132565b61fffe90565b6102a7610299565b90565b346102da576102ba366004610136565b6102d66102c561029f565b6102cd6100a2565b91829182610175565b0390f35b610132565b6102f26102ed3660046100e6565b610cf7565b6102fa6100a2565b8061030481610104565b0390f35b3461033a5761032461031b3660046101e5565b92919091610dfe565b61032c6100a2565b8061033681610104565b0390f35b610132565b5f90565b61034b61033f565b90565b3461037e5761035e366004610136565b61037a610369610343565b6103716100a2565b91829182610175565b0390f35b610132565b5f80fd5b90565b90565b6103a161039c6103a692610387565b61038a565b6101bf565b90565b60209181520190565b60207f7665000000000000000000000000000000000000000000000000000000000000917f5769746864726177616c20616d6f756e74206d75737420626520706f736974695f8201520152565b61040c60226040926103a9565b610415816103b2565b0190565b61042e9060208101905f8183039101526103ff565b90565b1561043857565b6104406100a2565b62461bcd60e51b81528061045660048201610419565b0390fd5b905090565b61046a5f809261045a565b0190565b6104779061045f565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906104a29061047a565b810190811067ffffffffffffffff8211176104bc57604052565b610484565b906104d46104cd6100a2565b9283610498565b565b67ffffffffffffffff81116104f4576104f060209161047a565b0190565b610484565b9061050b610506836104d6565b6104c1565b918252565b606090565b3d5f14610530576105253d6104f9565b903d5f602084013e5b565b610538610510565b9061052e565b5f7f4661696c656420746f206275726e204574686572000000000000000000000000910152565b61057260146020926103a9565b61057b8161053e565b0190565b6105949060208101905f818303910152610565565b90565b1561059e57565b6105a66100a2565b62461bcd60e51b8152806105bc6004820161057f565b0390fd5b6105d46105cf6105d9926100ac565b61038a565b6100ac565b90565b6105e5906105c0565b90565b6105f1906105dc565b90565b61060861060361060d926101bf565b61038a565b6101bf565b90565b610619906105c0565b90565b61062590610610565b90565b610631906105dc565b90565b60601b90565b61064390610634565b90565b61064f9061063a565b90565b61065e610663916100b7565b610646565b9052565b90565b61067661067b916101bf565b610667565b9052565b926106ac60146106b4946106a4828861069c60209b9a8399610652565b018092610652565b018092610652565b01809261066a565b0190565b60200190565b5190565b5f80fd5b60e01b90565b5f9103126106d657565b6100a8565b90565b6106e7906106db565b9052565b91906106fe905f602085019401906106de565b565b6107086100a2565b3d5f823e3d90fd5b61072c346107266107205f61038d565b916101bf565b11610431565b61075f5f8061073961033f565b346107426100a2565b908161074d8161046e565b03925af1610759610515565b50610597565b3381349061079f6107996107937fbb2689ff876f7ef453cf8865dde5ab10349d222e2e1383c5152fbdb083f02da2956105e8565b926105e8565b926105f4565b926107a86100a2565b806107b281610104565b0390a46107cd6107c86107c3610299565b61061c565b610628565b9062cffbe59061080f6107de610145565b6108006107e9610145565b9334906107f46100a2565b9586946020860161067f565b60208201810382520382610498565b61082161081b826106be565b916106b8565b20823b1561089557610852926108475f809461083b6100a2565b968795869485936106c6565b8352600483016106eb565b03925af1801561089057610864575b50565b610883905f3d8111610889575b61087b8183610498565b8101906106cc565b5f610861565b503d610871565b610700565b6106c2565b6108a3906105dc565b90565b60207f6520627269646765000000000000000000000000000000000000000000000000917f436f6d6d6f6e4272696467654c323a2063616c6c6572206973206e6f742074685f8201520152565b61090060286040926103a9565b610909816108a6565b0190565b6109229060208101905f8183039101526108f3565b90565b1561092c57565b6109346100a2565b62461bcd60e51b81528061094a6004820161090d565b0390fd5b9061097e9392916109793361097361096d6109683061089a565b6100b7565b916100b7565b14610925565b610a16565b565b63ffffffff1690565b63ffffffff60e01b1690565b6109a96109a46109ae92610980565b6106c6565b610989565b90565b6109ba906101bf565b9052565b6109f36109fa946109e96060949897956109df608086019a5f870190610168565b6020850190610168565b6040830190610168565b01906109b1565b565b151590565b9190610a14905f602085019401906109b1565b565b92919092610a855f80610a283061089a565b6004610a6c6379c0cdef610a5d88918b8d610a448d9293610995565b94610a4d6100a2565b97889660208801908152016109be565b60208201810382520382610498565b82602082019151925af1610a7e610515565b50156109fc565b610ae4575b92909192610adf610acd610ac7610ac17ff5353a2477e10b23280de25ca6cea55c17bb48000d8807ee631e514080e7fb4e946105e8565b946105e8565b946105e8565b94610ad66100a2565b91829182610a01565b0390a4565b610af2818584908692610f16565b610a8a565b90610b0393929161094e565b565b90610b35939291610b3033610b2a610b24610b1f3061089a565b6100b7565b916100b7565b14610925565b610bb6565b565b610b40906105c0565b90565b610b4c90610b37565b90565b610b58906105dc565b90565b90505190610b68826100c3565b565b90602082820312610b8357610b80915f01610b5b565b90565b6100a8565b15610b8f57565b5f80fd5b916020610bb4929493610bad60408201965f830190610168565b01906109b1565b565b90610bc090610b43565b610be46020610bce83610b4f565b63c2eeeebd90610bdc6100a2565b9384926106c6565b8252815f81610bf560048201610104565b03925af18015610ce457610c2c93610c27925f92610cac575b50610c1b610c21916100b7565b916100b7565b14610b88565b610b4f565b916318bf5077919092803b15610ca757610c595f8094610c64610c4d6100a2565b978896879586946106c6565b845260048401610b93565b03925af18015610ca257610c76575b50565b610c95905f3d8111610c9b575b610c8d8183610498565b8101906106cc565b5f610c73565b503d610c83565b610700565b6106c2565b610c21919250610cd5610c1b9160203d8111610cdd575b610ccd8183610498565b810190610b6a565b929150610c0e565b503d610cc3565b610700565b90610cf5939291610b05565b565b610d245f808334610d066100a2565b9081610d118161046e565b03925af1610d1d610515565b50156109fc565b610d6f575b3490610d6a610d587f85a190caa61692b36b63a55e069330d18ab9af179fed7a25c16a4262bc63b7d2926105e8565b92610d616100a2565b91829182610a01565b0390a2565b610d783061089a565b6351cff8d934919091908390803b15610df957610da85f93610db395610d9c6100a2565b968795869485936106c6565b835260048301610175565b03925af18015610df457610dc8575b50610d29565b610de7905f3d8111610ded575b610ddf8183610498565b8101906106cc565b5f610dc2565b503d610dd5565b610700565b6106c2565b929091610e1d82610e17610e115f61038d565b916101bf565b11610431565b610e2e610e2984610b43565b610b4f565b93632b8c49e3338496803b15610f1157610e5b5f8094610e66610e4f6100a2565b9b8c96879586946106c6565b845260048401610b93565b03925af1948515610f0c57610ede95610ee0575b50808483908592610ed2610ec0610eba610eb47f54538b93c6e9b3f518076db2d896122f653fac2bb32fa0b6bc75097b9f332e75946105e8565b946105e8565b946105e8565b94610ec96100a2565b91829182610a01565b0390a492909192610f16565b565b610eff905f3d8111610f05575b610ef78183610498565b8101906106cc565b5f610e7a565b503d610eed565b610700565b6106c2565b9190610f6290610f53610f37610f32610f2d610299565b61061c565b610628565b9562cffbe5959294610f476100a2565b9586946020860161067f565b60208201810382520382610498565b610f74610f6e826106be565b916106b8565b20823b15610fe857610fa592610f9a5f8094610f8e6100a2565b968795869485936106c6565b8352600483016106eb565b03925af18015610fe357610fb7575b50565b610fd6905f3d8111610fdc575b610fce8183610498565b8101906106cc565b5f610fb4565b503d610fc4565b610700565b6106c256fea2646970667358221220ba047060ba3574875cd782f062d08240871ba803894074a664b4df16b994741164736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" @@ -77,32 +67,32 @@ "0x000000000000000000000000000000000000fffd": { "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffd" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffd", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000fffe": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe" + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xeffe", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" }, "balance": "0x0", "nonce": "0x1" }, "0x000000000000000000000000000000000000ffff": { - "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef916105dc565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61060b565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61060b565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105ae6105a9836101d9565b6101c4565b918252565b3d5f146105ce576105c33d61059c565b903d5f602084013e5b565b6105d6610597565b906105cc565b5f80610608936105ea610597565b508390602081019051915af4906105ff6105b3565b90919091610613565b90565b90565b151590565b9061062790610620610597565b501561060e565b5f146106335750610697565b61063c82610356565b61064e6106485f61035d565b916100e6565b148061067c575b61065d575090565b610678905f918291639996b31560e01b8352600483016104b9565b0390fd5b50803b61069161068b5f61035d565b916100e6565b14610655565b6106a081610356565b6106b26106ac5f61035d565b916100e6565b115f146106c157602081519101fd5b5f63d6bda27560e01b8152806106d96004820161003b565b0390fd", + "code": "0x608060405261000c61000e565b005b610016610040565b565b60018060a01b031690565b61002c90610018565b90565b63ffffffff60e01b1690565b5f0190565b3361005a61005461004f6100c2565b610023565b91610023565b145f146100b35763ffffffff60e01b5f351661008561007f63278f794360e11b61002f565b9161002f565b14155f146100a9575f6334ad5dbb60e21b8152806100a56004820161003b565b0390fd5b6100b16102d9565b565b6100d6565b5f90565b61f00090565b6100ca6100b8565b506100d36100bc565b90565b6100de610318565b61032c565b90565b90565b90565b6101006100fb610105926100e3565b6100e9565b6100e6565b90565b60405190565b5f80fd5b5f80fd5b90939293848311610136578411610131576001820201920390565b610112565b61010e565b91565b5f80fd5b5f80fd5b61014f90610018565b90565b61015b81610146565b0361016257565b5f80fd5b9050359061017382610152565b565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101a59061017d565b810190811067ffffffffffffffff8211176101bf57604052565b610187565b906101d76101d0610108565b928361019b565b565b67ffffffffffffffff81116101f7576101f360209161017d565b0190565b610187565b90825f939282370152565b9092919261021c610217826101d9565b6101c4565b9381855260208501908284011161023857610236926101fc565b565b610179565b9080601f8301121561025b5781602061025893359101610207565b90565b610175565b9190916040818403126102a057610279835f8301610166565b92602082013567ffffffffffffffff811161029b57610298920161023d565b90565b610142565b61013e565b6102b96102b46102be92610018565b6100e9565b610018565b90565b6102ca906102a5565b90565b6102d6906102c1565b90565b61031661031161030a6103026102fc5f366102f460046100ec565b908092610116565b9061013b565b810190610260565b91906102cd565b610379565b565b6103206100b8565b50610329610486565b90565b5f8091368280378136915af43d5f803e5f14610346573d5ff35b3d5ffd5b610353906102c1565b90565b5190565b90565b61037161036c6103769261035a565b6100e9565b6100e6565b90565b906103838261050c565b816103ae7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9161034a565b906103b7610108565b806103c18161003b565b0390a26103cd81610356565b6103df6103d95f61035d565b916100e6565b115f146103f3576103ef9161059c565b505b565b50506103fd610561565b6103f1565b90565b90565b5f1b90565b61042161041c61042692610402565b610408565b610405565b90565b6104527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61040d565b90565b5f1c90565b60018060a01b031690565b61047161047691610455565b61045a565b90565b6104839054610465565b90565b61048e6100b8565b506104a95f6104a361049e610429565b61066f565b01610479565b90565b6104b590610023565b9052565b91906104cc905f602085019401906104ac565b565b906104df60018060a01b0391610408565b9181191691161790565b90565b906105016104fc6105089261034a565b6104e9565b82546104ce565b9055565b803b61052061051a5f61035d565b916100e6565b1461054257610540905f61053a610535610429565b61066f565b016104ec565b565b61055d905f918291634c9c8ce360e01b8352600483016104b9565b0390fd5b3461057461056e5f61035d565b916100e6565b1161057b57565b5f63b398979f60e01b8152806105936004820161003b565b0390fd5b606090565b906105b0906105a9610597565b5082610676565b808061062c575b5f146105ca5750506105c76106ab565b90565b5f146105ef576105eb905f918291639996b31560e01b8352600483016104b9565b0390fd5b6105f7610693565b6106096106035f61035d565b916100e6565b115f036106a0575f63d6bda27560e01b8152806106286004820161003b565b0390fd5b50610635610693565b6106476106415f61035d565b916100e6565b118015610654575b6105b7565b50813b6106696106635f61035d565b916100e6565b1161064f565b90565b5f90565b5f918291610682610672565b50602082519201905af490565b5f90565b61069b61068f565b503d90565b6040513d5f823e3d90fd5b6106b3610597565b50604051903d82523d5f602084013e3d602001820160405256fea2646970667358221220da9f1f29d0ed5131ce1f37bb5f2d1b5c6de637a513f4e6d4cc498b2391c0f6e564736f6c634300081d0033", "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000" + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0xf000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xefff" }, "balance": "0x0", "nonce": "0x1" }, "0x13b0d85ccb8bf860b6b79af3029fca081ae9bef2": { - "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f0919061027f916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61025461002b823961025490f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356", + "code": "0x60806040526004361015610015575b366105b157005b61001f5f356100be565b8063076c37b2146100b95780633f4ba83a146100b4578063481286e6146100af57806356299481146100aa5780635c975abb146100a557806366cfa057146100a0578063715018a61461009b5780638456cb59146100965780638da5cb5b146100915763f2fde38b0361000e5761057e565b61052b565b6104f8565b6104c5565b610491565b610320565b6102c3565b610230565b610197565b610154565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b90565b6100e2816100d6565b036100e957565b5f80fd5b905035906100fa826100d9565b565b90565b610108816100fc565b0361010f57565b5f80fd5b90503590610120826100ff565b565b919060408382031261014a578061013e610147925f86016100ed565b93602001610113565b90565b6100ce565b5f0190565b346101835761016d610167366004610122565b906105f3565b6101756100c4565b8061017f8161014f565b0390f35b6100ca565b5f91031261019257565b6100ce565b346101c5576101a7366004610188565b6101af61061b565b6101b76100c4565b806101c18161014f565b0390f35b6100ca565b91906040838203126101f257806101e66101ef925f8601610113565b93602001610113565b90565b6100ce565b60018060a01b031690565b61020b906101f7565b90565b61021790610202565b9052565b919061022e905f6020850194019061020e565b565b346102615761025d61024c6102463660046101ca565b90610629565b6102546100c4565b9182918261021b565b0390f35b6100ca565b61026f81610202565b0361027657565b5f80fd5b9050359061028782610266565b565b90916060828403126102be576102bb6102a4845f8501610113565b936102b28160208601610113565b9360400161027a565b90565b6100ce565b346102f4576102f06102df6102d9366004610289565b9161063f565b6102e76100c4565b9182918261021b565b0390f35b6100ca565b151590565b610307906102f9565b9052565b919061031e905f602085019401906102fe565b565b3461035057610330366004610188565b61034c61033b610689565b6103436100c4565b9182918261030b565b0390f35b6100ca565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103859061035d565b810190811067ffffffffffffffff82111761039f57604052565b610367565b906103b76103b06100c4565b928361037b565b565b67ffffffffffffffff81116103d7576103d360209161035d565b0190565b610367565b90825f939282370152565b909291926103fc6103f7826103b9565b6103a4565b9381855260208501908284011161041857610416926103dc565b565b610359565b9080601f8301121561043b57816020610438933591016103e7565b90565b610355565b9160608383031261048c57610457825f85016100ed565b926104658360208301610113565b92604082013567ffffffffffffffff811161048757610484920161041d565b90565b6100d2565b6100ce565b346104c0576104aa6104a4366004610440565b916106c3565b6104b26100c4565b806104bc8161014f565b0390f35b6100ca565b346104f3576104d5366004610188565b6104dd610723565b6104e56100c4565b806104ef8161014f565b0390f35b6100ca565b3461052657610508366004610188565b610510610749565b6105186100c4565b806105228161014f565b0390f35b6100ca565b3461055b5761053b366004610188565b610557610546610784565b61054e6100c4565b9182918261021b565b0390f35b6100ca565b9060208282031261057957610576915f0161027a565b90565b6100ce565b346105ac57610596610591366004610560565b61088d565b61059e6100c4565b806105a88161014f565b0390f35b6100ca565b5f80fd5b906105c7916105c261091a565b6105c9565b565b906105f091906102b5916105df602084016103a4565b92808452610efd6020850139610b0e565b50565b906105fd916105b5565b565b610607610c16565b61060f610611565b565b610619610cef565b565b6106236105ff565b565b5f90565b9061063c91610636610625565b50610cf9565b90565b916106559261064c610625565b50919091610d1a565b90565b5f90565b60a01c90565b60ff1690565b6106746106799161065c565b610662565b90565b6106869054610668565b90565b610691610658565b5061069b5f61067c565b90565b906106b192916106ac61091a565b6106b3565b565b916106c092919091610b0e565b50565b906106ce929161069e565b565b6106d8610c16565b6106e0610710565b565b90565b90565b6106fc6106f7610701926106e2565b6106e5565b6101f7565b90565b61070d906106e8565b90565b61072161071c5f610704565b610d92565b565b61072b6106d0565b565b610735610c16565b61073d61073f565b565b610747610e51565b565b61075161072d565b565b5f1c90565b60018060a01b031690565b61076f61077491610753565b610758565b90565b6107819054610763565b90565b61078c610625565b506107965f610777565b90565b6107aa906107a5610c16565b61085d565b565b60209181520190565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b61080f60266040926107ac565b610818816107b5565b0190565b6108319060208101905f818303910152610802565b90565b1561083b57565b6108436100c4565b62461bcd60e51b8152806108596004820161081c565b0390fd5b61088b906108868161087f6108796108745f610704565b610202565b91610202565b1415610834565b610d92565b565b61089690610799565b565b5f7f5061757361626c653a2070617573656400000000000000000000000000000000910152565b6108cc60106020926107ac565b6108d581610898565b0190565b6108ee9060208101905f8183039101526108bf565b90565b156108f857565b6109006100c4565b62461bcd60e51b815280610916600482016108d9565b0390fd5b61093361092e610928610689565b156102f9565b6108f1565b565b61094961094461094e926101f7565b6106e5565b6101f7565b90565b61095a90610935565b90565b61096690610951565b90565b5f7f437265617465323a20696e73756666696369656e742062616c616e6365000000910152565b61099d601d6020926107ac565b6109a681610969565b0190565b6109bf9060208101905f818303910152610990565b90565b156109c957565b6109d16100c4565b62461bcd60e51b8152806109e7600482016109aa565b0390fd5b5190565b610a036109fe610a08926106e2565b6106e5565b6100d6565b90565b5f7f437265617465323a2062797465636f6465206c656e677468206973207a65726f910152565b610a3e602080926107ac565b610a4781610a0b565b0190565b610a609060208101905f818303910152610a32565b90565b15610a6a57565b610a726100c4565b62461bcd60e51b815280610a8860048201610a4b565b0390fd5b5f7f437265617465323a204661696c6564206f6e206465706c6f7900000000000000910152565b610ac060196020926107ac565b610ac981610a8c565b0190565b610ae29060208101905f818303910152610ab3565b90565b15610aec57565b610af46100c4565b62461bcd60e51b815280610b0a60048201610acd565b0390fd5b919091610b19610625565b50610b40610b263061095d565b31610b39610b33846100d6565b916100d6565b10156109c2565b610b65610b4c836109eb565b610b5e610b585f6109ef565b916100d6565b1415610a63565b60208251920190f590610b9382610b8c610b86610b815f610704565b610202565b91610202565b1415610ae5565b565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b610bc8602080926107ac565b610bd181610b95565b0190565b610bea9060208101905f818303910152610bbc565b90565b15610bf457565b610bfc6100c4565b62461bcd60e51b815280610c1260048201610bd5565b0390fd5b610c40610c21610784565b610c3a610c34610c2f610e5b565b610202565b91610202565b14610bed565b565b610c4a610eea565b610c52610ca2565b565b60a01b90565b90610c6960ff60a01b91610c54565b9181191691161790565b610c7c906102f9565b90565b90565b90610c97610c92610c9e92610c73565b610c7f565b8254610c5a565b9055565b610cac5f5f610c82565b610cb4610e5b565b610cea7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa91610ce16100c4565b9182918261021b565b0390a1565b610cf7610c42565b565b90610d1791610d06610625565b5090610d113061095d565b91610d1a565b90565b90605592600b92610d29610625565b50604051926040840152602083015281520160ff81532090565b5f1b90565b90610d5960018060a01b0391610d43565b9181191691161790565b610d6c90610951565b90565b90565b90610d87610d82610d8e92610d63565b610d6f565b8254610d48565b9055565b610d9b5f610777565b610da5825f610d72565b90610dd9610dd37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610d63565b91610d63565b91610de26100c4565b80610dec8161014f565b0390a3565b610df961091a565b610e01610e03565b565b610e0e60015f610c82565b610e16610e5b565b610e4c7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25891610e436100c4565b9182918261021b565b0390a1565b610e59610df1565b565b610e63610625565b503390565b5f7f5061757361626c653a206e6f7420706175736564000000000000000000000000910152565b610e9c60146020926107ac565b610ea581610e68565b0190565b610ebe9060208101905f818303910152610e8f565b90565b15610ec857565b610ed06100c4565b62461bcd60e51b815280610ee660048201610ea9565b0390fd5b610efa610ef5610689565b610ec1565b56fe608060405234601c57600e6020565b61028a61002b823961028a90f35b6026565b60405190565b5f80fdfe60806040526004361015610013575b610125565b61001d5f3561002c565b63249cb3fa0361000e576100ef565b60e01c90565b60405190565b5f80fd5b5f80fd5b90565b61004c81610040565b0361005357565b5f80fd5b9050359061006482610043565b565b60018060a01b031690565b61007a90610066565b90565b61008681610071565b0361008d57565b5f80fd5b9050359061009e8261007d565b565b91906040838203126100c857806100bc6100c5925f8601610057565b93602001610091565b90565b61003c565b6100d690610040565b9052565b91906100ed905f602085019401906100cd565b565b346101205761011c61010b6101053660046100a0565b90610210565b610113610032565b918291826100da565b0390f35b610038565b5f80fd5b5f90565b61013690610040565b90565b906101439061012d565b5f5260205260405f2090565b90565b61016661016161016b92610066565b61014f565b610066565b90565b61017790610152565b90565b6101839061016e565b90565b906101909061017a565b5f5260205260405f2090565b5f1c90565b60ff1690565b6101b36101b89161019c565b6101a1565b90565b6101c590546101a7565b90565b90565b5f1b90565b6101e46101df6101e9926101c8565b6101cb565b610040565b90565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b490565b6102349161022a61022f92610223610129565b505f610139565b610186565b6101bb565b5f14610246576102426101ec565b5b90565b61024f5f6101d0565b61024356fea26469706673582212203dcabd569808849d0e409a052e5e7d1fa1624dd221cdb5cd5d9cbed0d5bd521b64736f6c634300081d0033a2646970667358221220c9ee82b3796a8b1e888ae9b0f1244e703b889a0a49a1fc2f76e48ff4436c7a1564736f6c634300081d0033", "storage": {}, "balance": "0x0", "nonce": "0x1" @@ -120,4 +110,4 @@ "nonce": "0x1" } } -} \ No newline at end of file +} From 121f052478004466a5fe75365e3485f893c694d7 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Fri, 17 Oct 2025 10:27:20 -0300 Subject: [PATCH 81/88] Fix typo --- crates/vm/backends/levm/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index e020df8b439..a72bef38344 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -87,7 +87,7 @@ impl LEVM { vm_type: VMType, ) -> Result { let chain_config = db.store.get_chain_config()?; - let gas_price: U256 = claculate_gas_price_for_tx( + let gas_price: U256 = calculate_gas_price_for_tx( tx, block_header.base_fee_per_gas.unwrap_or_default(), &vm_type, @@ -478,7 +478,7 @@ pub fn calculate_gas_price_for_generic(tx: &GenericTransaction, basefee: u64) -> } } -pub fn claculate_gas_price_for_tx( +pub fn calculate_gas_price_for_tx( tx: &Transaction, mut fee_per_gas: u64, vm_type: &VMType, From 6bb86e82a1cb28a4216728356cad02d99b996393 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Wed, 22 Oct 2025 12:13:56 -0300 Subject: [PATCH 82/88] Remove GetTransactionByHashTransaction --- crates/networking/rpc/clients/eth/mod.rs | 100 +---------------------- 1 file changed, 3 insertions(+), 97 deletions(-) diff --git a/crates/networking/rpc/clients/eth/mod.rs b/crates/networking/rpc/clients/eth/mod.rs index 9953203f52a..08996a540aa 100644 --- a/crates/networking/rpc/clients/eth/mod.rs +++ b/crates/networking/rpc/clients/eth/mod.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, fmt}; +use std::collections::BTreeMap; use crate::{ clients::eth::errors::{CallError, GetPeerCountError, GetWitnessError, TxPoolContentError}, @@ -21,12 +21,12 @@ use errors::{ }; use ethrex_common::{ Address, H256, U256, - types::{BlobsBundle, Block, GenericTransaction, TxKind, TxType}, + types::{BlobsBundle, Block, GenericTransaction, TxKind}, utils::decode_hex, }; use ethrex_rlp::decode::RLPDecode; use reqwest::{Client, Url}; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use serde_json::{Value, json}; use tracing::{debug, trace, warn}; @@ -685,97 +685,3 @@ impl EthClient { map } } - -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct GetTransactionByHashTransaction { - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub chain_id: u64, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub nonce: u64, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub max_priority_fee_per_gas: u64, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub max_fee_per_gas: u64, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub gas_limit: u64, - #[serde(default)] - pub to: Address, - #[serde(default)] - pub value: U256, - #[serde(default, with = "ethrex_common::serde_utils::vec_u8", alias = "input")] - pub data: Vec, - #[serde(default)] - pub access_list: Vec<(Address, Vec)>, - #[serde(default)] - pub r#type: TxType, - #[serde(default)] - pub signature_y_parity: bool, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub signature_r: u64, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub signature_s: u64, - #[serde(default)] - pub block_number: U256, - #[serde(default)] - pub block_hash: H256, - #[serde(default)] - pub from: Address, - #[serde(default)] - pub hash: H256, - #[serde(default, with = "ethrex_common::serde_utils::u64::hex_str")] - pub transaction_index: u64, - #[serde(default)] - pub blob_versioned_hashes: Option>, -} - -impl fmt::Display for GetTransactionByHashTransaction { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - r#" -chain_id: {}, -nonce: {}, -max_priority_fee_per_gas: {}, -max_fee_per_gas: {}, -gas_limit: {}, -to: {:#x}, -value: {}, -data: {:#?}, -access_list: {:#?}, -type: {:?}, -signature_y_parity: {}, -signature_r: {:x}, -signature_s: {:x}, -block_number: {}, -block_hash: {:#x}, -from: {:#x}, -hash: {:#x}, -transaction_index: {}"#, - self.chain_id, - self.nonce, - self.max_priority_fee_per_gas, - self.max_fee_per_gas, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - self.r#type, - self.signature_y_parity, - self.signature_r, - self.signature_s, - self.block_number, - self.block_hash, - self.from, - self.hash, - self.transaction_index, - )?; - - if let Some(blob_versioned_hashes) = &self.blob_versioned_hashes { - write!(f, "\nblob_versioned_hashes: {blob_versioned_hashes:#?}")?; - } - - fmt::Result::Ok(()) - } -} From 4c76c1ab101f220cbfd70ff5bfacb6a23baea318 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 10:25:38 -0300 Subject: [PATCH 83/88] Change operator fee to u64 --- .github/workflows/main_prover.yaml | 2 +- .github/workflows/pr-main_l2.yaml | 4 ++-- cmd/ethrex/l2/initializers.rs | 21 +++++++++------------ cmd/ethrex/l2/options.rs | 8 ++++---- crates/l2/Makefile | 2 +- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.github/workflows/main_prover.yaml b/.github/workflows/main_prover.yaml index 8c9b2078cea..8ec581de538 100644 --- a/.github/workflows/main_prover.yaml +++ b/.github/workflows/main_prover.yaml @@ -88,7 +88,7 @@ jobs: ETHREX_WATCHER_WATCH_INTERVAL=1000 \ ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=1000000000 \ docker compose up --build --detach --no-deps ethrex_l2 - name: Copy env to host diff --git a/.github/workflows/pr-main_l2.yaml b/.github/workflows/pr-main_l2.yaml index cd5d80a8297..e6456137c9e 100644 --- a/.github/workflows/pr-main_l2.yaml +++ b/.github/workflows/pr-main_l2.yaml @@ -283,7 +283,7 @@ jobs: else export ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 - export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 + export ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=1000000000 fi cd crates/l2 DOCKER_ETHREX_WORKDIR=/usr/local/bin \ @@ -392,7 +392,7 @@ jobs: ETHREX_COMMITTER_COMMIT_TIME=15000 \ ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \ ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \ - ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=0x3B9ACA00 \ + ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=1000000000 \ ETHREX_PROOF_COORDINATOR_ADDRESS=0.0.0.0 \ docker compose -f docker-compose.yaml -f docker-compose-l2-tdx.yaml up --detach --no-deps ethrex_l2 diff --git a/cmd/ethrex/l2/initializers.rs b/cmd/ethrex/l2/initializers.rs index 022df7a44d8..746e9b0256b 100644 --- a/cmd/ethrex/l2/initializers.rs +++ b/cmd/ethrex/l2/initializers.rs @@ -308,17 +308,14 @@ pub async fn get_operator_fee_config( .block_producer_opts .operator_fee_vault_address; - let operator_fee_config = if let (Some(operator_fee_vault), Some(operator_fee)) = (address, fee) - { - let operator_fee_per_gas = operator_fee - .try_into() - .map_err(|_| eyre::eyre!("Failed to convert operator_fee_per_gas to u64"))?; - Some(OperatorFeeConfig { - operator_fee_vault, - operator_fee_per_gas, - }) - } else { - None - }; + let operator_fee_config = + if let (Some(operator_fee_vault), Some(operator_fee_per_gas)) = (address, fee) { + Some(OperatorFeeConfig { + operator_fee_vault, + operator_fee_per_gas, + }) + } else { + None + }; Ok(operator_fee_config) } diff --git a/cmd/ethrex/l2/options.rs b/cmd/ethrex/l2/options.rs index 39fcb54c333..83b79b07dc6 100644 --- a/cmd/ethrex/l2/options.rs +++ b/cmd/ethrex/l2/options.rs @@ -3,7 +3,7 @@ use crate::{ utils::{self}, }; use clap::Parser; -use ethrex_common::{Address, U256, types::DEFAULT_BUILDER_GAS_CEIL}; +use ethrex_common::{Address, types::DEFAULT_BUILDER_GAS_CEIL}; use ethrex_l2::{ BasedConfig, BlockFetcherConfig, BlockProducerConfig, CommitterConfig, EthConfig, L1WatcherConfig, ProofCoordinatorConfig, SequencerConfig, StateUpdaterConfig, @@ -454,13 +454,13 @@ pub struct BlockProducerOptions { pub operator_fee_vault_address: Option
, #[arg( long, - value_name = "UINT256", + value_name = "UINT64", env = "ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS", requires = "operator_fee_vault_address", help_heading = "Block producer options", - help = "Fee per gas that the operator will receive for each transaction included in a block." + help = "Fee that the operator will receive for each unit of gas consumed in a block." )] - pub operator_fee_per_gas: Option, + pub operator_fee_per_gas: Option, #[arg( long, default_value = "2", diff --git a/crates/l2/Makefile b/crates/l2/Makefile index 60dbb96680d..7e1e9fcece6 100644 --- a/crates/l2/Makefile +++ b/crates/l2/Makefile @@ -45,7 +45,7 @@ L1_AUTH_PORT=8551 L1_RPC_ADDRESS=0.0.0.0 L2_RPC_ADDRESS=0.0.0.0 PROOF_COORDINATOR_ADDRESS?=127.0.0.1 -ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS?=0x3B9ACA00 \ +ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS?=1000000000 \ # Matches the ports used by the blockchain/metrics dir L2_PROMETHEUS_METRICS_PORT = 3702 From 16d007546aa06e37c3cc69b2385c384b653ab0b0 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 10:29:40 -0300 Subject: [PATCH 84/88] Remove clone --- crates/l2/based/block_fetcher.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index 4e808df829d..dae7c453bb2 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -247,7 +247,7 @@ impl BlockFetcher { missing_batches_logs.sort_by_key(|(_log, batch_number)| *batch_number); for (batch_committed_log, batch_number) in missing_batches_logs { - let batch_commit_tx_calldata = self + let tx = self .eth_client .get_transaction_by_hash(batch_committed_log.transaction_hash) .await? @@ -255,11 +255,9 @@ impl BlockFetcher { "Failed to get the receipt for transaction {:x}", batch_committed_log.transaction_hash )))? - .tx - .data() - .clone(); + .tx; - let batch = decode_batch_from_calldata(&batch_commit_tx_calldata)?; + let batch = decode_batch_from_calldata(&tx.data())?; self.store_batch(&batch).await?; From 8822d684086cd0db2b14bb1581cc24379ec44180 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 10:55:05 -0300 Subject: [PATCH 85/88] Improve operator fee disable --- crates/l2/based/block_fetcher.rs | 2 +- crates/vm/backends/levm/mod.rs | 32 ++++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index dae7c453bb2..50235ac9b60 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -257,7 +257,7 @@ impl BlockFetcher { )))? .tx; - let batch = decode_batch_from_calldata(&tx.data())?; + let batch = decode_batch_from_calldata(tx.data())?; self.store_batch(&batch).await?; diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index a72bef38344..e7bf4e22600 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -8,6 +8,7 @@ use crate::system_contracts::{ }; use crate::{EvmError, ExecutionResult}; use bytes::Bytes; +use ethrex_common::types::fee_config::FeeConfig; use ethrex_common::{ Address, U256, types::{ @@ -147,15 +148,15 @@ impl LEVM { // The block header for the current block. block_header: &BlockHeader, db: &mut GeneralizedDatabase, - mut vm_type: VMType, + vm_type: VMType, ) -> Result { let mut env = env_from_generic(tx, block_header, db)?; env.block_gas_limit = i64::MAX as u64; // disable block gas limit - adjust_disabled_base_fee(&mut env, &mut vm_type); + adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(tx, env, db, vm_type)?; + let mut vm = vm_from_generic(tx, env.clone(), db, vm_type)?; vm.execute() .map(|value| value.into()) @@ -297,11 +298,11 @@ impl LEVM { mut tx: GenericTransaction, header: &BlockHeader, db: &mut GeneralizedDatabase, - mut vm_type: VMType, + vm_type: VMType, ) -> Result<(ExecutionResult, AccessList), VMError> { let mut env = env_from_generic(&tx, header, db)?; - adjust_disabled_base_fee(&mut env, &mut vm_type); + adjust_disabled_base_fee(&mut env); let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; @@ -510,13 +511,9 @@ pub fn calculate_gas_price_for_tx( /// When basefee tracking is disabled (ie. env.disable_base_fee = true; env.disable_block_gas_limit = true;) /// and no gas prices were specified, lower the basefee to 0 to avoid breaking EVM invariants (basefee < feecap) /// See https://github.com/ethereum/go-ethereum/blob/00294e9d28151122e955c7db4344f06724295ec5/core/vm/evm.go#L137 -fn adjust_disabled_base_fee(env: &mut Environment, vm_type: &mut VMType) { +fn adjust_disabled_base_fee(env: &mut Environment) { if env.gas_price == U256::zero() { env.base_fee_per_gas = U256::zero(); - if let VMType::L2(fee_config) = vm_type { - // Don't deduct operator fee if no gas price is set - fee_config.operator_fee_config = None; - } } if env .tx_max_fee_per_blob_gas @@ -526,6 +523,20 @@ fn adjust_disabled_base_fee(env: &mut Environment, vm_type: &mut VMType) { } } +/// When operator fee is disabled (ie. env.gas_price = 0), set operator fee to None to avoid breaking EVM invariants. +fn adjust_disabled_operator_fee(env: &Environment, vm_type: VMType) -> VMType { + if env.gas_price == U256::zero() + && let VMType::L2(fee_config) = vm_type + { + // Don't deduct operator fee if no gas price is set + return VMType::L2(FeeConfig { + operator_fee_config: None, + ..fee_config + }); + } + vm_type +} + fn env_from_generic( tx: &GenericTransaction, header: &BlockHeader, @@ -598,5 +609,6 @@ fn vm_from_generic<'a>( ..Default::default() }), }; + let vm_type = adjust_disabled_operator_fee(&env, vm_type); VM::new(env, db, &tx, LevmCallTracer::disabled(), vm_type) } From 15769333892aa39ce5a79c7b449f71c2cd64ea09 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 11:01:43 -0300 Subject: [PATCH 86/88] Remove unneeded clone --- crates/vm/backends/levm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index e7bf4e22600..4401de483f3 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -156,7 +156,7 @@ impl LEVM { adjust_disabled_base_fee(&mut env); - let mut vm = vm_from_generic(tx, env.clone(), db, vm_type)?; + let mut vm = vm_from_generic(tx, env, db, vm_type)?; vm.execute() .map(|value| value.into()) From 42416cd400745acaac8a33daf6ba68c9088cb5a5 Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 12:58:08 -0300 Subject: [PATCH 87/88] Remove unneeded clone --- crates/vm/backends/levm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 4401de483f3..70a794be4fa 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -310,7 +310,7 @@ impl LEVM { // Execute the tx again, now with the created access list. tx.access_list = vm.substate.make_access_list(); - let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; + let mut vm = vm_from_generic(&tx, env, db, vm_type)?; let report = vm.stateless_execute()?; From 2ccc6729dedc8ca97d0eaf0368e561b7bd82b22b Mon Sep 17 00:00:00 2001 From: avilagaston9 Date: Thu, 23 Oct 2025 14:20:59 -0300 Subject: [PATCH 88/88] Update cli.md --- docs/CLI.md | 138 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 42 deletions(-) diff --git a/docs/CLI.md b/docs/CLI.md index 5ff7a9aefcd..3dc58f33926 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -142,7 +142,7 @@ Block building options: --builder.extra-data Block extra data message. - [default: "ethrex 4.0.0"] + [default: "ethrex 5.0.0"] --builder.gas-limit Target block gas limit. @@ -172,11 +172,11 @@ Commands: Options: -t, --tick-rate time in ms between two ticks - + [default: 1000] --batch-widget-height - + -h, --help Print help (see a summary with '-h') @@ -184,12 +184,12 @@ Options: Node options: --network Alternatively, the name of a known network can be provided instead to use its preset genesis file and include its preset bootnodes. The networks currently supported include holesky, sepolia, hoodi and mainnet. If not specified, defaults to mainnet. - + [env: ETHREX_NETWORK=] --datadir If the datadir is the word `memory`, ethrex will use the `InMemory Engine`. - + [env: ETHREX_DATADIR=] [default: "/home/runner/.local/share/ethrex"] @@ -211,63 +211,106 @@ Node options: --log.level Possible values: info, debug, trace, warn, error - + [default: INFO] + --mempool.maxsize + Maximum size of the mempool in number of transactions + + [default: 10000] + P2P options: --bootnodes ... Comma separated enode URLs for P2P discovery bootstrap. --syncmode - Can be either "full" or "snap" with "full" as default value. - - [default: full] + Can be either "full" or "snap" with "snap" as default value. + + [default: snap] --p2p.enabled - + --p2p.port TCP port for P2P protocol. - + [default: 30303] --discovery.port UDP port for P2P discovery. - + [default: 30303] + --p2p.tx-broadcasting-interval + Transaction Broadcasting Time Interval (ms) for batching transactions before broadcasting them. + + [default: 1000] + + --target.peers + Max amount of connected peers. + + [default: 100] + RPC options: --http.addr
Listening address for the http rpc server. - + [env: ETHREX_HTTP_ADDR=] [default: 0.0.0.0] --http.port Listening port for the http rpc server. - + [env: ETHREX_HTTP_PORT=] [default: 8545] + --ws.enabled + Enable websocket rpc server. Disabled by default. + + [env: ETHREX_ENABLE_WS=] + + --ws.addr
+ Listening address for the websocket rpc server. + + [env: ETHREX_WS_ADDR=] + [default: 0.0.0.0] + + --ws.port + Listening port for the websocket rpc server. + + [env: ETHREX_WS_PORT=] + [default: 8546] + --authrpc.addr
Listening address for the authenticated rpc server. - + [default: 127.0.0.1] --authrpc.port Listening port for the authenticated rpc server. - + [default: 8551] --authrpc.jwtsecret Receives the jwt secret used for authenticated rpc requests. - + [default: jwt.hex] +Block building options: + --builder.extra-data + Block extra data message. + + [default: "ethrex 5.0.0"] + + --builder.gas-limit + Target block gas limit. + + [default: 30000000] + Eth options: --eth.rpc-url ... List of rpc urls to use. - + [env: ETHREX_ETH_RPC_URL=] --eth.maximum-allowed-max-fee-per-gas @@ -300,7 +343,7 @@ L1 Watcher options: --watcher.watch-interval How often the L1 watcher checks for new blocks in milliseconds. - + [env: ETHREX_WATCHER_WATCH_INTERVAL=] [default: 12000] @@ -310,14 +353,14 @@ L1 Watcher options: --watcher.block-delay Number of blocks the L1 watcher waits before trusting an L1 block. - + [env: ETHREX_WATCHER_BLOCK_DELAY=] [default: 10] Block producer options: --block-producer.block-time How often does the sequencer produce new blocks to the L1 in milliseconds. - + [env: ETHREX_BLOCK_PRODUCER_BLOCK_TIME=] [default: 5000] @@ -326,13 +369,18 @@ Block producer options: --block-producer.base-fee-vault-address
[env: ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=] - + --block-producer.operator-fee-vault-address
[env: ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=] + --operator-fee-per-gas + Fee that the operator will receive for each unit of gas consumed in a block. + + [env: ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=] + --block-producer.block-gas-limit Maximum gas limit for the L2 blocks. - + [env: ETHREX_BLOCK_PRODUCER_BLOCK_GAS_LIMIT=] [default: 30000000] @@ -344,17 +392,17 @@ Proposer options: L1 Committer options: --committer.l1-private-key Private key of a funded account that the sequencer will use to send commit txs to the L1. - + [env: ETHREX_COMMITTER_L1_PRIVATE_KEY=] --committer.remote-signer-url URL of a Web3Signer-compatible server to remote sign instead of a local private key. - + [env: ETHREX_COMMITTER_REMOTE_SIGNER_URL=] --committer.remote-signer-public-key Public key to request the remote signature from. - + [env: ETHREX_COMMITTER_REMOTE_SIGNER_PUBLIC_KEY=] --l1.on-chain-proposer-address
@@ -362,18 +410,18 @@ L1 Committer options: --committer.commit-time How often does the sequencer commit new blocks to the L1 in milliseconds. - + [env: ETHREX_COMMITTER_COMMIT_TIME=] [default: 60000] --committer.batch-gas-limit Maximum gas limit for the batch - + [env: ETHREX_COMMITTER_BATCH_GAS_LIMIT=] --committer.first-wake-up-time Time to wait before the sequencer seals a batch when started. After committing the first batch, `committer.commit-time` will be used. - + [env: ETHREX_COMMITTER_FIRST_WAKE_UP_TIME=] --committer.arbitrary-base-blob-gas-price @@ -383,27 +431,33 @@ L1 Committer options: Proof coordinator options: --proof-coordinator.l1-private-key Private key of of a funded account that the sequencer will use to send verify txs to the L1. Has to be a different account than --committer-l1-private-key. - + [env: ETHREX_PROOF_COORDINATOR_L1_PRIVATE_KEY=] --proof-coordinator.tdx-private-key Private key of of a funded account that the TDX tool that will use to send the tdx attestation to L1. - + [env: ETHREX_PROOF_COORDINATOR_TDX_PRIVATE_KEY=] + --proof-coordinator.qpl-tool-path + Path to the QPL tool that will be used to generate TDX quotes. + + [env: ETHREX_PROOF_COORDINATOR_QPL_TOOL_PATH=] + [default: ./tee/contracts/automata-dcap-qpl/automata-dcap-qpl-tool/target/release/automata-dcap-qpl-tool] + --proof-coordinator.remote-signer-url URL of a Web3Signer-compatible server to remote sign instead of a local private key. - + [env: ETHREX_PROOF_COORDINATOR_REMOTE_SIGNER_URL=] --proof-coordinator.remote-signer-public-key Public key to request the remote signature from. - + [env: ETHREX_PROOF_COORDINATOR_REMOTE_SIGNER_PUBLIC_KEY=] --proof-coordinator.addr Set it to 0.0.0.0 to allow connections from other machines. - + [env: ETHREX_PROOF_COORDINATOR_LISTEN_ADDRESS=] [default: 127.0.0.1] @@ -413,7 +467,7 @@ Proof coordinator options: --proof-coordinator.send-interval How often does the proof coordinator send proofs to the L1 in milliseconds. - + [env: ETHREX_PROOF_COORDINATOR_SEND_INTERVAL=] [default: 5000] @@ -446,24 +500,24 @@ Aligned options: --aligned.beacon-url ... List of beacon urls to use. - + [env: ETHREX_ALIGNED_BEACON_URL=] --aligned-network L1 network name for Aligned sdk - + [env: ETHREX_ALIGNED_NETWORK=] [default: devnet] --aligned.fee-estimate Fee estimate for Aligned sdk - + [env: ETHREX_ALIGNED_FEE_ESTIMATE=] [default: instant] --aligned-sp1-elf-path Path to the SP1 elf. This is used for proof verification. - + [env: ETHREX_ALIGNED_SP1_ELF_PATH=] Admin server options: @@ -478,7 +532,7 @@ Admin server options: L2 options: --validium If true, L2 will run on validium mode as opposed to the default rollup mode, meaning it will not publish state diffs to the L1. - + [env: ETHREX_L2_VALIDIUM=] --sponsorable-addresses @@ -486,14 +540,14 @@ L2 options: --sponsor-private-key The private key of ethrex L2 transactions sponsor. - + [env: SPONSOR_PRIVATE_KEY=] [default: 0xffd790338a2798b648806fc8635ac7bf14af15425fed0c8f25bcc5febaa9b192] Monitor options: --no-monitor [env: ETHREX_NO_MONITOR=] - + ``` ## ethrex l2 prover