Skip to content

Commit bc3584e

Browse files
committed
test stability
1 parent 917e3c9 commit bc3584e

File tree

1 file changed

+84
-21
lines changed

1 file changed

+84
-21
lines changed

test/e2e/failover_e2e_test.go

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,15 @@ func TestLeaseFailoverE2E(t *testing.T) {
219219
return err == nil
220220
}, time.Second, 100*time.Millisecond)
221221

222-
lastDABlockNewLeader = queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
223-
224222
genesisHeight := state.InitialHeight
225223
verifyNoDoubleSigning(t, clusterNodes, genesisHeight, state.LastBlockHeight)
226224

227-
// wait for the next DA block to ensure all blocks are propagated
228-
require.Eventually(t, func() bool {
229-
before := lastDABlockNewLeader
230-
lastDABlockNewLeader = queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
231-
return before < lastDABlockNewLeader
232-
}, 2*must(time.ParseDuration(DefaultDABlockTime)), 100*time.Millisecond)
233-
225+
// wait for the DA submitter to catch up — poll until all blocks are on DA
234226
t.Log("+++ Verifying no DA gaps...")
235-
verifyDABlocks(t, 1, lastDABlockNewLeader, env.SequencerJWT, env.Endpoints.GetDAAddress(), genesisHeight, state.LastBlockHeight)
227+
require.EventuallyWithT(t, func(collect *assert.CollectT) {
228+
lastDA := queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
229+
verifyDABlocksCollect(collect, 1, lastDA, env.SequencerJWT, env.Endpoints.GetDAAddress(), genesisHeight, state.LastBlockHeight)
230+
}, 3*must(time.ParseDuration(DefaultDABlockTime)), 500*time.Millisecond)
236231

237232
// Cleanup processes
238233
clusterNodes.killAll()
@@ -508,22 +503,16 @@ func TestHASequencerRollingRestartE2E(t *testing.T) {
508503
return err == nil
509504
}, time.Second, 100*time.Millisecond)
510505

511-
lastDABlock := queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
512-
513506
genesisHeight := state.InitialHeight
514507
verifyNoDoubleSigning(t, clusterNodes, genesisHeight, state.LastBlockHeight)
515508
t.Log("+++ No double-signing detected ✓")
516509

517-
// Wait for the next DA block to ensure all blocks are propagated
518-
require.Eventually(t, func() bool {
519-
before := lastDABlock
520-
lastDABlock = queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
521-
return before < lastDABlock
522-
}, 2*must(time.ParseDuration(DefaultDABlockTime)), 100*time.Millisecond)
523-
524-
// Verify no DA gaps
510+
// Wait for the DA submitter to catch up — poll until all blocks are on DA
525511
t.Log("+++ Verifying no DA gaps...")
526-
verifyDABlocks(t, 1, lastDABlock, env.SequencerJWT, env.Endpoints.GetDAAddress(), genesisHeight, state.LastBlockHeight)
512+
require.EventuallyWithT(t, func(collect *assert.CollectT) {
513+
lastDA := queryLastDAHeight(t, env.SequencerJWT, env.Endpoints.GetDAAddress())
514+
verifyDABlocksCollect(collect, 1, lastDA, env.SequencerJWT, env.Endpoints.GetDAAddress(), genesisHeight, state.LastBlockHeight)
515+
}, 3*must(time.ParseDuration(DefaultDABlockTime)), 500*time.Millisecond)
527516
t.Log("+++ No DA gaps detected ✓")
528517

529518
// Cleanup processes
@@ -611,6 +600,80 @@ func verifyDABlocks(t *testing.T, daStartHeight, lastDABlock uint64, jwtSecret s
611600
}
612601
}
613602

603+
// verifyDABlocksCollect is like verifyDABlocks but uses assert.CollectT so it can be retried
604+
// inside require.EventuallyWithT.
605+
func verifyDABlocksCollect(collect *assert.CollectT, daStartHeight, lastDABlock uint64, jwtSecret string, daAddress string, genesisHeight, lastEVBlock uint64) {
606+
ctx := context.Background()
607+
blobClient, err := blobrpc.NewClient(ctx, daAddress, jwtSecret, "")
608+
if !assert.NoError(collect, err) {
609+
return
610+
}
611+
defer blobClient.Close()
612+
613+
ns, err := libshare.NewNamespaceFromBytes(coreda.NamespaceFromString(DefaultDANamespace).Bytes())
614+
if !assert.NoError(collect, err) {
615+
return
616+
}
617+
evHeightsToEvBlockParts := make(map[uint64]int)
618+
deduplicationCache := make(map[string]uint64)
619+
620+
for daHeight := daStartHeight; daHeight <= lastDABlock; daHeight++ {
621+
blobs, err := blobClient.Blob.GetAll(ctx, daHeight, []libshare.Namespace{ns})
622+
if err != nil {
623+
if strings.Contains(err.Error(), "blob: not found") {
624+
continue
625+
}
626+
assert.NoError(collect, err, "height %d/%d", daHeight, lastDABlock)
627+
return
628+
}
629+
if len(blobs) == 0 {
630+
continue
631+
}
632+
633+
for _, blob := range blobs {
634+
if evHeight, hash, blobType := extractBlockHeightRaw(blob.Data()); evHeight != 0 {
635+
_ = blobType
636+
if height, ok := deduplicationCache[hash.String()]; ok {
637+
assert.Equal(collect, evHeight, height)
638+
continue
639+
}
640+
assert.GreaterOrEqual(collect, evHeight, genesisHeight)
641+
deduplicationCache[hash.String()] = evHeight
642+
evHeightsToEvBlockParts[evHeight]++
643+
}
644+
}
645+
}
646+
647+
for h := genesisHeight; h <= lastEVBlock; h++ {
648+
assert.NotEmpty(collect, evHeightsToEvBlockParts[h], "missing block on DA for height %d/%d", h, lastEVBlock)
649+
assert.Less(collect, evHeightsToEvBlockParts[h], 3, "duplicate block on DA for height %d/%d", h, lastEVBlock)
650+
}
651+
}
652+
653+
// extractBlockHeightRaw is like extractBlockHeight but doesn't require *testing.T.
654+
func extractBlockHeightRaw(blob []byte) (uint64, types.Hash, string) {
655+
if len(blob) == 0 {
656+
return 0, nil, ""
657+
}
658+
var headerPb pb.SignedHeader
659+
if err := proto.Unmarshal(blob, &headerPb); err == nil {
660+
var signedHeader types.SignedHeader
661+
if err := signedHeader.FromProto(&headerPb); err == nil {
662+
if err := signedHeader.Header.ValidateBasic(); err == nil {
663+
return signedHeader.Height(), signedHeader.Hash(), "header"
664+
}
665+
}
666+
}
667+
668+
var signedData types.SignedData
669+
if err := signedData.UnmarshalBinary(blob); err == nil {
670+
if signedData.Metadata != nil {
671+
return signedData.Height(), signedData.Hash(), "data"
672+
}
673+
}
674+
return 0, nil, ""
675+
}
676+
614677
// extractBlockHeight attempts to decode a blob as SignedHeader or SignedData and extract the block height
615678
func extractBlockHeight(t *testing.T, blob []byte) (uint64, types.Hash, string) {
616679
t.Helper()

0 commit comments

Comments
 (0)