Skip to content

Commit 1b28ff5

Browse files
author
colinlyguo
committed
address comments
1 parent c76e613 commit 1b28ff5

File tree

1 file changed

+44
-68
lines changed

1 file changed

+44
-68
lines changed

rollup/internal/controller/relayer/l2_relayer_sanity.go

Lines changed: 44 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -53,83 +53,70 @@ func (r *Layer2Relayer) sanityChecksBeforeConstructingTransaction(batchesToSubmi
5353
return fmt.Errorf("no batches to submit")
5454
}
5555

56-
// Basic validation
57-
if err := r.validateBatchesBasic(batchesToSubmit); err != nil {
58-
return err
59-
}
60-
61-
// Codec version validation
62-
if err := r.validateCodecVersions(batchesToSubmit); err != nil {
63-
return err
64-
}
65-
6656
// Get previous chunk for continuity check
6757
prevChunk, err := r.getPreviousChunkForContinuity(batchesToSubmit[0])
6858
if err != nil {
6959
return err
7060
}
7161

72-
// Validate each batch in detail
73-
if err := r.validateBatchesDetailed(batchesToSubmit, prevChunk); err != nil {
62+
// Validate batches (including basic, codec versions, and detailed checks)
63+
if err := r.validateBatches(batchesToSubmit, prevChunk); err != nil {
7464
return err
7565
}
7666

7767
log.Info("Sanity check passed before constructing transaction", "batches count", len(batchesToSubmit))
7868
return nil
7969
}
8070

81-
// validateBatchesBasic performs basic validation on all batches
82-
func (r *Layer2Relayer) validateBatchesBasic(batchesToSubmit []*dbBatchWithChunks) error {
71+
// getPreviousChunkForContinuity gets the previous chunk for block continuity check
72+
func (r *Layer2Relayer) getPreviousChunkForContinuity(firstBatch *dbBatchWithChunks) (*orm.Chunk, error) {
73+
firstChunk := firstBatch.Chunks[0]
74+
if firstChunk.Index == 0 {
75+
return nil, fmt.Errorf("genesis chunk should not be in normal batch submission flow, chunk index: %d", firstChunk.Index)
76+
}
77+
78+
prevChunk, err := r.chunkOrm.GetChunkByIndex(r.ctx, firstChunk.Index-1)
79+
if err != nil {
80+
return nil, fmt.Errorf("failed to get previous chunk %d for continuity check: %w", firstChunk.Index-1, err)
81+
}
82+
83+
return prevChunk, nil
84+
}
85+
86+
// validateBatches performs validation on all batches including basic checks, codec version consistency, and detailed checks.
87+
func (r *Layer2Relayer) validateBatches(batchesToSubmit []*dbBatchWithChunks, initialPrevChunk *orm.Chunk) error {
88+
// Basic validation: ensure each batch and its chunks are non-empty.
8389
for i, batch := range batchesToSubmit {
8490
if batch == nil || batch.Batch == nil {
8591
return fmt.Errorf("batch %d is nil", i)
8692
}
87-
8893
if len(batch.Chunks) == 0 {
8994
return fmt.Errorf("batch %d has no chunks", batch.Batch.Index)
9095
}
9196
}
92-
return nil
93-
}
9497

95-
// validateCodecVersions checks all batches have the same codec version
96-
func (r *Layer2Relayer) validateCodecVersions(batchesToSubmit []*dbBatchWithChunks) error {
98+
// Check that all batches have the same codec version.
9799
firstBatchCodecVersion := batchesToSubmit[0].Batch.CodecVersion
98100
for _, batch := range batchesToSubmit {
99101
if batch.Batch.CodecVersion != firstBatchCodecVersion {
100102
return fmt.Errorf("batch %d has different codec version %d, expected %d", batch.Batch.Index, batch.Batch.CodecVersion, firstBatchCodecVersion)
101103
}
102104
}
103-
return nil
104-
}
105-
106-
// getPreviousChunkForContinuity gets the previous chunk for block continuity check
107-
func (r *Layer2Relayer) getPreviousChunkForContinuity(firstBatch *dbBatchWithChunks) (*orm.Chunk, error) {
108-
firstChunk := firstBatch.Chunks[0]
109-
if firstChunk.Index == 0 {
110-
return nil, fmt.Errorf("genesis chunk should not be in normal batch submission flow, chunk index: %d", firstChunk.Index)
111-
}
112105

113-
prevChunk, err := r.chunkOrm.GetChunkByIndex(r.ctx, firstChunk.Index-1)
114-
if err != nil {
115-
return nil, fmt.Errorf("failed to get previous chunk %d for continuity check: %w", firstChunk.Index-1, err)
116-
}
117-
118-
return prevChunk, nil
119-
}
120-
121-
// validateBatchesDetailed performs detailed validation on each batch
122-
func (r *Layer2Relayer) validateBatchesDetailed(batchesToSubmit []*dbBatchWithChunks, prevChunkFromPrevBatch *orm.Chunk) error {
106+
// Validate each batch in detail, updating the previous chunk as we go.
107+
currentPrevChunk := initialPrevChunk
123108
for i, batch := range batchesToSubmit {
124-
if err := r.validateSingleBatch(batch, i, batchesToSubmit, prevChunkFromPrevBatch); err != nil {
109+
if err := r.validateSingleBatch(batch, i, batchesToSubmit, currentPrevChunk); err != nil {
125110
return err
126111
}
112+
// Update the previous chunk to the last chunk of this batch for the next batch.
113+
currentPrevChunk = batch.Chunks[len(batch.Chunks)-1]
127114
}
128115
return nil
129116
}
130117

131118
// validateSingleBatch validates a single batch and its chunks
132-
func (r *Layer2Relayer) validateSingleBatch(batch *dbBatchWithChunks, i int, allBatches []*dbBatchWithChunks, prevChunkFromPrevBatch *orm.Chunk) error {
119+
func (r *Layer2Relayer) validateSingleBatch(batch *dbBatchWithChunks, i int, allBatches []*dbBatchWithChunks, prevChunk *orm.Chunk) error {
133120
// Validate batch fields
134121
if err := r.validateBatchFields(batch, i, allBatches); err != nil {
135122
return err
@@ -141,7 +128,7 @@ func (r *Layer2Relayer) validateSingleBatch(batch *dbBatchWithChunks, i int, all
141128
}
142129

143130
// Validate chunks
144-
if err := r.validateBatchChunks(batch, i, allBatches, prevChunkFromPrevBatch); err != nil {
131+
if err := r.validateBatchChunks(batch, prevChunk); err != nil {
145132
return err
146133
}
147134

@@ -191,80 +178,69 @@ func (r *Layer2Relayer) validateBatchFields(batch *dbBatchWithChunks, i int, all
191178
}
192179

193180
// validateBatchChunks validates all chunks in a batch
194-
func (r *Layer2Relayer) validateBatchChunks(batch *dbBatchWithChunks, i int, allBatches []*dbBatchWithChunks, prevChunkFromPrevBatch *orm.Chunk) error {
195-
// Check all chunks in this batch have the same codec version as the batch
181+
func (r *Layer2Relayer) validateBatchChunks(batch *dbBatchWithChunks, prevChunk *orm.Chunk) error {
182+
// Check codec version consistency.
196183
for _, chunk := range batch.Chunks {
197184
if chunk.CodecVersion != batch.Batch.CodecVersion {
198185
return fmt.Errorf("batch %d chunk %d has different codec version %d, expected %d", batch.Batch.Index, chunk.Index, chunk.CodecVersion, batch.Batch.CodecVersion)
199186
}
200187
}
201188

202189
for j, chunk := range batch.Chunks {
203-
if err := r.validateSingleChunk(chunk, j, batch, i, allBatches, prevChunkFromPrevBatch); err != nil {
204-
return err
190+
if err := r.validateSingleChunk(chunk, prevChunk); err != nil {
191+
return fmt.Errorf("batch %d chunk %d: %w", batch.Batch.Index, j, err)
205192
}
193+
// Update the previous chunk to the current one for the next chunk.
194+
prevChunk = chunk
206195
}
207196

208197
return nil
209198
}
210199

211200
// validateSingleChunk validates a single chunk
212-
func (r *Layer2Relayer) validateSingleChunk(chunk *orm.Chunk, chunkIndex int, batch *dbBatchWithChunks, i int, allBatches []*dbBatchWithChunks, prevChunkFromPrevBatch *orm.Chunk) error {
201+
func (r *Layer2Relayer) validateSingleChunk(chunk *orm.Chunk, prevChunk *orm.Chunk) error {
213202
if chunk == nil {
214-
return fmt.Errorf("batch %d chunk %d is nil", batch.Batch.Index, chunkIndex)
203+
return fmt.Errorf("chunk is nil")
215204
}
216205

217206
chunkHash := common.HexToHash(chunk.Hash)
218207
if chunkHash == (common.Hash{}) {
219-
return fmt.Errorf("batch %d chunk %d hash is zero", batch.Batch.Index, chunk.Index)
220-
}
221-
222-
// Get previous chunk for continuity check
223-
var prevChunk *orm.Chunk
224-
if chunkIndex > 0 {
225-
prevChunk = batch.Chunks[chunkIndex-1]
226-
} else if i == 0 {
227-
prevChunk = prevChunkFromPrevBatch
228-
} else if i > 0 {
229-
// Use the last chunk from the previous batch
230-
prevBatch := allBatches[i-1]
231-
prevChunk = prevBatch.Chunks[len(prevBatch.Chunks)-1]
208+
return fmt.Errorf("chunk %d hash is zero", chunk.Index)
232209
}
233210

234211
// Check chunk index is sequential
235212
if chunk.Index != prevChunk.Index+1 {
236-
return fmt.Errorf("batch %d chunk %d index is not sequential: prev chunk index %d, current chunk index %d", batch.Batch.Index, chunkIndex, prevChunk.Index, chunk.Index)
213+
return fmt.Errorf("chunk index is not sequential: prev chunk index %d, current chunk index %d", prevChunk.Index, chunk.Index)
237214
}
238215

239216
// Check L1 messages popped continuity
240217
expectedPoppedBefore := prevChunk.TotalL1MessagesPoppedBefore + prevChunk.TotalL1MessagesPoppedInChunk
241218
if chunk.TotalL1MessagesPoppedBefore != expectedPoppedBefore {
242-
return fmt.Errorf("batch %d chunk %d L1 messages popped before is incorrect: expected %d, got %d",
243-
batch.Batch.Index, chunk.Index, expectedPoppedBefore, chunk.TotalL1MessagesPoppedBefore)
219+
return fmt.Errorf("L1 messages popped before is incorrect: expected %d, got %d", expectedPoppedBefore, chunk.TotalL1MessagesPoppedBefore)
244220
}
245221

246222
if chunk.StartBlockNumber == 0 && chunk.EndBlockNumber == 0 {
247-
return fmt.Errorf("batch %d chunk %d has zero block range", batch.Batch.Index, chunk.Index)
223+
return fmt.Errorf("chunk %d has zero block range", chunk.Index)
248224
}
249225

250226
if chunk.StartBlockNumber > chunk.EndBlockNumber {
251-
return fmt.Errorf("batch %d chunk %d has invalid block range: start %d > end %d", batch.Batch.Index, chunk.Index, chunk.StartBlockNumber, chunk.EndBlockNumber)
227+
return fmt.Errorf("chunk %d has invalid block range: start %d > end %d", chunk.Index, chunk.StartBlockNumber, chunk.EndBlockNumber)
252228
}
253229

254230
// Check chunk hash fields
255231
startBlockHash := common.HexToHash(chunk.StartBlockHash)
256232
if startBlockHash == (common.Hash{}) {
257-
return fmt.Errorf("batch %d chunk %d start block hash is zero", batch.Batch.Index, chunk.Index)
233+
return fmt.Errorf("chunk %d start block hash is zero", chunk.Index)
258234
}
259235

260236
endBlockHash := common.HexToHash(chunk.EndBlockHash)
261237
if endBlockHash == (common.Hash{}) {
262-
return fmt.Errorf("batch %d chunk %d end block hash is zero", batch.Batch.Index, chunk.Index)
238+
return fmt.Errorf("chunk %d end block hash is zero", chunk.Index)
263239
}
264240

265241
// Check chunk continuity: previous chunk's end block number + 1 should equal current chunk's start block number
266242
if prevChunk.EndBlockNumber+1 != chunk.StartBlockNumber {
267-
return fmt.Errorf("batch %d chunk %d is not continuous with previous chunk: prev chunk %d end block %d, current chunk start block %d", batch.Batch.Index, chunk.Index, prevChunk.Index, prevChunk.EndBlockNumber, chunk.StartBlockNumber)
243+
return fmt.Errorf("chunk is not continuous with previous chunk %d: prev end block %d, current start block %d", prevChunk.Index, prevChunk.EndBlockNumber, chunk.StartBlockNumber)
268244
}
269245

270246
return nil

0 commit comments

Comments
 (0)