Skip to content

Commit d88fdf5

Browse files
committed
Fixed tests for badger and epochs
1 parent d70da07 commit d88fdf5

File tree

4 files changed

+79
-76
lines changed

4 files changed

+79
-76
lines changed

engine/access/rpc/backend/backend_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_NoTransitionSpan() {
167167
epochBuilder := unittest.NewEpochBuilder(suite.T(), state)
168168
// build epoch 1
169169
// blocks in current state
170-
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit| <- G(S_E)
170+
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit|
171171
epochBuilder.
172172
BuildEpoch().
173173
CompleteEpoch()
@@ -181,9 +181,9 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_NoTransitionSpan() {
181181
suite.state.On("AtHeight", height).Return(state.AtHeight(height)).Once()
182182
}
183183

184-
// Take snapshot at height of block D (epoch1.heights[3]) for valid segment and valid snapshot
185-
// where it's sealing segment is B <- C <- D
186-
snap := state.AtHeight(epoch1.Range()[3])
184+
// Take snapshot at height of block D (epoch1.heights[2]) for valid segment and valid snapshot
185+
// where it's sealing segment is B <- C
186+
snap := state.AtHeight(epoch1.Range()[2])
187187
suite.state.On("Final").Return(snap).Once()
188188

189189
backend := New(
@@ -283,8 +283,8 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_TransitionSpans() {
283283
suite.Require().NoError(err)
284284
fmt.Println()
285285

286-
// we expect the endpoint to return last valid snapshot which is the snapshot at block D (height 3)
287-
expectedSnapshotBytes, err := convert.SnapshotToBytes(state.AtHeight(epoch1.Range()[3]))
286+
// we expect the endpoint to return last valid snapshot which is the snapshot at block C (height 2)
287+
expectedSnapshotBytes, err := convert.SnapshotToBytes(state.AtHeight(epoch1.Range()[2]))
288288
suite.Require().NoError(err)
289289
suite.Require().Equal(expectedSnapshotBytes, bytes)
290290
})
@@ -300,7 +300,7 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_PhaseTransitionSpan() {
300300
epochBuilder := unittest.NewEpochBuilder(suite.T(), state)
301301
// build epoch 1
302302
// blocks in current state
303-
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit| <- G(S_E)
303+
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit|
304304
epochBuilder.
305305
BuildEpoch().
306306
CompleteEpoch()
@@ -314,11 +314,11 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_PhaseTransitionSpan() {
314314
suite.state.On("AtHeight", height).Return(state.AtHeight(height))
315315
}
316316

317-
// Take snapshot at height of block E (epoch1.heights[4]) the sealing segment for this snapshot
318-
// is C(S_A) <- D(S_B) |setup| <- E(S_C) which spans the epoch setup phase. This will force
317+
// Take snapshot at height of block D (epoch1.heights[3]) the sealing segment for this snapshot
318+
// is C(S_A) <- D(S_B) |setup|) which spans the epoch setup phase. This will force
319319
// our RPC endpoint to return a snapshot at block D which is the snapshot at the boundary where the phase
320320
// transition happens.
321-
snap := state.AtHeight(epoch1.Range()[4])
321+
snap := state.AtHeight(epoch1.Range()[3])
322322
suite.state.On("Final").Return(snap).Once()
323323

324324
backend := New(
@@ -346,8 +346,8 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_PhaseTransitionSpan() {
346346
bytes, err := backend.GetLatestProtocolStateSnapshot(context.Background())
347347
suite.Require().NoError(err)
348348

349-
// we expect the endpoint to return last valid snapshot which is the snapshot at block D (height 3)
350-
expectedSnapshotBytes, err := convert.SnapshotToBytes(state.AtHeight(epoch1.Range()[3]))
349+
// we expect the endpoint to return last valid snapshot which is the snapshot at block C (height 2)
350+
expectedSnapshotBytes, err := convert.SnapshotToBytes(state.AtHeight(epoch1.Range()[2]))
351351
suite.Require().NoError(err)
352352
suite.Require().Equal(expectedSnapshotBytes, bytes)
353353
})
@@ -363,7 +363,7 @@ func (suite *Suite) TestGetLatestProtocolStateSnapshot_EpochTransitionSpan() {
363363
epochBuilder := unittest.NewEpochBuilder(suite.T(), state)
364364
// build epoch 1
365365
// blocks in current state
366-
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit| <- G(S_E)
366+
// P <- A(S_P-1) <- B(S_P) <- C(S_A) <- D(S_B) |setup| <- E(S_C) <- F(S_D) |commit|
367367
epochBuilder.BuildEpoch()
368368

369369
// add more blocks to our state in the commit phase, this will allow

state/protocol/badger/snapshot_test.go

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -262,34 +262,40 @@ func TestSealingSegment(t *testing.T) {
262262

263263
// test sealing segment for non-root segment with simple sealing structure
264264
// (no blocks in between reference block and latest sealed)
265-
// ROOT <- B1 <- B2(S1)
266-
// Expected sealing segment: [B1, B2], extra blocks: [ROOT]
265+
// ROOT <- B1 <- B2(R1) <- B3(S1)
266+
// Expected sealing segment: [B1, B2, B3], extra blocks: [ROOT]
267267
t.Run("non-root", func(t *testing.T) {
268268
util.RunWithFollowerProtocolState(t, rootSnapshot, func(db *badger.DB, state *bprotocol.FollowerState) {
269269
// build a block to seal
270270
block1 := unittest.BlockWithParentFixture(head)
271271
buildFinalizedBlock(t, state, block1)
272272

273-
// build a block sealing block1
274-
block2 := unittest.BlockWithParentFixture(block1.Header)
275273
receipt1, seal1 := unittest.ReceiptAndSealForBlock(block1)
276-
block2.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1), unittest.WithSeals(seal1)))
274+
275+
block2 := unittest.BlockWithParentFixture(block1.Header)
276+
block2.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1)))
277277
buildFinalizedBlock(t, state, block2)
278278

279-
segment, err := state.AtBlockID(block2.ID()).SealingSegment()
279+
// build a block sealing block1
280+
block3 := unittest.BlockWithParentFixture(block2.Header)
281+
282+
block3.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1)))
283+
buildFinalizedBlock(t, state, block3)
284+
285+
segment, err := state.AtBlockID(block3.ID()).SealingSegment()
280286
require.NoError(t, err)
281287

282288
require.Len(t, segment.ExtraBlocks, 1)
283289
assert.Equal(t, segment.ExtraBlocks[0].Header.Height, head.Height)
284290

285291
// build a valid child B3 to ensure we have a QC
286-
buildBlock(t, state, unittest.BlockWithParentFixture(block2.Header))
292+
buildBlock(t, state, unittest.BlockWithParentFixture(block3.Header))
287293

288294
// sealing segment should contain B1 and B2
289295
// B2 is reference of snapshot, B1 is latest sealed
290-
unittest.AssertEqualBlocksLenAndOrder(t, []*flow.Block{block1, block2}, segment.Blocks)
296+
unittest.AssertEqualBlocksLenAndOrder(t, []*flow.Block{block1, block2, block3}, segment.Blocks)
291297
assert.Len(t, segment.ExecutionResults, 1)
292-
assertSealingSegmentBlocksQueryableAfterBootstrap(t, state.AtBlockID(block2.ID()))
298+
assertSealingSegmentBlocksQueryableAfterBootstrap(t, state.AtBlockID(block3.ID()))
293299
})
294300
})
295301

@@ -304,22 +310,22 @@ func TestSealingSegment(t *testing.T) {
304310
block1 := unittest.BlockWithParentFixture(head)
305311
buildFinalizedBlock(t, state, block1)
306312

313+
receipt1, seal1 := unittest.ReceiptAndSealForBlock(block1)
314+
307315
parent := block1
308316
// build a large chain of intermediary blocks
309317
for i := 0; i < 100; i++ {
310318
next := unittest.BlockWithParentFixture(parent.Header)
319+
next.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1)))
311320
buildFinalizedBlock(t, state, next)
312321
parent = next
313322
}
314323

315324
// build the block sealing block 1
316325
blockN := unittest.BlockWithParentFixture(parent.Header)
317-
receipt1, seal1 := unittest.ReceiptAndSealForBlock(block1)
318-
blockN.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1), unittest.WithSeals(seal1)))
319-
buildFinalizedBlock(t, state, blockN)
320326

321-
// build a valid child B3 to ensure we have a QC
322-
buildFinalizedBlock(t, state, unittest.BlockWithParentFixture(blockN.Header))
327+
blockN.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1)))
328+
buildFinalizedBlock(t, state, blockN)
323329

324330
segment, err := state.AtBlockID(blockN.ID()).SealingSegment()
325331
require.NoError(t, err)
@@ -613,15 +619,16 @@ func TestSealingSegment_FailureCases(t *testing.T) {
613619
t.Run("sealing segment from block below local state root", func(t *testing.T) {
614620
// Step I: constructing bootstrapping snapshot with some short history:
615621
//
616-
// ╭───── finalized blocks ─────╮
617-
// <- b1 <- b2 <- b3(seal(b1)) <-
618-
// └── head ──┘
622+
// ╭───── finalized blocks ─────╮
623+
// <- b1 <- b2(result(b1)) <- b3(seal(b1)) <-
624+
// └── head ──┘
619625
//
620626
b1 := unittest.BlockWithParentFixture(sporkRoot) // construct block b1, append to state and finalize
627+
receipt, seal := unittest.ReceiptAndSealForBlock(b1)
621628
b2 := unittest.BlockWithParentFixture(b1.Header) // construct block b2, append to state and finalize
629+
b2.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt)))
622630
b3 := unittest.BlockWithParentFixture(b2.Header) // construct block b3 with seal for b1, append it to state and finalize
623-
receipt, seal := unittest.ReceiptAndSealForBlock(b1)
624-
b3.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt), unittest.WithSeals(seal)))
631+
b3.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal)))
625632

626633
multipleBlockSnapshot := snapshotAfter(t, sporkRootSnapshot, func(state *bprotocol.FollowerState) protocol.Snapshot {
627634
for _, b := range []*flow.Block{b1, b2, b3} {
@@ -788,15 +795,20 @@ func TestLatestSealedResult(t *testing.T) {
788795
block1 := unittest.BlockWithParentFixture(head)
789796

790797
block2 := unittest.BlockWithParentFixture(block1.Header)
798+
791799
receipt1, seal1 := unittest.ReceiptAndSealForBlock(block1)
792-
block2.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1), unittest.WithReceipts(receipt1)))
800+
block2.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1)))
793801
block3 := unittest.BlockWithParentFixture(block2.Header)
802+
block3.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1)))
794803

795804
receipt2, seal2 := unittest.ReceiptAndSealForBlock(block2)
796805
receipt3, seal3 := unittest.ReceiptAndSealForBlock(block3)
797806
block4 := unittest.BlockWithParentFixture(block3.Header)
798807
block4.SetPayload(unittest.PayloadFixture(
799808
unittest.WithReceipts(receipt2, receipt3),
809+
))
810+
block5 := unittest.BlockWithParentFixture(block4.Header)
811+
block5.SetPayload(unittest.PayloadFixture(
800812
unittest.WithSeals(seal2, seal3),
801813
))
802814

@@ -806,34 +818,37 @@ func TestLatestSealedResult(t *testing.T) {
806818
err = state.ExtendCertified(context.Background(), block2, block3.Header.QuorumCertificate())
807819
require.NoError(t, err)
808820

809-
// B1 <- B2(R1,S1)
810-
// querying B2 should return result R1, seal S1
821+
err = state.ExtendCertified(context.Background(), block3, block4.Header.QuorumCertificate())
822+
require.NoError(t, err)
823+
824+
// B1 <- B2(R1) <- B3(S1)
825+
// querying B3 should return result R1, seal S1
811826
t.Run("reference block contains seal", func(t *testing.T) {
812-
gotResult, gotSeal, err := state.AtBlockID(block2.ID()).SealedResult()
827+
gotResult, gotSeal, err := state.AtBlockID(block3.ID()).SealedResult()
813828
require.NoError(t, err)
814829
assert.Equal(t, block2.Payload.Results[0], gotResult)
815-
assert.Equal(t, block2.Payload.Seals[0], gotSeal)
830+
assert.Equal(t, block3.Payload.Seals[0], gotSeal)
816831
})
817832

818-
err = state.ExtendCertified(context.Background(), block3, block4.Header.QuorumCertificate())
833+
err = state.ExtendCertified(context.Background(), block4, block5.Header.QuorumCertificate())
819834
require.NoError(t, err)
820835

821-
// B1 <- B2(R1,S1) <- B3
836+
// B1 <- B2(S1) <- B3(S1)
822837
// querying B3 should still return (R1,S1) even though they are in parent block
823838
t.Run("reference block contains no seal", func(t *testing.T) {
824-
gotResult, gotSeal, err := state.AtBlockID(block2.ID()).SealedResult()
839+
gotResult, gotSeal, err := state.AtBlockID(block3.ID()).SealedResult()
825840
require.NoError(t, err)
826841
assert.Equal(t, &receipt1.ExecutionResult, gotResult)
827842
assert.Equal(t, seal1, gotSeal)
828843
})
829844

830-
// B1 <- B2(R1,S1) <- B3 <- B4(R2,S2,R3,S3)
845+
// B1 <- B2(R1) <- B3(S1) <- B4(R2,R3) <- B5(S2,S3)
831846
// There are two seals in B4 - should return latest by height (S3,R3)
832847
t.Run("reference block contains multiple seals", func(t *testing.T) {
833-
err = state.ExtendCertified(context.Background(), block4, unittest.CertifyBlock(block4.Header))
848+
err = state.ExtendCertified(context.Background(), block5, unittest.CertifyBlock(block5.Header))
834849
require.NoError(t, err)
835850

836-
gotResult, gotSeal, err := state.AtBlockID(block4.ID()).SealedResult()
851+
gotResult, gotSeal, err := state.AtBlockID(block5.ID()).SealedResult()
837852
require.NoError(t, err)
838853
assert.Equal(t, &receipt3.ExecutionResult, gotResult)
839854
assert.Equal(t, seal3, gotSeal)

state/protocol/badger/state_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,25 @@ func TestBootstrapNonRoot(t *testing.T) {
260260
require.NoError(t, err)
261261

262262
// should be able to bootstrap from snapshot after sealing a non-root block
263-
// ROOT <- B1 <- B2(S1) <- CHILD
263+
// ROOT <- B1 <- B2(R1) <- B3(S1) <- CHILD
264264
t.Run("with sealed block", func(t *testing.T) {
265265
after := snapshotAfter(t, rootSnapshot, func(state *bprotocol.FollowerState) protocol.Snapshot {
266266
block1 := unittest.BlockWithParentFixture(rootBlock)
267267
buildFinalizedBlock(t, state, block1)
268268

269269
receipt1, seal1 := unittest.ReceiptAndSealForBlock(block1)
270270
block2 := unittest.BlockWithParentFixture(block1.Header)
271-
block2.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1), unittest.WithReceipts(receipt1)))
271+
block2.SetPayload(unittest.PayloadFixture(unittest.WithReceipts(receipt1)))
272272
buildFinalizedBlock(t, state, block2)
273273

274-
child := unittest.BlockWithParentFixture(block2.Header)
274+
block3 := unittest.BlockWithParentFixture(block2.Header)
275+
block3.SetPayload(unittest.PayloadFixture(unittest.WithSeals(seal1)))
276+
buildFinalizedBlock(t, state, block3)
277+
278+
child := unittest.BlockWithParentFixture(block3.Header)
275279
buildBlock(t, state, child)
276280

277-
return state.AtBlockID(block2.ID())
281+
return state.AtBlockID(block3.ID())
278282
})
279283

280284
bootstrap(t, after, func(state *bprotocol.State, err error) {

utils/unittest/epoch_builder.go

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ func (builder *EpochBuilder) EpochHeights(counter uint64) (*EpochHeights, bool)
123123
//
124124
// | EPOCH N |
125125
// | |
126-
// P A B C D E F G
126+
// P A B C D E F
127127
//
128-
// +------------+ +------------+ +-----------+ +-----------+ +----------+ +----------+ +----------+----------+
129-
// | ER(P-1) |->| ER(P) |->| ER(A) |->| ER(B) |->| ER(C) |->| ER(D) |->| ER(E) | ER(F) |
130-
// | S(ER(P-2)) | | S(ER(P-1)) | | S(ER(P)) | | S(ER(A)) | | S(ER(B)) | | S(ER(C)) | | S(ER(D)) | S(ER(E)) |
131-
// +------------+ +------------+ +-----------+ +-----------+ +----------+ +----------+ +----------+----------+
132-
// | |
133-
// Setup Commit
128+
// +------------+ +------------+ +-----------+ +-----------+ +----------+ +----------+ +----------+
129+
// | ER(P-1) |->| ER(P) |->| ER(A) |->| ER(B) |->| ER(C) |->| ER(D) |->| ER(E) |
130+
// | S(ER(P-2)) | | S(ER(P-1)) | | S(ER(P)) | | S(ER(A)) | | S(ER(B)) | | S(ER(C)) | | S(ER(D)) |
131+
// +------------+ +------------+ +-----------+ +-----------+ +----------+ +----------+ +----------+
132+
// | |
133+
// Setup Commit
134134
//
135135
// ER(X) := ExecutionReceipt for block X
136136
// S(ER(X)) := Seal for the ExecutionResult contained in ER(X) (seals block X)
@@ -142,11 +142,11 @@ func (builder *EpochBuilder) EpochHeights(counter uint64) (*EpochHeights, bool)
142142
// block A. This is because the root block is sealed from genesis and we
143143
// can't insert duplicate seals.
144144
//
145-
// D contains a seal for block B containing the EpochSetup service event.
146-
// E contains a QC for D, which causes the EpochSetup to become activated.
145+
// D contains a seal for block B containing the EpochSetup service event,
146+
// processing D causes the EpochSetup to become activated.
147147
//
148148
// F contains a seal for block D containing the EpochCommit service event.
149-
// G contains a QC for F, which causes the EpochCommit to become activated.
149+
// processing F causes the EpochCommit to become activated.
150150
//
151151
// To build a sequence of epochs, we call BuildEpoch, then CompleteEpoch, and so on.
152152
//
@@ -295,30 +295,14 @@ func (builder *EpochBuilder) BuildEpoch() *EpochBuilder {
295295
Seals: []*flow.Seal{sealForD},
296296
})
297297
builder.addBlock(F)
298-
// create receipt for block F
299-
receiptF := ReceiptForBlockFixture(F)
300-
301-
// build block G
302-
// G contains a seal for block E and a receipt for block F
303-
G := BlockWithParentFixture(F.Header)
304-
sealForE := Seal.Fixture(
305-
Seal.WithResult(&receiptE.ExecutionResult),
306-
)
307-
G.SetPayload(flow.Payload{
308-
Receipts: []*flow.ExecutionReceiptMeta{receiptF.Meta()},
309-
Results: []*flow.ExecutionResult{&receiptF.ExecutionResult},
310-
Seals: []*flow.Seal{sealForE},
311-
})
312-
313-
builder.addBlock(G)
314298

315299
// cache information about the built epoch
316300
builder.built[counter] = &EpochHeights{
317301
Counter: counter,
318302
Staking: A.Height,
319-
Setup: E.Header.Height,
320-
Committed: G.Header.Height,
321-
CommittedFinal: G.Header.Height,
303+
Setup: D.Header.Height,
304+
Committed: F.Header.Height,
305+
CommittedFinal: F.Header.Height,
322306
}
323307

324308
return builder

0 commit comments

Comments
 (0)