Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
40162ae
feat: add e2e tests for reorg and trie corruption scenarios
yongkangc Sep 5, 2025
609b8af
removed unused files
yongkangc Sep 5, 2025
dd2a129
feat: add SendPayloadFromJson action for payload handling
yongkangc Sep 5, 2025
0082cdc
refactor: clean up trie corruption test and improve code readability
yongkangc Sep 5, 2025
d6b89e4
combine files
yongkangc Sep 5, 2025
01bc941
refactor: improve code readability and consistency in e2e test utilities
yongkangc Sep 5, 2025
1137015
feat: introduce unified payload handling for engine API actions
yongkangc Sep 5, 2025
99ff0f2
refactor: remove duplicate ProduceBlockWithTransactions implementation
yongkangc Sep 5, 2025
f75f1a8
added trie updates checker
Sep 5, 2025
55b506f
fmt, clippy
yongkangc Sep 5, 2025
e279d43
fix: update parent_beacon_block_root to use B256::ZERO in testsuite
yongkangc Sep 5, 2025
26486e7
feat: enhance trie updates handling in testsuite
yongkangc Sep 5, 2025
6d5d113
feat: implement trie update forwarding and monitoring in testsuite
yongkangc Sep 5, 2025
8757799
cleanup
yongkangc Sep 8, 2025
3fedd6d
fix: update expected payload status in trie corruption tests
yongkangc Sep 8, 2025
73f397f
remove
yongkangc Sep 10, 2025
eb908f3
feat: add simplified trie corruption test suite
yongkangc Sep 10, 2025
8634a2a
remove: delete obsolete trie corruption test file
yongkangc Sep 10, 2025
e37b0d3
feat: add comprehensive trie fork and reorg test suite
yongkangc Sep 10, 2025
ff18f7c
refactor: enhance trie update actions and test structure
yongkangc Sep 10, 2025
ab3300d
feat: implement block production with transactions via Engine API
yongkangc Sep 10, 2025
7a7f0f1
chore: enhance block production with transactions via Engine API
yongkangc Sep 10, 2025
6fcf463
feat: add trie module to actions for enhanced testing capabilities
yongkangc Sep 10, 2025
f04fe88
clippy
yongkangc Sep 10, 2025
5cfb1f5
feat: implement enhanced block production with transactions via Engin…
yongkangc Sep 10, 2025
ae7680c
fmt
yongkangc Sep 10, 2025
079d786
feat: enhance block production and environment updates in Engine API
yongkangc Sep 10, 2025
e250978
feat: preserve trie updates for single-block chains in CanonicalChain
yongkangc Sep 10, 2025
2fec5f6
refactor: improve logging and code formatting in transaction actions
yongkangc Sep 10, 2025
f1b2871
fix: resolve CI errors in e2e tests
yongkangc Sep 10, 2025
43ee266
fix: resolve remaining CI errors
yongkangc Sep 10, 2025
e0abdd9
remove parent beacon root
yongkangc Sep 11, 2025
eb6b484
update e2e tests to use Cancun fork instead of Shanghai
yongkangc Sep 16, 2025
946206c
refactor: update trie update tests and remove obsolete test
yongkangc Sep 16, 2025
2c1eaec
refactor: update storage structure for trie update tests
yongkangc Sep 16, 2025
eade8f0
refactor: clarify storage slot configurations in trie update tests
yongkangc Sep 16, 2025
99f5427
refactor: simplify trie update imports in test suite
yongkangc Sep 16, 2025
a5cf73e
refactor: streamline trie update test configuration
yongkangc Sep 16, 2025
6b4d5b2
fmt
yongkangc Sep 16, 2025
ed0ae11
Made the AssertMineBlock action work with Optimism
yongkangc Sep 17, 2025
82a8dfe
fix(e2e-test): remove emojis and fix compilation errors in trie actions
yongkangc Sep 19, 2025
f85422d
fix(deps): add serde feature to op-alloy-rpc-types-engine
yongkangc Sep 19, 2025
0f730e1
fix(test): rename e2e test directory to match Cargo configuration
yongkangc Sep 25, 2025
bc925b2
ci: trigger CI checks after fixing test directory naming
yongkangc Sep 25, 2025
310e60a
chore: merge main and resolve conflicts
yongkangc Sep 25, 2025
cd2f9b2
fix: resolve remaining merge conflicts and format code
yongkangc Sep 25, 2025
db5bb11
refactor(test): simplify e2e reorg trie test to match actual incident
yongkangc Sep 26, 2025
905c5dc
fix: resolve compilation error in test genesis setup
yongkangc Sep 26, 2025
b145018
Merge remote-tracking branch 'origin/main' into yk/e2e_reorg_trie
yongkangc Sep 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 19 additions & 7 deletions crates/chain-state/src/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,13 +919,25 @@ impl<N: NodePrimitives<SignedTx: SignedTransaction>> NewCanonicalChain<N> {
pub fn to_chain_notification(&self) -> CanonStateNotification<N> {
match self {
Self::Commit { new } => {
let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
chain.append_block(
exec.recovered_block().clone(),
exec.execution_outcome().clone(),
);
chain
}));
// For single-block chains, preserve trie updates for testing
// This maintains backwards compatibility while allowing tests to access trie
// updates
let new = if new.len() == 1 {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shekhirin @mediocregopher @Rjected would appreciate a look over here as its what is required to replicate the test.

However as with anything with the trie state would need a double look

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my understanding of single block chains - the chain contains exactly one executed block

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afaict this is ok, the only behavior change is that CanonStateNotification::Commit contains trie updates for single block chains now, which the documentation states is the case anyway.

let block = new.first().unwrap();
Arc::new(Chain::from_block(
block.recovered_block().clone(),
block.execution_outcome().clone(),
block.trie_updates().cloned(),
))
} else {
Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
chain.append_block(
exec.recovered_block().clone(),
exec.execution_outcome().clone(),
);
chain
}))
};
CanonStateNotification::Commit { new }
}
Self::Reorg { new, old } => {
Expand Down
5 changes: 3 additions & 2 deletions crates/e2e-test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ reth-rpc-eth-api.workspace = true
reth-rpc-api = { workspace = true, features = ["client"] }
reth-payload-builder = { workspace = true, features = ["test-utils"] }
reth-payload-builder-primitives.workspace = true
reth-payload-primitives.workspace = true
reth-payload-primitives = { workspace = true, features = ["op"] }
reth-provider.workspace = true
reth-node-api.workspace = true
reth-node-core.workspace = true
Expand All @@ -41,6 +41,7 @@ reth-consensus.workspace = true
reth-primitives.workspace = true
reth-db-common.workspace = true
reth-primitives-traits.workspace = true
reth-trie-common.workspace = true

revm.workspace = true
tempfile.workspace = true
Expand Down Expand Up @@ -71,4 +72,4 @@ derive_more.workspace = true

[[test]]
name = "e2e_testsuite"
path = "tests/e2e-testsuite/main.rs"
path = "tests/e2e_testsuite/main.rs"
105 changes: 102 additions & 3 deletions crates/e2e-test-utils/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{network::NetworkTestContext, payload::PayloadTestContext, rpc::RpcTestContext};
use crate::{
network::NetworkTestContext, payload::PayloadTestContext, rpc::RpcTestContext,
testsuite::TrieUpdateEvent,
};
use alloy_consensus::{transaction::TxHashRef, BlockHeader};
use alloy_eips::BlockId;
use alloy_primitives::{BlockHash, BlockNumber, Bytes, Sealable, B256};
Expand All @@ -17,13 +20,14 @@ use reth_node_builder::{rpc::RethRpcAddOns, FullNode, NodeTypes};

use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
use reth_provider::{
BlockReader, BlockReaderIdExt, CanonStateNotificationStream, CanonStateSubscriptions,
HeaderProvider, StageCheckpointReader,
BlockReader, BlockReaderIdExt, CanonStateNotification, CanonStateNotificationStream,
CanonStateSubscriptions, HeaderProvider, StageCheckpointReader,
};
use reth_rpc_builder::auth::AuthServerHandle;
use reth_rpc_eth_api::helpers::{EthApiSpec, EthTransactions, TraceExt};
use reth_stages_types::StageId;
use std::pin::Pin;
use tokio::sync::mpsc;
use tokio_stream::StreamExt;
use url::Url;

Expand Down Expand Up @@ -304,6 +308,101 @@ where
self.inner.auth_server_handle().clone()
}

/// Start a background task that forwards trie updates from canonical state notifications
/// to the test environment via the provided channel
pub fn start_trie_update_forwarder(
&mut self,
node_idx: usize,
tx: mpsc::UnboundedSender<TrieUpdateEvent>,
) where
AddOns: RethRpcAddOns<Node> + 'static,
{
// Take the canonical stream (we can't clone it, so we move it into the task)
// This means each node can only have one forwarder, which is fine for our use case
let canonical_stream = std::mem::replace(
&mut self.canonical_stream,
self.inner.provider.canonical_state_stream(),
);

tokio::spawn(async move {
println!("Starting trie update forwarder for node {}", node_idx);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover println

tracing::debug!("Starting trie update forwarder for node {}", node_idx);

let mut stream = canonical_stream;
while let Some(notification) = stream.next().await {
println!(
"Node {} received canonical state notification: {:?}",
node_idx,
std::mem::discriminant(&notification)
);
match notification {
CanonStateNotification::Commit { new } => {
// Extract trie updates from committed chain
if let Some(trie_updates) = new.trie_updates() {
// Get the tip block hash from the chain
if let Some(tip_header) = new.headers().last() {
let tip_hash: alloy_primitives::B256 = tip_header.hash();

let event = TrieUpdateEvent {
node_idx,
block_hash: tip_hash,
trie_updates: trie_updates.clone(),
};

// Send the event, ignore errors if receiver is dropped
let _ = tx.send(event);

tracing::debug!(
"Forwarded trie updates for committed block {} from node {}",
tip_hash,
node_idx
);
}
} else {
println!("Node {}: No trie updates in committed chain", node_idx);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to remove after debugging

tracing::debug!(
"No trie updates in committed chain for node {}",
node_idx
);
}
}
CanonStateNotification::Reorg { old: _old, new } => {
// Extract trie updates from the new canonical chain after reorg
if let Some(trie_updates) = new.trie_updates() {
// Get all blocks in the new chain and forward their trie updates
for header in new.headers() {
let block_hash: alloy_primitives::B256 = header.hash();

let event = TrieUpdateEvent {
node_idx,
block_hash,
trie_updates: trie_updates.clone(),
};

// Send the event, ignore errors if receiver is dropped
let _ = tx.send(event);

tracing::debug!(
"Forwarded trie updates for reorged block {} from node {}",
block_hash,
node_idx
);
}
} else {
println!("Node {}: No trie updates in reorged chain", node_idx);
tracing::debug!(
"No trie updates in reorged chain for node {}",
node_idx
);
}
}
}
}

tracing::debug!("Trie update forwarder ended for node {}", node_idx);
});
}

/// Creates a [`crate::testsuite::NodeClient`] from this test context.
///
/// This helper method extracts the necessary handles and creates a client
Expand Down
Loading
Loading