Compare commits

..

11 Commits

Author SHA1 Message Date
Dan Cline
a979a0a42c fix(tree): prioritize BAL prewarm for state root task (#23839) 2026-04-29 16:42:02 +02:00
Dan Cline
73fd1b6a72 fix(engine): do not install state hook if BAL is disabled (#23835) (#23836)
Co-authored-by: Alexey Shekhirin <github@shekhirin.com>
2026-04-29 16:00:22 +02:00
Ishika Choudhury
ada5c64864 chore: remaining Devnet3 fixes (#23826)
Co-authored-by: Soubhik Singha Mahapatra <soubhiksmp2004@gmail.com>
Co-authored-by: Soubhik Singha Mahapatra <160333583+Soubhik-10@users.noreply.github.com>
Co-authored-by: Brian Picciano <me@mediocregopher.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2026-04-29 14:16:02 +02:00
Alexey Shekhirin
4cc0a8fb24 ci(hive): use bal-devnet-3 fixtures and branch 2026-04-29 10:13:38 +02:00
Matthias Seitz
253d53e94a chore(hive): remove duplicate expected failures 2026-04-29 10:07:26 +02:00
Matthias Seitz
bf349a3cb6 fix(bal): propagate built block access lists 2026-04-29 10:04:50 +02:00
Matthias Seitz
f17ff3fa5f Merge remote-tracking branch 'origin/main' into bal-devnet-3
# Conflicts:
#	.github/scripts/hive/expected_failures.yaml
2026-04-29 09:48:58 +02:00
Emma Jamieson-Hoare
b598d64ebd feat(net): enable ETH70 by default (#23771) (#23772)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2026-04-28 13:13:19 +01:00
Emma Jamieson-Hoare
e56fb8f22b chore(hive): expect Amsterdam EIP-7610 collision failures
Adds Amsterdam fork variants of the EIP-7610 create-collision test
failures already tracked for prior forks in eels/consume-engine and
eels/consume-rlp.

Amp-Thread-ID: https://ampcode.com/threads/T-019dcdeb-2f75-71d7-a319-e88f3677046a
Co-authored-by: Amp <amp@ampcode.com>
2026-04-27 11:13:44 +02:00
Emma Jamieson-Hoare
18edd918c8 feat(engine): validate BAL post-execution (EIP-7928)
Pre-execution: reject blocks whose declared BAL exceeds the gas-limit
budget (total_bal_items > gas_limit / ITEM_COST).

Post-execution: enable the BAL builder on the State DB when a BAL is
present, extract the produced BAL via take_built_alloy_bal, and verify
its hash matches block_access_list_hash committed in the header.

Amp-Thread-ID: https://ampcode.com/threads/T-019dcdeb-2f75-71d7-a319-e88f3677046a
Co-authored-by: Amp <amp@ampcode.com>
2026-04-27 11:13:44 +02:00
Emma Jamieson-Hoare
2771424cc9 feat(consensus): add BAL error variants
Adds BlockAccessListHashMismatch and BlockAccessListCostMoreThanGasLimit
ConsensusError variants for EIP-7928 (Amsterdam) BAL validation.

Amp-Thread-ID: https://ampcode.com/threads/T-019dcdeb-2f75-71d7-a319-e88f3677046a
Co-authored-by: Amp <amp@ampcode.com>
2026-04-27 11:13:44 +02:00
11 changed files with 237 additions and 218 deletions

View File

@@ -5,8 +5,8 @@ fixture_variant="${1:-osaka}"
case "${fixture_variant}" in
amsterdam)
eels_fixtures="https://github.com/ethereum/execution-spec-tests/releases/download/bal@v6.0.0/fixtures_bal.tar.gz"
eels_branch="devnets/snøbal/4"
eels_fixtures="https://github.com/ethereum/execution-spec-tests/releases/download/bal@v5.6.1/fixtures_bal.tar.gz"
eels_branch="devnets/bal/3"
;;
osaka)
eels_fixtures="https://github.com/ethereum/execution-spec-tests/releases/download/v5.3.0/fixtures_develop.tar.gz"

View File

@@ -6,9 +6,6 @@ on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
pull_request:
branches:
- "**"
env:
CARGO_TERM_COLOR: always
@@ -31,9 +28,9 @@ jobs:
secrets: inherit
prepare-hive:
if: github.repository == 'paradigmxyz/reth-oss' || github.repository == 'paradigmxyz/reth'
if: github.repository == 'paradigmxyz/reth'
timeout-minutes: 45
runs-on: ${{ (github.repository == 'paradigmxyz/reth-oss' || github.repository == 'paradigmxyz/reth') && 'depot-ubuntu-latest-16' || 'ubuntu-latest' }}
runs-on: ${{ github.repository == 'paradigmxyz/reth' && 'depot-ubuntu-latest-16' || 'ubuntu-latest' }}
permissions:
contents: read
strategy:
@@ -204,7 +201,7 @@ jobs:
- prepare-hive
name: Hive-Amsterdam / ${{ matrix.scenario.sim }}${{ matrix.scenario.limit && format(' - {0}', matrix.scenario.limit) }}
# Use larger runners for eels tests to avoid OOM runner crashes
runs-on: ${{ (github.repository == 'paradigmxyz/reth-oss' || github.repository == 'paradigmxyz/reth') && (contains(matrix.scenario.sim, 'eels') && 'depot-ubuntu-latest-8' || 'depot-ubuntu-latest-4') || 'ubuntu-latest' }}
runs-on: ${{ github.repository == 'paradigmxyz/reth' && (contains(matrix.scenario.sim, 'eels') && 'depot-ubuntu-latest-8' || 'depot-ubuntu-latest-4') || 'ubuntu-latest' }}
permissions:
contents: read
issues: write
@@ -384,7 +381,7 @@ jobs:
- prepare-hive
name: Hive-Osaka / ${{ matrix.scenario.sim }}${{ matrix.scenario.limit && format(' - {0}', matrix.scenario.limit) }}
# Use larger runners for eels tests to avoid OOM runner crashes
runs-on: ${{ (github.repository == 'paradigmxyz/reth-oss' || github.repository == 'paradigmxyz/reth') && (contains(matrix.scenario.sim, 'eels') && 'depot-ubuntu-latest-8' || 'depot-ubuntu-latest-4') || 'ubuntu-latest' }}
runs-on: ${{ github.repository == 'paradigmxyz/reth' && (contains(matrix.scenario.sim, 'eels') && 'depot-ubuntu-latest-8' || 'depot-ubuntu-latest-4') || 'ubuntu-latest' }}
permissions:
contents: read
issues: write

361
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -433,14 +433,14 @@ reth-trie-sparse = { path = "crates/trie/sparse", default-features = false }
reth-zstd-compressors = { version = "0.3.1", default-features = false }
# revm
revm = { version = "=38.0.0", default-features = false }
revm-bytecode = { version = "=10.0.0", default-features = false }
revm-database = { version = "=13.0.1", default-features = false }
revm-state = { version = "=11.0.1", default-features = false }
revm-primitives = { version = "=23.0.0", default-features = false }
revm-interpreter = { version = "=35.0.1", default-features = false }
revm-database-interface = { version = "=11.0.1", default-features = false }
revm-inspectors = "=0.39.0"
revm = { version = "38.0.0", default-features = false }
revm-bytecode = { version = "10.0.0", default-features = false }
revm-database = { version = "13.0.0", default-features = false }
revm-state = { version = "11.0.0", default-features = false }
revm-primitives = { version = "23.0.0", default-features = false }
revm-interpreter = { version = "35.0.0", default-features = false }
revm-database-interface = { version = "11.0.0", default-features = false }
revm-inspectors = "0.39.0"
# eth
alloy-dyn-abi = "1.5.6"
@@ -700,24 +700,3 @@ vergen-git2 = "9.1.0"
# networking
ipnet = "2.11"
[patch.crates-io]
revm = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-bytecode = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-context = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-context-interface = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-database = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-database-interface = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-handler = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-inspector = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-precompile = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-primitives = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-state = { git = "https://github.com/bluealloy/revm", rev = "3ed3bdfed9ad6e5ba37f4e1f015436ab89ca98be" }
revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "5eebb56819ee6bec5bfbc69a415276ee1a784fec" }
alloy-evm = { git = "https://github.com/alloy-rs/evm", branch = "bal-devnet-4" }
reth-codecs = { git = "https://github.com/paradigmxyz/reth-core", rev = "8612239c4f3dda83cc389f577b9eb04f10ebf81d" }
reth-codecs-derive = { git = "https://github.com/paradigmxyz/reth-core", rev = "8612239c4f3dda83cc389f577b9eb04f10ebf81d" }
reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth-core", rev = "8612239c4f3dda83cc389f577b9eb04f10ebf81d" }
reth-rpc-traits = { git = "https://github.com/paradigmxyz/reth-core", rev = "8612239c4f3dda83cc389f577b9eb04f10ebf81d" }
reth-zstd-compressors = { git = "https://github.com/paradigmxyz/reth-core", rev = "8612239c4f3dda83cc389f577b9eb04f10ebf81d" }

View File

@@ -477,8 +477,8 @@ pub enum ConsensusError {
#[error(transparent)]
TransactionGasLimitTooHigh(Box<TxGasLimitTooHighErr>),
/// Error when an unexpected block access list cost is encountered.
#[error("block access list exceeds gas limit")]
BlockAccessListExceedsGasLimit,
#[error("block access list cost exceeds gas limit")]
BlockAccessListCostMoreThanGasLimit,
/// Error when the block access list hash doesn't match the expected value.
#[error("block access list hash mismatch: {0}")]
BlockAccessListHashMismatch(GotExpectedBoxed<B256>),
@@ -538,7 +538,7 @@ pub fn validate_block_access_list_gas(
if let Some(bal) = block_access_list {
let bal_items = alloy_eip7928::total_bal_items(bal);
if bal_items > gas_limit / alloy_eip7928::ITEM_COST as u64 {
return Err(ConsensusError::BlockAccessListExceedsGasLimit)
return Err(ConsensusError::BlockAccessListCostMoreThanGasLimit)
}
}
Ok(())

View File

@@ -1162,16 +1162,19 @@ mod tests {
}
}
let mut account = revm_state::Account::default();
account.info = AccountInfo {
balance: U256::from(rng.random::<u64>()),
nonce: rng.random::<u64>(),
code_hash: KECCAK_EMPTY,
code: Some(Default::default()),
account_id: None,
let account = revm_state::Account {
info: AccountInfo {
balance: U256::from(rng.random::<u64>()),
nonce: rng.random::<u64>(),
code_hash: KECCAK_EMPTY,
code: Some(Default::default()),
account_id: None,
},
original_info: Box::new(AccountInfo::default()),
storage,
status: AccountStatus::Touched,
transaction_id: 0,
};
account.storage = storage;
account.status = AccountStatus::Touched;
state_update.insert(address, account);
}

View File

@@ -1016,7 +1016,7 @@ where
// Extract the built bal if payload has bal
let built_bal = if has_bal { db.take_built_alloy_bal() } else { None };
tracing::debug!(has_bal = built_bal.is_some(), "Built BAL");
tracing::info!("Built Bal is {:?}", built_bal);
let output = BlockExecutionOutput { result, state: db.take_bundle() };
@@ -1115,6 +1115,7 @@ where
executor.evm_mut().db_mut().bump_bal_index();
}
}
drop(exec_span);
Ok((executor, senders))

View File

@@ -266,7 +266,6 @@ mod tests {
state_gas_used: 0,
reservoir: 0,
gas_refunded: 0,
refill_amount: 0,
bytes: Bytes::default(),
})
})
@@ -281,7 +280,6 @@ mod tests {
state_gas_used: 0,
reservoir: 0,
gas_refunded: 0,
refill_amount: 0,
bytes: alloy_primitives::Bytes::copy_from_slice(b"cached_result"),
};
@@ -316,7 +314,6 @@ mod tests {
state_gas_used: 0,
reservoir: 0,
gas_refunded: 0,
refill_amount: 0,
bytes: alloy_primitives::Bytes::copy_from_slice(b"output_from_precompile_1"),
})
}
@@ -334,7 +331,6 @@ mod tests {
state_gas_used: 0,
reservoir: 0,
gas_refunded: 0,
refill_amount: 0,
bytes: alloy_primitives::Bytes::copy_from_slice(b"output_from_precompile_2"),
})
}

View File

@@ -487,9 +487,9 @@ where
max_rlp_length: MAX_RLP_BLOCK_SIZE,
}));
}
let block_access_list: Option<Bytes> =
block_access_list.map(|block_access_list| alloy_rlp::encode(&block_access_list).into());
let payload = EthBuiltPayload::new(sealed_block, total_fees, requests, block_access_list)
// add blob sidecars from the executed txs
.with_sidecars(blob_sidecars);

View File

@@ -152,7 +152,7 @@ pub trait Executor<DB: Database>: Sized {
/// This is used to optimize DB commits depending on the size of the state.
fn size_hint(&self) -> usize;
/// Take built [`BlockAccessList`] from executor
/// Takes built [`BlockAccessList`] from executor.
fn take_bal(&mut self) -> Option<BlockAccessList>;
}
@@ -471,7 +471,6 @@ where
fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> {
self.executor.apply_pre_execution_changes()?;
// Bump BAL index after pre-execution changes (EIP-7928: index 0 is pre-execution)
self.executor.evm_mut().db_mut().bump_bal_index();
Ok(())
@@ -487,7 +486,6 @@ where
self.executor.execute_transaction_with_commit_condition((tx_env, &tx), f)?
{
self.transactions.push(tx);
// Bump BAL index after each committed transaction (EIP-7928)
self.executor.evm_mut().db_mut().bump_bal_index();
Ok(Some(gas_used))
} else {
@@ -506,7 +504,6 @@ where
// merge all transitions into bundle state
db.merge_transitions(BundleRetention::Reverts);
// extract the built block access list (EIP-7928, Amsterdam) and compute its hash
let block_access_list = db.take_built_alloy_bal();
let block_access_list_hash =
block_access_list.as_ref().map(|bal| compute_block_access_list_hash(bal));

View File

@@ -1424,7 +1424,6 @@ pub fn ensure_intrinsic_gas<T: EthPoolTransaction>(
.map(|l| l.iter().map(|i| i.storage_keys.len()).sum::<usize>())
.unwrap_or_default() as u64,
transaction.authorization_list().map(|l| l.len()).unwrap_or_default() as u64,
revm_primitives::eip8037::CPSB_GLAMSTERDAM,
);
let gas_limit = transaction.gas_limit();