Skip to content

Commit 2e12d81

Browse files
test: Check full node is able to sync blocks from local DA in E2E test (#2470)
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. NOTE: PR titles should follow semantic commits: https://www.conventionalcommits.org/en/v1.0.0/ --> ## Overview Adds a check at the end of an EVM E2E full node test to make sure it syncs blocks from the DA layer (local-da) as well in addition to just syncing them from P2P <!-- Please provide an explanation of the PR, including the appropriate context, background, goal, and rationale. If there is an issue with this information, please provide a tl;dr and link the issue. Ex: Closes #<issue number> --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Enhanced end-to-end tests for EVM full nodes to verify Data Availability (DA) inclusion synchronization, including additional checks and detailed logging. * Updated test documentation to reflect new DA inclusion verification steps. * **Chores** * Added new indirect dependencies to support enhanced testing and DA verification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 4906143 commit 2e12d81

3 files changed

Lines changed: 169 additions & 5 deletions

File tree

test/e2e/evm_full_node_e2e_test.go

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// - Block propagation verification with multiple full nodes
1212
// - Distributed node restart and recovery mechanisms
1313
// - Lazy mode sequencer behavior with full node sync
14+
// - DA (Data Availability) inclusion synchronization between nodes
1415
//
1516
// Test Coverage:
1617
// 1. TestEvmSequencerWithFullNodeE2E - Full node P2P sync with sequencer
@@ -23,6 +24,7 @@ package e2e
2324

2425
import (
2526
"context"
27+
"encoding/binary"
2628
"flag"
2729
"path/filepath"
2830
"testing"
@@ -31,6 +33,9 @@ import (
3133
"github.com/ethereum/go-ethereum/common"
3234
"github.com/ethereum/go-ethereum/ethclient"
3335
"github.com/stretchr/testify/require"
36+
37+
"github.com/rollkit/rollkit/pkg/rpc/client"
38+
"github.com/rollkit/rollkit/pkg/store"
3439
)
3540

3641
// Note: evmSingleBinaryPath is declared in evm_sequencer_e2e_test.go to avoid duplicate declaration
@@ -264,6 +269,8 @@ func setupSequencerWithFullNode(t *testing.T, sut *SystemUnderTest, sequencerHom
264269
// 5. Submits transaction to sequencer EVM and gets the block number
265270
// 6. Verifies the full node syncs the exact same block containing the transaction
266271
// 7. Performs comprehensive state root verification across all synced blocks
272+
// 8. Queries full node's latest block height and waits 2 DA block times for DA inclusion
273+
// 9. Verifies DA (Data Availability) inclusion has caught up to the queried block height
267274
//
268275
// Validation:
269276
// - Both sequencer and full node start successfully
@@ -273,6 +280,7 @@ func setupSequencerWithFullNode(t *testing.T, sut *SystemUnderTest, sequencerHom
273280
// - Transaction data is identical on both nodes (same block, same receipt)
274281
// - State roots match between sequencer and full node for all blocks (key validation)
275282
// - Block hashes and transaction counts are consistent across both nodes
283+
// - DA included height >= full node's block height after wait (ensuring DA layer sync)
276284
//
277285
// Key Technical Details:
278286
// - Uses separate Docker Compose configurations for different EVM ports
@@ -283,8 +291,10 @@ func setupSequencerWithFullNode(t *testing.T, sut *SystemUnderTest, sequencerHom
283291
// - Ensures EVM state consistency between sequencer and full node on the Reth side
284292
//
285293
// This test demonstrates that full nodes can sync with sequencers in real-time,
286-
// validates the P2P block propagation mechanism in Rollkit, and ensures that
287-
// the underlying EVM execution state remains consistent across all nodes.
294+
// validates the P2P block propagation mechanism in Rollkit, ensures that
295+
// the underlying EVM execution state remains consistent across all nodes, and
296+
// verifies that DA (Data Availability) inclusion processes blocks within expected
297+
// timeframes after allowing sufficient time for DA layer synchronization.
288298
func TestEvmSequencerWithFullNodeE2E(t *testing.T) {
289299
flag.Parse()
290300
workDir := t.TempDir()
@@ -398,8 +408,73 @@ func TestEvmSequencerWithFullNodeE2E(t *testing.T) {
398408
}
399409
}
400410

401-
t.Logf("✅ Test PASSED: All blocks (%d-%d) have matching state roots, %d transactions synced successfully across blocks %v",
411+
t.Logf("✅ State root verification passed: All blocks (%d-%d) have matching state roots, %d transactions synced successfully across blocks %v",
402412
startHeight, endHeight, len(txHashes), txBlockNumbers)
413+
414+
// === DA INCLUSION VERIFICATION ===
415+
416+
t.Log("Verifying DA inclusion for latest block height...")
417+
418+
// Create RPC client for full node
419+
fullNodeRPCClient := client.NewClient("http://127.0.0.1:" + FullNodeRPCPort)
420+
421+
// Get the full node's current block height before waiting
422+
fnHeader, err = fullNodeClient.HeaderByNumber(fnCtx, nil)
423+
require.NoError(t, err, "Should get full node header for DA inclusion check")
424+
fnBlockHeightBeforeWait := fnHeader.Number.Uint64()
425+
426+
t.Logf("Full node block height before DA inclusion wait: %d", fnBlockHeightBeforeWait)
427+
428+
// Wait for one DA block time to allow DA inclusion to process
429+
waitTime := 1 * time.Second
430+
t.Logf("Waiting %v (1 DA block time) for DA inclusion to process...", waitTime)
431+
time.Sleep(waitTime)
432+
433+
// Get the DA included height from full node after the wait
434+
fnDAIncludedHeightBytes, err := fullNodeRPCClient.GetMetadata(fnCtx, store.DAIncludedHeightKey)
435+
require.NoError(t, err, "Should get DA included height from full node")
436+
437+
// Decode the DA included height
438+
require.Equal(t, 8, len(fnDAIncludedHeightBytes), "DA included height should be 8 bytes")
439+
fnDAIncludedHeight := binary.LittleEndian.Uint64(fnDAIncludedHeightBytes)
440+
441+
t.Logf("After waiting, full node DA included height: %d", fnDAIncludedHeight)
442+
443+
// Verify that the DA included height is >= the full node's block height before wait
444+
// This ensures that the blocks that existed before the wait have been DA included
445+
require.GreaterOrEqual(t, fnDAIncludedHeight, fnBlockHeightBeforeWait,
446+
"Full node DA included height (%d) should be >= block height before wait (%d)",
447+
fnDAIncludedHeight, fnBlockHeightBeforeWait)
448+
449+
t.Logf("✅ DA inclusion verification passed:")
450+
t.Logf(" - Full node block height before wait: %d", fnBlockHeightBeforeWait)
451+
t.Logf(" - Full node DA included height after wait: %d", fnDAIncludedHeight)
452+
t.Logf(" - DA inclusion caught up to full node's block height ✓")
453+
454+
// === COMPREHENSIVE TEST SUMMARY ===
455+
456+
t.Logf("")
457+
t.Logf("🎉 TEST PASSED: Comprehensive EVM Full Node E2E Test Successfully Completed!")
458+
t.Logf(" 📊 Test Statistics:")
459+
t.Logf(" • Total transactions submitted: %d", len(txHashes))
460+
t.Logf(" • Transaction blocks: %v", txBlockNumbers)
461+
t.Logf(" • Final sequencer height: %d", seqHeight)
462+
t.Logf(" • Final full node height: %d", fnHeight)
463+
t.Logf(" • State root verification range: blocks %d-%d", startHeight, endHeight)
464+
t.Logf(" • Full node block height before DA wait: %d", fnBlockHeightBeforeWait)
465+
t.Logf(" • DA wait time: %v (1 DA block time)", waitTime)
466+
t.Logf(" • Full node DA included height after wait: %d", fnDAIncludedHeight)
467+
t.Logf("")
468+
t.Logf(" ✅ Verified Components:")
469+
t.Logf(" • P2P connection establishment between sequencer and full node")
470+
t.Logf(" • Real-time transaction synchronization via P2P")
471+
t.Logf(" • Block propagation and consistency across nodes")
472+
t.Logf(" • State root consistency across all synced blocks")
473+
t.Logf(" • Transaction receipt consistency between nodes")
474+
t.Logf(" • DA (Data Availability) inclusion processing within expected timeframes")
475+
t.Logf(" • EVM execution state consistency")
476+
t.Logf("")
477+
t.Logf(" 🏆 All validation criteria met - distributed rollkit network is functioning correctly!")
403478
}
404479

405480
// TestEvmFullNodeBlockPropagationE2E tests that blocks produced by the aggregator

test/e2e/go.mod

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ require (
4545
github.com/beorn7/perks v1.0.1 // indirect
4646
github.com/bits-and-blooms/bitset v1.17.0 // indirect
4747
github.com/buger/goterm v1.0.4 // indirect
48+
github.com/celestiaorg/go-header v0.6.6 // indirect
4849
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
4950
github.com/cespare/xxhash/v2 v2.3.0 // indirect
5051
github.com/compose-spec/compose-go/v2 v2.6.0 // indirect
@@ -66,6 +67,8 @@ require (
6667
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
6768
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
6869
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
70+
github.com/dgraph-io/badger/v4 v4.5.1 // indirect
71+
github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect
6972
github.com/distribution/reference v0.6.0 // indirect
7073
github.com/docker/buildx v0.22.0 // indirect
7174
github.com/docker/cli v28.0.4+incompatible // indirect
@@ -78,6 +81,7 @@ require (
7881
github.com/docker/go-connections v0.5.0 // indirect
7982
github.com/docker/go-metrics v0.0.1 // indirect
8083
github.com/docker/go-units v0.5.0 // indirect
84+
github.com/dustin/go-humanize v1.0.1 // indirect
8185
github.com/ebitengine/purego v0.8.2 // indirect
8286
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 // indirect
8387
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
@@ -96,8 +100,10 @@ require (
96100
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
97101
github.com/gofrs/flock v0.12.1 // indirect
98102
github.com/gogo/protobuf v1.3.2 // indirect
103+
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
99104
github.com/golang/protobuf v1.5.4 // indirect
100105
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
106+
github.com/google/flatbuffers v24.12.23+incompatible // indirect
101107
github.com/google/gnostic-models v0.6.8 // indirect
102108
github.com/google/go-cmp v0.7.0 // indirect
103109
github.com/google/gofuzz v1.2.0 // indirect
@@ -110,19 +116,25 @@ require (
110116
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
111117
github.com/hashicorp/go-multierror v1.1.1 // indirect
112118
github.com/hashicorp/go-version v1.7.0 // indirect
119+
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
113120
github.com/holiman/uint256 v1.3.2 // indirect
114121
github.com/imdario/mergo v0.3.16 // indirect
115122
github.com/in-toto/in-toto-golang v0.5.0 // indirect
116123
github.com/inconshreveable/mousetrap v1.1.0 // indirect
117124
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect
118125
github.com/ipfs/go-cid v0.5.0 // indirect
126+
github.com/ipfs/go-datastore v0.8.2 // indirect
127+
github.com/ipfs/go-ds-badger4 v0.1.8 // indirect
128+
github.com/ipfs/go-log/v2 v2.6.0 // indirect
119129
github.com/jonboulle/clockwork v0.5.0 // indirect
120130
github.com/josharian/intern v1.0.0 // indirect
121131
github.com/json-iterator/go v1.1.12 // indirect
122132
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
123133
github.com/klauspost/compress v1.18.0 // indirect
124134
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
125135
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
136+
github.com/libp2p/go-libp2p-pubsub v0.14.1 // indirect
137+
github.com/libp2p/go-msgio v0.3.0 // indirect
126138
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
127139
github.com/magiconair/properties v1.8.10 // indirect
128140
github.com/mailru/easyjson v0.7.7 // indirect
@@ -157,9 +169,11 @@ require (
157169
github.com/multiformats/go-base32 v0.1.0 // indirect
158170
github.com/multiformats/go-base36 v0.2.0 // indirect
159171
github.com/multiformats/go-multiaddr v0.16.0 // indirect
172+
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
160173
github.com/multiformats/go-multibase v0.2.0 // indirect
161174
github.com/multiformats/go-multicodec v0.9.0 // indirect
162175
github.com/multiformats/go-multihash v0.2.3 // indirect
176+
github.com/multiformats/go-multistream v0.6.0 // indirect
163177
github.com/multiformats/go-varint v0.0.7 // indirect
164178
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
165179
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
@@ -207,6 +221,7 @@ require (
207221
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
208222
github.com/yusufpapurcu/wmi v1.2.4 // indirect
209223
github.com/zclconf/go-cty v1.16.0 // indirect
224+
go.opencensus.io v0.24.0 // indirect
210225
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
211226
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 // indirect
212227
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 // indirect
@@ -223,6 +238,8 @@ require (
223238
go.opentelemetry.io/otel/trace v1.35.0 // indirect
224239
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
225240
go.uber.org/mock v0.5.0 // indirect
241+
go.uber.org/multierr v1.11.0 // indirect
242+
go.uber.org/zap v1.27.0 // indirect
226243
golang.org/x/crypto v0.39.0 // indirect
227244
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
228245
golang.org/x/net v0.41.0 // indirect

0 commit comments

Comments
 (0)