Update block_sync_test.go

This commit is contained in:
SERHII BUHAI 2025-08-21 21:22:04 +03:00 committed by GitHub
parent 94ecd1db22
commit e06b779a69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -137,6 +137,7 @@ func TestBlockSync(t *testing.T) {
type testHeadTracker struct { type testHeadTracker struct {
prefetch types.HeadInfo prefetch types.HeadInfo
validated types.SignedHeader validated types.SignedHeader
finalityUpdate types.FinalityUpdate
} }
func (h *testHeadTracker) PrefetchHead() types.HeadInfo { func (h *testHeadTracker) PrefetchHead() types.HeadInfo {
@ -161,3 +162,152 @@ func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
SignatureSlot: h.validated.SignatureSlot, SignatureSlot: h.validated.SignatureSlot,
}, h.validated.Header != (types.Header{}) }, 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()
}