Skip to content

Commit

Permalink
add more logs to debug
Browse files Browse the repository at this point in the history
  • Loading branch information
colinlyguo committed Jul 16, 2024
1 parent aa76eb7 commit 4befe9f
Showing 1 changed file with 81 additions and 20 deletions.
101 changes: 81 additions & 20 deletions rollup/rollup_sync_service/rollup_sync_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,23 +445,34 @@ func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.Chun
// Note: This function is compatible with both "finalize by batch" and "finalize by bundle" methods.
// In "finalize by bundle", only the last batch of each bundle is fully verified.
func validateBatch(event *L1FinalizeBatchEvent, parentBatchMeta *rawdb.FinalizedBatchMeta, chunks []*encoding.Chunk, chainCfg *params.ChainConfig, stack *node.Node, lastBatch bool) (uint64, *rawdb.FinalizedBatchMeta, error) {
log.Info("Starting validateBatch", "batchIndex", event.BatchIndex.Uint64(), "lastBatch", lastBatch)

if len(chunks) == 0 {
log.Error("Invalid argument: length of chunks is 0", "batchIndex", event.BatchIndex.Uint64())
return 0, nil, fmt.Errorf("invalid argument: length of chunks is 0, batch index: %v", event.BatchIndex.Uint64())
}

startChunk := chunks[0]
if len(startChunk.Blocks) == 0 {
log.Error("Invalid argument: block count of start chunk is 0", "batchIndex", event.BatchIndex.Uint64())
return 0, nil, fmt.Errorf("invalid argument: block count of start chunk is 0, batch index: %v", event.BatchIndex.Uint64())
}
startBlock := startChunk.Blocks[0]

endChunk := chunks[len(chunks)-1]
if len(endChunk.Blocks) == 0 {
log.Error("Invalid argument: block count of end chunk is 0", "batchIndex", event.BatchIndex.Uint64())
return 0, nil, fmt.Errorf("invalid argument: block count of end chunk is 0, batch index: %v", event.BatchIndex.Uint64())
}
endBlock := endChunk.Blocks[len(endChunk.Blocks)-1]

// Note: All params of batch are calculated locally based on the block data.
log.Info("Batch details",
"batchIndex", event.BatchIndex.Uint64(),
"startBlockNumber", startBlock.Header.Number.Uint64(),
"endBlockNumber", endBlock.Header.Number.Uint64(),
"parentBatchHash", parentBatchMeta.BatchHash.Hex(),
"parentTotalL1MessagePopped", parentBatchMeta.TotalL1MessagePopped)

batch := &encoding.Batch{
Index: event.BatchIndex.Uint64(),
TotalL1MessagePoppedBefore: parentBatchMeta.TotalL1MessagePopped,
Expand All @@ -470,79 +481,129 @@ func validateBatch(event *L1FinalizeBatchEvent, parentBatchMeta *rawdb.Finalized
}

var localBatchHash common.Hash
if startBlock.Header.Number.Uint64() == 0 || !chainCfg.IsBernoulli(startBlock.Header.Number) { // codecv0: genesis batch or batches before Bernoulli
var codecVersion string

if startBlock.Header.Number.Uint64() == 0 || !chainCfg.IsBernoulli(startBlock.Header.Number) {
codecVersion = "codecv0"
daBatch, err := codecv0.NewDABatch(batch)
if err != nil {
log.Error("Failed to create codecv0 DA batch", "batchIndex", event.BatchIndex.Uint64(), "error", err)
return 0, nil, fmt.Errorf("failed to create codecv0 DA batch, batch index: %v, err: %w", event.BatchIndex.Uint64(), err)
}
localBatchHash = daBatch.Hash()
} else if !chainCfg.IsCurie(startBlock.Header.Number) { // codecv1: batches after Bernoulli and before Curie
} else if !chainCfg.IsCurie(startBlock.Header.Number) {
codecVersion = "codecv1"
daBatch, err := codecv1.NewDABatch(batch)
if err != nil {
log.Error("Failed to create codecv1 DA batch", "batchIndex", event.BatchIndex.Uint64(), "error", err)
return 0, nil, fmt.Errorf("failed to create codecv1 DA batch, batch index: %v, err: %w", event.BatchIndex.Uint64(), err)
}
localBatchHash = daBatch.Hash()
} else if !chainCfg.IsDarwin(startBlock.Header.Time) { // codecv2: batches after Curie and before Darwin
} else if !chainCfg.IsDarwin(startBlock.Header.Time) {
codecVersion = "codecv2"
daBatch, err := codecv2.NewDABatch(batch)
if err != nil {
log.Error("Failed to create codecv2 DA batch", "batchIndex", event.BatchIndex.Uint64(), "error", err)
return 0, nil, fmt.Errorf("failed to create codecv2 DA batch, batch index: %v, err: %w", event.BatchIndex.Uint64(), err)
}
localBatchHash = daBatch.Hash()
} else { // codecv3: batches after Darwin
} else {
codecVersion = "codecv3"
daBatch, err := codecv3.NewDABatch(batch)
if err != nil {
log.Error("Failed to create codecv3 DA batch", "batchIndex", event.BatchIndex.Uint64(), "error", err)
return 0, nil, fmt.Errorf("failed to create codecv3 DA batch, batch index: %v, err: %w", event.BatchIndex.Uint64(), err)
}
localBatchHash = daBatch.Hash()
}

log.Info("Batch hash calculated",
"batchIndex", event.BatchIndex.Uint64(),
"codecVersion", codecVersion,
"localBatchHash", localBatchHash.Hex())

localStateRoot := endBlock.Header.Root
localWithdrawRoot := endBlock.WithdrawRoot

// Note: If the state root, withdraw root, and batch headers match, this ensures the consistency of blocks and transactions
// (including skipped transactions) between L1 and L2.
//
// Only check when it's the last batch. This is compatible with both "finalize by batch" and "finalize by bundle":
// - finalize by batch: check all batches
// - finalize by bundle: check the last batch, because only one event (containing the info of the last batch) is emitted per bundle
log.Info("Local roots calculated",
"batchIndex", event.BatchIndex.Uint64(),
"localStateRoot", localStateRoot.Hex(),
"localWithdrawRoot", localWithdrawRoot.Hex())

if lastBatch {
log.Info("Verifying last batch", "batchIndex", event.BatchIndex.Uint64())

if localStateRoot != event.StateRoot {
log.Error("State root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "l1 finalized state root", event.StateRoot.Hex(), "l2 state root", localStateRoot.Hex())
log.Error("State root mismatch",
"batchIndex", event.BatchIndex.Uint64(),
"startBlock", startBlock.Header.Number.Uint64(),
"endBlock", endBlock.Header.Number.Uint64(),
"parentBatchHash", parentBatchMeta.BatchHash.Hex(),
"l1FinalizedStateRoot", event.StateRoot.Hex(),
"l2StateRoot", localStateRoot.Hex())
stack.Close()
os.Exit(1)
}

if localWithdrawRoot != event.WithdrawRoot {
log.Error("Withdraw root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "l1 finalized withdraw root", event.WithdrawRoot.Hex(), "l2 withdraw root", localWithdrawRoot.Hex())
log.Error("Withdraw root mismatch",
"batchIndex", event.BatchIndex.Uint64(),
"startBlock", startBlock.Header.Number.Uint64(),
"endBlock", endBlock.Header.Number.Uint64(),
"parentBatchHash", parentBatchMeta.BatchHash.Hex(),
"l1FinalizedWithdrawRoot", event.WithdrawRoot.Hex(),
"l2WithdrawRoot", localWithdrawRoot.Hex())
stack.Close()
os.Exit(1)
}

// Verify batch hash
// This check ensures the correctness of all batch hashes in the bundle
// due to the parent-child relationship between batch hashes
if localBatchHash != event.BatchHash {
log.Error("Batch hash mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "parent TotalL1MessagePopped", parentBatchMeta.TotalL1MessagePopped, "l1 finalized batch hash", event.BatchHash.Hex(), "l2 batch hash", localBatchHash.Hex())
log.Error("Batch hash mismatch",
"batchIndex", event.BatchIndex.Uint64(),
"startBlock", startBlock.Header.Number.Uint64(),
"endBlock", endBlock.Header.Number.Uint64(),
"parentBatchHash", parentBatchMeta.BatchHash.Hex(),
"parentTotalL1MessagePopped", parentBatchMeta.TotalL1MessagePopped,
"l1FinalizedBatchHash", event.BatchHash.Hex(),
"l2BatchHash", localBatchHash.Hex())
chunksJson, err := json.Marshal(chunks)
if err != nil {
log.Error("marshal chunks failed", "err", err)
log.Error("Marshal chunks failed", "error", err)
}
log.Error("Chunks", "chunks", string(chunksJson))
stack.Close()
os.Exit(1)
}

log.Info("Last batch verified successfully", "batchIndex", event.BatchIndex.Uint64())
}

totalL1MessagePopped := parentBatchMeta.TotalL1MessagePopped
for _, chunk := range chunks {
totalL1MessagePopped += chunk.NumL1Messages(totalL1MessagePopped)
for i, chunk := range chunks {
chunkL1Messages := chunk.NumL1Messages(totalL1MessagePopped)
totalL1MessagePopped += chunkL1Messages
log.Info("Chunk L1 messages",
"batchIndex", event.BatchIndex.Uint64(),
"chunkIndex", i,
"chunkL1Messages", chunkL1Messages,
"totalL1MessagePopped", totalL1MessagePopped)
}

finalizedBatchMeta := &rawdb.FinalizedBatchMeta{
BatchHash: localBatchHash,
TotalL1MessagePopped: totalL1MessagePopped,
StateRoot: localStateRoot,
WithdrawRoot: localWithdrawRoot,
}

log.Info("Batch validation completed",
"batchIndex", event.BatchIndex.Uint64(),
"endBlockNumber", endBlock.Header.Number.Uint64(),
"finalBatchHash", finalizedBatchMeta.BatchHash.Hex(),
"finalTotalL1MessagePopped", finalizedBatchMeta.TotalL1MessagePopped,
"finalStateRoot", finalizedBatchMeta.StateRoot.Hex(),
"finalWithdrawRoot", finalizedBatchMeta.WithdrawRoot.Hex())

return endBlock.Header.Number.Uint64(), finalizedBatchMeta, nil
}

Expand Down

0 comments on commit 4befe9f

Please sign in to comment.