Skip to content

Commit b08b629

Browse files
authored
beacon/blsync: test validated finality (#32633)
This PR improves `TestBlockSync` so that it also tests the finality update validation. Note: to this date four long and complex (at least partly AI generated) PRs arrived that did something related to testing finality but honestly we do not need a bloated "comprehensive" test to test a trivial feature because maintaining these tests can also be a pain over the long term. This PR adds some sufficient sanity checks to detect if finality ever gets broken by a future change.
1 parent 2b3d617 commit b08b629

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

beacon/blsync/block_sync_test.go

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var (
3232
testServer2 = testServer("testServer2")
3333

3434
testBlock1 = types.NewBeaconBlock(&deneb.BeaconBlock{
35-
Slot: 123,
35+
Slot: 127,
3636
Body: deneb.BeaconBlockBody{
3737
ExecutionPayload: deneb.ExecutionPayload{
3838
BlockNumber: 456,
@@ -41,14 +41,22 @@ var (
4141
},
4242
})
4343
testBlock2 = types.NewBeaconBlock(&deneb.BeaconBlock{
44-
Slot: 124,
44+
Slot: 128,
4545
Body: deneb.BeaconBlockBody{
4646
ExecutionPayload: deneb.ExecutionPayload{
4747
BlockNumber: 457,
4848
BlockHash: zrntcommon.Hash32(common.HexToHash("011703f39c664efc1c6cf5f49ca09b595581eec572d4dfddd3d6179a9e63e655")),
4949
},
5050
},
5151
})
52+
testFinal1 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
53+
BlockNumber: 395,
54+
BlockHash: zrntcommon.Hash32(common.HexToHash("abbe7625624bf8ddd84723709e2758956289465dd23475f02387e0854942666")),
55+
})
56+
testFinal2 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
57+
BlockNumber: 420,
58+
BlockHash: zrntcommon.Hash32(common.HexToHash("9182a6ef8723654de174283750932ccc092378549836bf4873657eeec474598")),
59+
})
5260
)
5361

5462
type testServer string
@@ -66,29 +74,37 @@ func TestBlockSync(t *testing.T) {
6674
ts.AddServer(testServer1, 1)
6775
ts.AddServer(testServer2, 1)
6876

69-
expHeadBlock := func(expHead *types.BeaconBlock) {
77+
expHeadEvent := func(expHead *types.BeaconBlock, expFinal *types.ExecutionHeader) {
7078
t.Helper()
7179
var expNumber, headNumber uint64
80+
var expFinalHash, finalHash common.Hash
7281
if expHead != nil {
7382
p, err := expHead.ExecutionPayload()
7483
if err != nil {
7584
t.Fatalf("expHead.ExecutionPayload() failed: %v", err)
7685
}
7786
expNumber = p.NumberU64()
7887
}
88+
if expFinal != nil {
89+
expFinalHash = expFinal.BlockHash()
90+
}
7991
select {
8092
case event := <-headCh:
8193
headNumber = event.Block.NumberU64()
94+
finalHash = event.Finalized
8295
default:
8396
}
8497
if headNumber != expNumber {
8598
t.Errorf("Wrong head block, expected block number %d, got %d)", expNumber, headNumber)
8699
}
100+
if finalHash != expFinalHash {
101+
t.Errorf("Wrong finalized block, expected block hash %064x, got %064x)", expFinalHash[:], finalHash[:])
102+
}
87103
}
88104

89105
// no block requests expected until head tracker knows about a head
90106
ts.Run(1)
91-
expHeadBlock(nil)
107+
expHeadEvent(nil, nil)
92108

93109
// set block 1 as prefetch head, announced by server 2
94110
head1 := blockHeadInfo(testBlock1)
@@ -103,12 +119,13 @@ func TestBlockSync(t *testing.T) {
103119
ts.AddAllowance(testServer2, 1)
104120
ts.Run(3)
105121
// head block still not expected as the fetched block is not the validated head yet
106-
expHeadBlock(nil)
122+
expHeadEvent(nil, nil)
107123

108124
// set as validated head, expect no further requests but block 1 set as head block
109125
ht.validated.Header = testBlock1.Header()
126+
ht.finalized, ht.finalizedPayload = testBlock1.Header(), testFinal1
110127
ts.Run(4)
111-
expHeadBlock(testBlock1)
128+
expHeadEvent(testBlock1, testFinal1)
112129

113130
// set block 2 as prefetch head, announced by server 1
114131
head2 := blockHeadInfo(testBlock2)
@@ -126,17 +143,26 @@ func TestBlockSync(t *testing.T) {
126143
// expect req2 retry to server 2
127144
ts.Run(7, testServer2, sync.ReqBeaconBlock(head2.BlockRoot))
128145
// now head block should be unavailable again
129-
expHeadBlock(nil)
146+
expHeadEvent(nil, nil)
130147

131148
// valid response, now head block should be block 2 immediately as it is already validated
149+
// but head event is still not expected because an epoch boundary was crossed and the
150+
// expected finality update has not arrived yet
132151
ts.RequestEvent(request.EvResponse, ts.Request(7, 1), testBlock2)
133152
ts.Run(8)
134-
expHeadBlock(testBlock2)
153+
expHeadEvent(nil, nil)
154+
155+
// expected finality update arrived, now a head event is expected
156+
ht.finalized, ht.finalizedPayload = testBlock2.Header(), testFinal2
157+
ts.Run(9)
158+
expHeadEvent(testBlock2, testFinal2)
135159
}
136160

137161
type testHeadTracker struct {
138-
prefetch types.HeadInfo
139-
validated types.SignedHeader
162+
prefetch types.HeadInfo
163+
validated types.SignedHeader
164+
finalized types.Header
165+
finalizedPayload *types.ExecutionHeader
140166
}
141167

142168
func (h *testHeadTracker) PrefetchHead() types.HeadInfo {
@@ -151,13 +177,14 @@ func (h *testHeadTracker) ValidatedOptimistic() (types.OptimisticUpdate, bool) {
151177
}, h.validated.Header != (types.Header{})
152178
}
153179

154-
// TODO add test case for finality
155180
func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
156-
finalized := types.NewExecutionHeader(new(deneb.ExecutionPayloadHeader))
181+
if h.validated.Header == (types.Header{}) || h.finalizedPayload == nil {
182+
return types.FinalityUpdate{}, false
183+
}
157184
return types.FinalityUpdate{
158-
Attested: types.HeaderWithExecProof{Header: h.validated.Header},
159-
Finalized: types.HeaderWithExecProof{PayloadHeader: finalized},
185+
Attested: types.HeaderWithExecProof{Header: h.finalized},
186+
Finalized: types.HeaderWithExecProof{Header: h.finalized, PayloadHeader: h.finalizedPayload},
160187
Signature: h.validated.Signature,
161188
SignatureSlot: h.validated.SignatureSlot,
162-
}, h.validated.Header != (types.Header{})
189+
}, true
163190
}

0 commit comments

Comments
 (0)