-
Notifications
You must be signed in to change notification settings - Fork 619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(relayer): adapt to CodecV7 for EuclidV2 #1583
Open
jonastheis
wants to merge
15
commits into
omerfirmak/mpt
Choose a base branch
from
feat/use-codec-v6
base: omerfirmak/mpt
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+920
−98
Open
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
41606fe
support first version of CodecV6 in relayer and add functionality to …
jonastheis 0c0c417
adjust Sender to support multiple blobs when sending a transaction
jonastheis 78c9963
implement batch submission of multiple batches per transaction and co…
jonastheis 940fde0
implement missing part of commit logic for CodecV6
jonastheis b460d4a
Merge remote-tracking branch 'origin/omerfirmak/mpt' into feat/use-co…
jonastheis 182f8e3
update go.mod to latest da-codec version V7
jonastheis 783b965
update go.mod to latest da-codec version V7
jonastheis 5a479c3
address review comments
jonastheis 310abdd
add InitialL1MessageQueueHash and LastL1MessageQueueHash to chunk and…
jonastheis 2efbbd7
add support for bundles with CodecV7
jonastheis e713424
update contextIDFromBatches prefix to v7
jonastheis f4e17bc
fix ci
jonastheis 99c0a9f
update to latest da-codec
jonastheis 8db5339
fix issues with chunks when handling CodecV7
jonastheis 69a80d4
add testCommitBatchAndFinalizeBundleCodecV7 for relayer
jonastheis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -373,11 +373,156 @@ func (r *Layer2Relayer) ProcessGasPriceOracle() { | |
// ProcessPendingBatches processes the pending batches by sending commitBatch transactions to layer 1. | ||
func (r *Layer2Relayer) ProcessPendingBatches() { | ||
// get pending batches from database in ascending order by their index. | ||
dbBatches, err := r.batchOrm.GetFailedAndPendingBatches(r.ctx, 5) | ||
dbBatches, err := r.batchOrm.GetFailedAndPendingBatches(r.ctx, max(5, r.cfg.SenderConfig.BatchSubmission.MaxBatches)) | ||
if err != nil { | ||
log.Error("Failed to fetch pending L2 batches", "err", err) | ||
return | ||
} | ||
|
||
var batchesToSubmit []*dbBatchWithChunksAndParent | ||
var forceSubmit bool | ||
for i, dbBatch := range dbBatches { | ||
if i == 0 && encoding.CodecVersion(dbBatch.CodecVersion) < encoding.CodecV6 { | ||
// if the first batch is not >= V6 then we need to submit batches one by one | ||
colinlyguo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
r.processPendingBatchesV4(dbBatches) | ||
return | ||
} | ||
|
||
batchesToSubmitLen := len(batchesToSubmit) | ||
var dbChunks []*orm.Chunk | ||
var dbParentBatch *orm.Batch | ||
|
||
// Verify batches compatibility | ||
{ | ||
dbChunks, err = r.chunkOrm.GetChunksInRange(r.ctx, dbBatch.StartChunkIndex, dbBatch.EndChunkIndex) | ||
if err != nil { | ||
log.Error("failed to get chunks in range", "err", err) | ||
return | ||
} | ||
|
||
// check codec version | ||
for _, dbChunk := range dbChunks { | ||
if dbBatch.CodecVersion != dbChunk.CodecVersion { | ||
log.Error("batch codec version is different from chunk codec version", "batch index", dbBatch.Index, "chunk index", dbChunk.Index, "batch codec version", dbBatch.CodecVersion, "chunk codec version", dbChunk.CodecVersion) | ||
return | ||
} | ||
} | ||
|
||
if dbBatch.Index == 0 { | ||
log.Error("invalid args: batch index is 0, should only happen in committing genesis batch") | ||
return | ||
} | ||
|
||
dbParentBatch, err = r.batchOrm.GetBatchByIndex(r.ctx, dbBatch.Index-1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most of these batches are already in memory ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed to use |
||
if err != nil { | ||
log.Error("failed to get parent batch header", "err", err) | ||
return | ||
} | ||
|
||
if dbParentBatch.CodecVersion > dbBatch.CodecVersion { | ||
log.Error("parent batch codec version is greater than current batch codec version", "index", dbBatch.Index, "hash", dbBatch.Hash, "parent codec version", dbParentBatch.CodecVersion, "current codec version", dbBatch.CodecVersion) | ||
return | ||
} | ||
|
||
// make sure we commit batches of the same codec version together. | ||
// If we encounter a batch with a different codec version, we stop here and will commit the batches we have so far. | ||
// The next call of ProcessPendingBatches will then start with the batch with the different codec version. | ||
if batchesToSubmitLen > 0 && batchesToSubmit[batchesToSubmitLen-1].Batch.CodecVersion != dbBatch.CodecVersion { | ||
break | ||
} | ||
} | ||
|
||
// if one of the batches is too old, we force submit all batches that we have so far in the next step | ||
if !forceSubmit && time.Since(dbBatch.CreatedAt) > time.Duration(r.cfg.SenderConfig.BatchSubmission.TimeoutSec)*time.Second { | ||
forceSubmit = true | ||
} | ||
|
||
if batchesToSubmitLen <= r.cfg.SenderConfig.BatchSubmission.MaxBatches { | ||
batchesToSubmit = append(batchesToSubmit, &dbBatchWithChunksAndParent{ | ||
Batch: dbBatch, | ||
Chunks: dbChunks, | ||
ParentBatch: dbParentBatch, | ||
}) | ||
} | ||
} | ||
|
||
if !forceSubmit && len(batchesToSubmit) < r.cfg.SenderConfig.BatchSubmission.MinBatches { | ||
log.Debug("Not enough batches to submit", "count", len(batchesToSubmit), "minBatches", r.cfg.SenderConfig.BatchSubmission.MinBatches, "maxBatches", r.cfg.SenderConfig.BatchSubmission.MaxBatches) | ||
return | ||
} | ||
|
||
if forceSubmit { | ||
log.Info("Forcing submission of batches due to timeout", "batch index", batchesToSubmit[0].Batch.Index, "created at", batchesToSubmit[0].Batch.CreatedAt) | ||
} | ||
|
||
// We have at least 1 batch to commit | ||
firstBatch := batchesToSubmit[0].Batch | ||
lastBatch := batchesToSubmit[len(batchesToSubmit)-1].Batch | ||
|
||
codecVersion := encoding.CodecVersion(firstBatch.CodecVersion) | ||
switch codecVersion { | ||
case encoding.CodecV6: | ||
calldata, blob, err := r.constructCommitBatchPayloadCodecV6(batchesToSubmit) | ||
if err != nil { | ||
log.Error("failed to construct commitBatchWithBlobProof payload for V6", "codecVersion", codecVersion, "start index", firstBatch.Index, "end index", lastBatch.Index, "err", err) | ||
return | ||
} | ||
default: | ||
log.Error("unsupported codec version in ProcessPendingBatches", "codecVersion", codecVersion, "start index", firstBatch, "end index", lastBatch.Index) | ||
return | ||
} | ||
|
||
//txHash, err := r.commitSender.SendTransaction(dbBatch.Hash, &r.cfg.RollupContractAddress, calldata, blob, 0) | ||
//if err != nil { | ||
// if errors.Is(err, sender.ErrTooManyPendingBlobTxs) { | ||
// r.metrics.rollupL2RelayerProcessPendingBatchErrTooManyPendingBlobTxsTotal.Inc() | ||
// log.Debug( | ||
// "Skipped sending commitBatch tx to L1: too many pending blob txs", | ||
// "maxPending", r.cfg.SenderConfig.MaxPendingBlobTxs, | ||
// "err", err, | ||
// ) | ||
// return | ||
// } | ||
// log.Error( | ||
// "Failed to send commitBatch tx to layer1", | ||
// "index", dbBatch.Index, | ||
// "hash", dbBatch.Hash, | ||
// "RollupContractAddress", r.cfg.RollupContractAddress, | ||
// "err", err, | ||
// "calldata", common.Bytes2Hex(calldata), | ||
// ) | ||
// return | ||
//} | ||
// | ||
//err = r.batchOrm.UpdateCommitTxHashAndRollupStatus(r.ctx, dbBatch.Hash, txHash.String(), types.RollupCommitting) | ||
//if err != nil { | ||
// log.Error("UpdateCommitTxHashAndRollupStatus failed", "hash", dbBatch.Hash, "index", dbBatch.Index, "err", err) | ||
// return | ||
//} | ||
// | ||
//var maxBlockHeight uint64 | ||
//var totalGasUsed uint64 | ||
//for _, dbChunk := range dbChunks { | ||
// if dbChunk.EndBlockNumber > maxBlockHeight { | ||
// maxBlockHeight = dbChunk.EndBlockNumber | ||
// } | ||
// totalGasUsed += dbChunk.TotalL2TxGas | ||
//} | ||
//r.metrics.rollupL2RelayerCommitBlockHeight.Set(float64(maxBlockHeight)) | ||
//r.metrics.rollupL2RelayerCommitThroughput.Add(float64(totalGasUsed)) | ||
// | ||
//r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Inc() | ||
//log.Info("Sent the commitBatch tx to layer1", "batch index", dbBatch.Index, "batch hash", dbBatch.Hash, "tx hash", txHash.String()) | ||
|
||
} | ||
|
||
type dbBatchWithChunksAndParent struct { | ||
Batch *orm.Batch | ||
Chunks []*orm.Chunk | ||
ParentBatch *orm.Batch | ||
} | ||
|
||
func (r *Layer2Relayer) processPendingBatchesV4(dbBatches []*orm.Batch) { | ||
for _, dbBatch := range dbBatches { | ||
r.metrics.rollupL2RelayerProcessPendingBatchTotal.Inc() | ||
|
||
|
@@ -432,7 +577,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() { | |
return | ||
} | ||
default: | ||
log.Error("unsupported codec version", "codecVersion", codecVersion) | ||
log.Error("unsupported codec version in processPendingBatchesV4", "codecVersion", codecVersion) | ||
return | ||
} | ||
|
||
|
@@ -868,6 +1013,64 @@ func (r *Layer2Relayer) constructCommitBatchPayloadCodecV4(dbBatch *orm.Batch, d | |
return calldata, daBatch.Blob(), nil | ||
} | ||
|
||
func (r *Layer2Relayer) constructCommitBatchPayloadCodecV6(batchesToSubmit []*dbBatchWithChunksAndParent) ([]byte, []*kzg4844.Blob, error) { | ||
blobs := make([]*kzg4844.Blob, len(batchesToSubmit)) | ||
|
||
version := encoding.CodecVersion(batchesToSubmit[0].Batch.CodecVersion) | ||
var firstParentBatch *orm.Batch | ||
// construct blobs | ||
for _, b := range batchesToSubmit { | ||
// double check that all batches have the same version | ||
batchVersion := encoding.CodecVersion(b.Batch.CodecVersion) | ||
if batchVersion != version { | ||
return nil, nil, fmt.Errorf("codec version mismatch, expected: %d, got: %d for batches %d and %d", version, batchVersion, batchesToSubmit[0].Batch.Index, b.Batch.Index) | ||
} | ||
|
||
if firstParentBatch == nil { | ||
firstParentBatch = b.ParentBatch | ||
} | ||
|
||
chunks := make([]*encoding.Chunk, len(b.Chunks)) | ||
for i, c := range b.Chunks { | ||
blocks, err := r.l2BlockOrm.GetL2BlocksInRange(r.ctx, c.StartBlockNumber, c.EndBlockNumber) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to get blocks in range for batch %d: %w", b.Batch.Index, err) | ||
} | ||
chunks[i] = &encoding.Chunk{Blocks: blocks} | ||
} | ||
|
||
encodingBatch := &encoding.Batch{ | ||
Index: b.Batch.Index, | ||
TotalL1MessagePoppedBefore: b.Chunks[0].TotalL1MessagesPoppedBefore, | ||
ParentBatchHash: common.HexToHash(b.ParentBatch.Hash), | ||
Chunks: chunks, | ||
} | ||
|
||
codec, err := encoding.CodecFromVersion(version) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to get codec from version %d, err: %w", b.Batch.CodecVersion, err) | ||
} | ||
|
||
daBatch, err := codec.NewDABatch(encodingBatch) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to create DA batch: %w", err) | ||
} | ||
|
||
blobs = append(blobs, daBatch.Blob()) | ||
} | ||
|
||
if firstParentBatch == nil { | ||
return nil, nil, fmt.Errorf("firstParentBatch is nil") | ||
} | ||
|
||
// TODO: this needs to be updated once the contract interface is finalized | ||
calldata, err := r.l1RollupABI.Pack("commitBatches", version, firstParentBatch.BatchHeader) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to pack commitBatchWithBlobProof: %w", err) | ||
} | ||
return calldata, blobs, nil | ||
} | ||
|
||
func (r *Layer2Relayer) constructFinalizeBundlePayloadCodecV4(dbBatch *orm.Batch, aggProof *message.BundleProof) ([]byte, error) { | ||
if aggProof != nil { // finalizeBundle with proof. | ||
calldata, packErr := r.l1RollupABI.Pack( | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove 5, and use config value only?