-
Notifications
You must be signed in to change notification settings - Fork 606
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(permissionless batches): batch production toolkit and operator recovery #1555
base: develop
Are you sure you want to change the base?
Conversation
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
can you add more description about this pr |
Will do so once it's in a better shape. This is still a draft PR and and such many things are still changing. Once ready, I'll provide a high-level description + how it relates to the changes made in this PR :) |
rollup/cmd/rollup_relayer/app/app.go
Outdated
log.Info("Latest finalized batch from L1 contract", "latest finalized batch", latestFinalizedBatch, "at latest finalized L1 block", latestFinalizedL1Block) | ||
|
||
// 4. Get batches one by one from stored in DB to latest finalized batch. | ||
receipt, err := l1Client.TransactionReceipt(context.Background(), common.HexToHash(latestDBBatch.CommitTxHash)) |
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.
due to the pruning of txn index, not sure if we may need an archive node or fallback to fetch the whole block for this.
// 2. Make sure that the specified batch is indeed finalized on the L1 rollup contract and is the latest finalized batch. | ||
// TODO: enable check | ||
//latestFinalizedBatch, err := reader.LatestFinalizedBatch(latestFinalizedL1Block) | ||
//if cfg.RecoveryConfig.LatestFinalizedBatch != latestFinalizedBatch { |
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.
curious about why setting cfg.RecoveryConfig.LatestFinalizedBatch
instead of using reader.LatestFinalizedBatch
as the start point.
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.
you're right, can probably remove it and make the configuration a bit easier. initially, I wanted the user to specify L1 block and the latest finalized batch so that the user knows where the (minimal) recovery process is starting from and there's no "magic" happening (e.g. if there's another batch committed in the meantime).
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.
I introduced another config parameter for testing purposes to override this check force_latest_finalized_batch
. The user now still needs to specify the L1 block height and latest finalized batch to not have any surprises/magic.
… message amount. this is mainly for testing purposes
@@ -149,6 +149,10 @@ func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, chai | |||
return p | |||
} | |||
|
|||
func (p *BatchProposer) BatchORM() *orm.Batch { |
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.
as our layout purpose, the orm instance should be exposed to app layer.
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.
done in 5ff6fd0
return db, nil | ||
} | ||
|
||
func fetchL2Blocks(ctx context.Context, cfg *config.Config, genesis *core.Genesis, db *gorm.DB, registry prometheus.Registerer, fromBlock uint64, l2BlockHeightLimit uint64) (uint64, error) { |
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.
I suggest that move these logics to controller layer
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.
done in 5ff6fd0
|
||
// TODO: make these parameters -> part of genesis config? | ||
scrollChainAddress := common.HexToAddress("0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0") | ||
l1MessageQueueAddress := common.HexToAddress("0xF0B2293F5D834eAe920c6974D50957A1732de763") |
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.
read from config
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.
done in 5ff6fd0
…erriding and instead switching to batch submission mode
rollup/internal/controller/permissionless_batches/minimal_recovery.go
Outdated
Show resolved
Hide resolved
if err != nil { | ||
return true | ||
} | ||
if chunk.Index <= defaultRestoredChunkIndex { |
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.
Why don't get the defaultRestoredChunkIndex, defaultRestoredBundleIndex from config like RecoveryConfig.LatestFinalizedBatch
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.
// defaultFakeRestoredChunkIndex is the default index of the last restored fake chunk. It is used to be able to generate new chunks pretending that we have already processed some chunks.
I renamed them now to include fake
in the name. It is not a config parameter but just an arbitrary constant value as we need to pretend we have chunks and bundles in the DB (even though in reality we don't)
return toBlock, nil | ||
} | ||
|
||
func (r *MinimalRecovery) resetDB() error { |
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.
I prefer the user use database component to do it.
- cd scroll/database
- make
db_cli
- ./build/bin/db_cli migrate --config ./config.json
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.
Yeah I was thinking about this as well. But the user doesn't even really know there's a database (it's automatically started with executing the Docker Compose profiles). For the minimal recovery the DB is just a crutch to make the batch creating with existing logic, coordinator and proving working without changing the logic in the components respectively.
If we add it like this then we'll need to add these additional steps to the README.md
which makes the entire thing even more complicated.
rollup/internal/orm/batch.go
Outdated
@@ -324,6 +326,53 @@ func (o *Batch) InsertBatch(ctx context.Context, batch *encoding.Batch, codecVer | |||
return &newBatch, nil | |||
} | |||
|
|||
func (o *Batch) InsertBatchRaw(ctx context.Context, batchIndex *big.Int, batchHash common.Hash, codecVersion encoding.CodecVersion, chunk *Chunk) (*Batch, error) { |
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.
func (o *Batch) InsertBatchRaw(ctx context.Context, batchIndex *big.Int, batchHash common.Hash, codecVersion encoding.CodecVersion, chunk *Chunk) (*Batch, error) { | |
func (o *Batch) InsertPermissionlessBatch(ctx context.Context, batchIndex *big.Int, batchHash common.Hash, codecVersion encoding.CodecVersion, chunk *Chunk) (*Batch, error) { |
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.
done in 6ef4775
rollup/internal/orm/batch.go
Outdated
StartChunkHash: chunk.Hash, | ||
EndChunkIndex: chunk.Index, | ||
EndChunkHash: chunk.Hash, | ||
StateRoot: "", |
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.
If the field doesn't have a value, don't need to assign a empty value to it, the gorm will set automatically.
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.
done in 6ef4775
log.Info("Success! You're ready to generate proofs!") | ||
} else { | ||
// TODO: implement batch submission if proofs are available | ||
log.Info("TODO: Batch submission") |
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.
you mean the finalizeBundle?
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.
no, I mean a new function on the contracts for permissionless mode (commitAndFinalizeBatch
) to submit the batch and finalize in one go. However, the implementation is not yet done and changing as we won't have SGX for now: https://github.com/scroll-tech/scroll-contracts/pull/61/files#diff-569c04365d5a05d8c3084fec1c23fa7d12607340e012df710d3c5963bd1684beR511
rollup/internal/orm/chunk.go
Outdated
@@ -254,6 +256,52 @@ func (o *Chunk) InsertChunk(ctx context.Context, chunk *encoding.Chunk, codecVer | |||
return &newChunk, nil | |||
} | |||
|
|||
func (o *Chunk) InsertChunkRaw(ctx context.Context, index uint64, codecVersion encoding.CodecVersion, chunk *encoding.DAChunkRawTx, totalL1MessagePoppedBefore uint64) (*Chunk, error) { |
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.
ditto
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.
done in 6ef4775
} | ||
|
||
func (r *MinimalRecovery) RecoveryNeeded() bool { | ||
chunk, err := r.chunkORM.GetLatestChunk(r.ctx) |
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.
If users run, here seems weird.
for users, I think they don't have any data locally.
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.
within the Docker Compose they have a DB but users don't really know about it as it is all part of the automatic script.
// RestoreFullPreviousState restores the full state from L1. | ||
// The DB state should be clean: the latest batch in the DB should be finalized on L1. This function will | ||
// restore all batches between the latest finalized batch in the DB and the latest finalized batch on L1. | ||
func (f *FullRecovery) RestoreFullPreviousState() error { |
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.
Why I feel we can combine the RestoreMinimalPreviousState
and RestoreFullPreviousState
to same logic. WDYT?
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.
Purpose or design rationale of this PR
This PR is part of the permissionless batches (aka enforced batches) feature. It implements the permissionless batch production, operator recovery and provides instructions how to run these in the readme.
permissionless batch production:
rollup/cmd/permissionless_batches/app/app.go
the main tool in conjunction withpermissionless-batches/docker-compose.yml
(usage will be explained in readme later) to create batches in a permissionless way and submit them to L1. It requires the recovery and potentially block production without signature in l2geth before.operator recovery:
rollup/cmd/rollup_relayer/app/app.go
withcfg.RecoveryConfig.Enable == true
. Willrestore all batches between the latest finalized batch in the DB and the latest finalized batch on L1 based on L1 data. It requires the recovery of l2geth before.
Other parts of this feature are implemented in following PRs:
PR title
Your PR title must follow conventional commits (as we are doing squash merge for each PR), so it must start with one of the following types:
Deployment tag versioning
Has
tag
incommon/version.go
been updated or have you addedbump-version
label to this PR?Breaking change label
Does this PR have the
breaking-change
label?