mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
Update block_sync_test.go
This commit is contained in:
parent
94ecd1db22
commit
e06b779a69
1 changed files with 150 additions and 0 deletions
|
|
@ -137,6 +137,7 @@ func TestBlockSync(t *testing.T) {
|
|||
type testHeadTracker struct {
|
||||
prefetch types.HeadInfo
|
||||
validated types.SignedHeader
|
||||
finalityUpdate types.FinalityUpdate
|
||||
}
|
||||
|
||||
func (h *testHeadTracker) PrefetchHead() types.HeadInfo {
|
||||
|
|
@ -161,3 +162,152 @@ func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
|
|||
SignatureSlot: h.validated.SignatureSlot,
|
||||
}, h.validated.Header != (types.Header{})
|
||||
}
|
||||
|
||||
func TestBlockSyncFinality(t *testing.T) {
|
||||
ht := &testHeadTracker{}
|
||||
blockSync := newBeaconBlockSync(ht)
|
||||
headCh := make(chan types.ChainHeadEvent, 16)
|
||||
blockSync.SubscribeChainHead(headCh)
|
||||
ts := sync.NewTestScheduler(t, blockSync)
|
||||
ts.AddServer(testServer1, 1)
|
||||
ts.AddServer(testServer2, 1)
|
||||
|
||||
// Helper function to check finality hash in chain head events
|
||||
expFinalizedHash := func(expFinalizedHash common.Hash) {
|
||||
t.Helper()
|
||||
select {
|
||||
case event := <-headCh:
|
||||
if event.Finalized != expFinalizedHash {
|
||||
t.Errorf("Wrong finalized hash, expected %x, got %x", expFinalizedHash, event.Finalized)
|
||||
}
|
||||
default:
|
||||
t.Error("Expected chain head event with finalized hash, but none received")
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check no chain head event
|
||||
expNoChainHeadEvent := func() {
|
||||
t.Helper()
|
||||
select {
|
||||
case event := <-headCh:
|
||||
t.Errorf("Unexpected chain head event received: finalized hash %x", event.Finalized)
|
||||
default:
|
||||
// Expected: no event
|
||||
}
|
||||
}
|
||||
|
||||
// Create test blocks with different slot configurations
|
||||
testBlock3 := types.NewBeaconBlock(&deneb.BeaconBlock{
|
||||
Slot: 127, // Slot 127 (epoch 3, slot 63)
|
||||
Body: deneb.BeaconBlockBody{
|
||||
ExecutionPayload: deneb.ExecutionPayload{
|
||||
BlockNumber: 460,
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1")),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
testBlock4 := types.NewBeaconBlock(&deneb.BeaconBlock{
|
||||
Slot: 128, // Slot 128 (epoch 4, slot 0)
|
||||
Body: deneb.BeaconBlockBody{
|
||||
ExecutionPayload: deneb.ExecutionPayload{
|
||||
BlockNumber: 461,
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2")),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Test case 1: No finality update available
|
||||
// Set block 3 as validated head, no finality update
|
||||
ht.validated.Header = testBlock3.Header()
|
||||
ts.Run(1)
|
||||
// Should not emit chain head event because no finality update is available
|
||||
expNoChainHeadEvent()
|
||||
|
||||
// Test case 2: Finality update available, same epoch
|
||||
// Set finality update for the same epoch as attested header
|
||||
ht.finalityUpdate = types.FinalityUpdate{
|
||||
Attested: types.HeaderWithExecProof{Header: testBlock3.Header()},
|
||||
Finalized: types.HeaderWithExecProof{
|
||||
Header: types.Header{
|
||||
Slot: 127,
|
||||
StateRoot: common.HexToHash("f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2"),
|
||||
},
|
||||
PayloadHeader: types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2")),
|
||||
}),
|
||||
},
|
||||
Signature: ht.validated.Signature,
|
||||
SignatureSlot: ht.validated.SignatureSlot,
|
||||
}
|
||||
ts.Run(2)
|
||||
// Should emit chain head event with finalized hash
|
||||
expFinalizedHash(common.HexToHash("f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2"))
|
||||
|
||||
// Test case 3: Finality update available, attested epoch < finalized epoch
|
||||
// This should not emit chain head event
|
||||
ht.validated.Header = testBlock3.Header() // Slot 127 (epoch 3)
|
||||
ht.finalityUpdate = types.FinalityUpdate{
|
||||
Attested: types.HeaderWithExecProof{Header: testBlock3.Header()},
|
||||
Finalized: types.HeaderWithExecProof{
|
||||
Header: types.Header{
|
||||
Slot: 128,
|
||||
StateRoot: common.HexToHash("e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2d3"),
|
||||
},
|
||||
PayloadHeader: types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2d3")),
|
||||
}),
|
||||
},
|
||||
Signature: ht.validated.Signature,
|
||||
SignatureSlot: ht.validated.SignatureSlot,
|
||||
}
|
||||
ts.Run(3)
|
||||
// Should not emit chain head event because attested epoch < finalized epoch
|
||||
expNoChainHeadEvent()
|
||||
|
||||
// Test case 4: Finality update available, attested epoch == finalized epoch + 1
|
||||
// Set block 4 as validated head (epoch 4, slot 0)
|
||||
ht.validated.Header = testBlock4.Header()
|
||||
// Set finalized header to epoch 3 (slot 127)
|
||||
ht.finalityUpdate.Finalized.Header.Slot = 127
|
||||
ts.Run(4)
|
||||
// Should not emit chain head event because head is at first slot of next epoch
|
||||
// and we need to wait for finality update
|
||||
expNoChainHeadEvent()
|
||||
|
||||
// Test case 5: Finality update available, attested epoch == finalized epoch + 1
|
||||
// but parent block is not in the same epoch as finalized
|
||||
// Set block 4 as validated head (epoch 4, slot 0)
|
||||
ht.validated.Header = testBlock4.Header()
|
||||
// Set finalized header to epoch 3 (slot 127)
|
||||
ht.finalityUpdate.Finalized.Header.Slot = 127
|
||||
// Set finalized payload header for test case 5
|
||||
ht.finalityUpdate.Finalized.PayloadHeader = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2d3")),
|
||||
})
|
||||
// Add parent block (block 3) to recent blocks
|
||||
blockSync.recentBlocks.Add(testBlock3.Root(), testBlock3)
|
||||
ts.Run(5)
|
||||
// Should emit chain head event because parent block is available and not in finalized epoch
|
||||
expFinalizedHash(common.HexToHash("e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0d1c2b3a4f5e6d7c8b9a0f1e2d3"))
|
||||
|
||||
// Test case 6: Finality update available, attested epoch == finalized epoch + 1
|
||||
// but parent block is in the same epoch as finalized
|
||||
// Create a block in epoch 2 (slot 95)
|
||||
testBlock5 := types.NewBeaconBlock(&deneb.BeaconBlock{
|
||||
Slot: 95, // Slot 95 (epoch 2, slot 63)
|
||||
Body: deneb.BeaconBlockBody{
|
||||
ExecutionPayload: deneb.ExecutionPayload{
|
||||
BlockNumber: 462,
|
||||
BlockHash: zrntcommon.Hash32(common.HexToHash("c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3")),
|
||||
},
|
||||
},
|
||||
})
|
||||
ht.validated.Header = testBlock4.Header() // Slot 128 (epoch 4, slot 0)
|
||||
ht.finalityUpdate.Finalized.Header.Slot = 127 // Epoch 3, slot 63
|
||||
// Add parent block (block 5) to recent blocks - this is in epoch 2
|
||||
blockSync.recentBlocks.Add(testBlock5.Root(), testBlock5)
|
||||
ts.Run(6)
|
||||
// Should not emit chain head event because parent is in finalized epoch
|
||||
expNoChainHeadEvent()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue