Skip to content
Merged
Changes from all commits
Commits
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
61 changes: 55 additions & 6 deletions system_tests/historical_block_hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,38 @@ import (
"encoding/binary"
"math/big"
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"

"github.com/offchainlabs/nitro/arbnode"
)

func TestHistoricalBlockHash(t *testing.T) {
func testHistoricalBlockHash(t *testing.T, executionClientMode ExecutionClientMode) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
cleanup := builder.Build(t)
defer cleanup()

// Build replica with specified execution mode
replicaConfig := arbnode.ConfigDefaultL1NonSequencerTest()
replicaParams := &SecondNodeParams{
nodeConfig: replicaConfig,
useExecutionClientOnly: true,
executionClientMode: executionClientMode,
}

replicaTestClient, replicaCleanup := builder.Build2ndNode(t, replicaParams)
defer replicaCleanup()
replicaClient := replicaTestClient.Client

// Wait for replica to initialize
time.Sleep(time.Second * 2)

// Generate 300+ blocks on primary
for {
builder.L2.TransferBalance(t, "Faucet", "Faucet", common.Big1, builder.L2Info)
number, err := builder.L2.Client.BlockNumber(ctx)
Expand All @@ -28,18 +47,48 @@ func TestHistoricalBlockHash(t *testing.T) {
}
}

block, err := builder.L2.Client.BlockByNumber(ctx, nil)
// Get current block from primary
block, err := builder.L2.Client.BlockNumber(ctx)
Require(t, err)

// Wait for replica to catch up to primary
for i := 0; i < 60; i++ {
replicaBlock, err := replicaClient.BlockNumber(ctx)
Require(t, err)
if replicaBlock >= block {
break
}
time.Sleep(time.Second)
}

// Verify replica caught up
replicaBlock, err := replicaClient.BlockNumber(ctx)
Require(t, err)
if replicaBlock < block {
t.Fatalf("Replica failed to sync: primary at block %d, replica at block %d", block, replicaBlock)
}

for i := uint64(0); i < block.Number().Uint64(); i++ {
// Test historical block hashes on replica
for i := uint64(0); i < replicaBlock; i++ {
var key common.Hash
binary.BigEndian.PutUint64(key[24:], i)
expectedBlock, err := builder.L2.Client.BlockByNumber(ctx, new(big.Int).SetUint64(i))
expectedBlock, err := replicaClient.BlockByNumber(ctx, new(big.Int).SetUint64(i))
Require(t, err)
blockHash := sendContractCall(t, ctx, params.HistoryStorageAddress, builder.L2.Client, key.Bytes())
blockHash := sendContractCall(t, ctx, params.HistoryStorageAddress, replicaClient, key.Bytes())
if !bytes.Equal(blockHash, expectedBlock.Hash().Bytes()) {
t.Fatalf("Expected block hash %s, got %s", expectedBlock.Hash(), blockHash)
t.Fatalf("Expected block hash %s, got %s for block %d", expectedBlock.Hash(), blockHash, i)
}
}
}

func TestHistoricalBlockHashInternal(t *testing.T) {
testHistoricalBlockHash(t, ExecutionClientModeInternal)
}

func TestHistoricalBlockHashExternal(t *testing.T) {
testHistoricalBlockHash(t, ExecutionClientModeExternal)
}

func TestHistoricalBlockHashComparison(t *testing.T) {
testHistoricalBlockHash(t, ExecutionClientModeComparison)
}