Skip to content

Commit a25acbb

Browse files
tynesgakonst
andauthored
Refactor the SyncService to more closely implement the specification (#552)
* l2geth: add Backend enums and config parsing * l2geth: move OVMContext to types file * l2geth: implement syncservice spec * l2geth: fix error handling for get tx batch * l2geth: update tests to compile and pass * l2geth: add sync range functions * l2geth: add batch index indexing * l2geth: update syncservice hot path logging * l2geth: use indexed batch index * chore: add changeset * l2geth: sync spec refactor (#822) * l2geth: more in depth usage string * l2geth: add standard client getters for index * l2geth: refactor sync service into shared codepaths * l2geth: clean up tests * l2geth: better logging and error handling * test: improve test coverage around timestamps * l2geth: improve docstring * l2geth: rename variable * sync-service: better logline * l2geth: better logline * l2geth: test apply indexed transaction * l2geth: better logline * linting: fix * syncservice: fix logline * l2geth: add error and fix logline * l2geth: sync service tests * fix: get last confirmed enqueue (#846) * l2geth: fix get last confirmed enqueue * chore: add changeset * client: return error correctly * batch-submitter: updated config (#847) * batch-submitter: backwards compatible configuration * chore: add changeset * deps: update * js: move bcfg interface to core-utils * batch-submitter: parse USE_SENTRY and add to env example * chore: add changeset * batch-submitter: parse as float instead of int * batch-submitter: better error logging * l2geth: update rawdb logline Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * l2geth: more robust testing Co-authored-by: Georgios Konstantopoulos <me@gakonst.com> * l2geth: add sanity check for L1ToL2 timestamps * l2geth: handle error in single place * l2geth: fix test tx queue origin * l2geth: add new arg to start.sh * l2geth: return error in the SyncService.Start() * chore: go fmt Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
1 parent c3d39df commit a25acbb

13 files changed

Lines changed: 1083 additions & 330 deletions

File tree

.changeset/nervous-bobcats-grow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@eth-optimism/l2geth": patch
3+
---
4+
5+
Refactor the SyncService to more closely implement the specification. This includes using query params to select the backend from the DTL, trailing syncing of batches for the sequencer, syncing by batches as the verifier as well as unified code paths for transaction ingestion to prevent double ingestion or missed ingestion

l2geth/cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ var (
165165
utils.RollupMaxCalldataSizeFlag,
166166
utils.RollupDataPriceFlag,
167167
utils.RollupExecutionPriceFlag,
168+
utils.RollupBackendFlag,
168169
utils.RollupEnableL2GasPollingFlag,
169170
utils.RollupGasPriceOracleAddressFlag,
170171
utils.RollupEnforceFeesFlag,

l2geth/cmd/geth/usage.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ var AppHelpFlagGroups = []flagGroup{
8080
utils.RollupMaxCalldataSizeFlag,
8181
utils.RollupDataPriceFlag,
8282
utils.RollupExecutionPriceFlag,
83+
utils.RollupBackendFlag,
8384
utils.RollupEnableL2GasPollingFlag,
8485
utils.RollupGasPriceOracleAddressFlag,
8586
utils.RollupEnforceFeesFlag,

l2geth/cmd/utils/flags.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,12 @@ var (
851851
Value: time.Minute * 3,
852852
EnvVar: "ROLLUP_TIMESTAMP_REFRESH",
853853
}
854+
RollupBackendFlag = cli.StringFlag{
855+
Name: "rollup.backend",
856+
Usage: "Sync backend for verifiers (\"l1\" or \"l2\"), defaults to l1",
857+
Value: "l1",
858+
EnvVar: "ROLLUP_BACKEND",
859+
}
854860
// Flag to enable verifier mode
855861
RollupEnableVerifierFlag = cli.BoolFlag{
856862
Name: "rollup.verifier",
@@ -1188,6 +1194,15 @@ func setRollup(ctx *cli.Context, cfg *rollup.Config) {
11881194
if ctx.GlobalIsSet(RollupExecutionPriceFlag.Name) {
11891195
cfg.ExecutionPrice = GlobalBig(ctx, RollupExecutionPriceFlag.Name)
11901196
}
1197+
if ctx.GlobalIsSet(RollupBackendFlag.Name) {
1198+
val := ctx.GlobalString(RollupBackendFlag.Name)
1199+
backend, err := rollup.NewBackend(val)
1200+
if err != nil {
1201+
log.Error("Configured with unknown sync backend, defaulting to l1", "backend", val)
1202+
backend, _ = rollup.NewBackend("l1")
1203+
}
1204+
cfg.Backend = backend
1205+
}
11911206
if ctx.GlobalIsSet(RollupGasPriceOracleAddressFlag.Name) {
11921207
addr := ctx.GlobalString(RollupGasPriceOracleAddressFlag.Name)
11931208
cfg.GasPriceOracleAddress = common.HexToAddress(addr)

l2geth/core/rawdb/rollup_indexes.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,24 @@ func WriteHeadVerifiedIndex(db ethdb.KeyValueWriter, index uint64) {
6969
log.Crit("Failed to store verifier index", "err", err)
7070
}
7171
}
72+
73+
// ReadHeadBatchIndex will read the known tip of the processed batches
74+
func ReadHeadBatchIndex(db ethdb.KeyValueReader) *uint64 {
75+
data, _ := db.Get(headBatchKey)
76+
if len(data) == 0 {
77+
return nil
78+
}
79+
ret := new(big.Int).SetBytes(data).Uint64()
80+
return &ret
81+
}
82+
83+
// WriteHeadBatchIndex will write the known tip of the processed batches
84+
func WriteHeadBatchIndex(db ethdb.KeyValueWriter, index uint64) {
85+
value := new(big.Int).SetUint64(index).Bytes()
86+
if index == 0 {
87+
value = []byte{0}
88+
}
89+
if err := db.Put(headBatchKey, value); err != nil {
90+
log.Crit("Failed to store head batch index", "err", err)
91+
}
92+
}

l2geth/core/rawdb/schema.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ var (
6262
headQueueIndexKey = []byte("LastQueueIndex")
6363
// headVerifiedIndexKey tracks the latest verified index
6464
headVerifiedIndexKey = []byte("LastVerifiedIndex")
65+
// headBatchKey tracks the latest processed batch
66+
headBatchKey = []byte("LastBatch")
6567

6668
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
6769
configPrefix = []byte("ethereum-config-") // config prefix for the db

l2geth/eth/api_backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
330330
}
331331
}
332332
}
333-
return b.eth.syncService.ApplyTransaction(signedTx)
333+
return b.eth.syncService.ValidateAndApplySequencerTransaction(signedTx)
334334
}
335335
// OVM Disabled
336336
return b.eth.txPool.AddLocal(signedTx)

l2geth/rollup/client.go

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,17 @@ type decoded struct {
116116
type RollupClient interface {
117117
GetEnqueue(index uint64) (*types.Transaction, error)
118118
GetLatestEnqueue() (*types.Transaction, error)
119-
GetTransaction(uint64) (*types.Transaction, error)
120-
GetLatestTransaction() (*types.Transaction, error)
119+
GetLatestEnqueueIndex() (*uint64, error)
120+
GetTransaction(uint64, Backend) (*types.Transaction, error)
121+
GetLatestTransaction(Backend) (*types.Transaction, error)
122+
GetLatestTransactionIndex(Backend) (*uint64, error)
121123
GetEthContext(uint64) (*EthContext, error)
122124
GetLatestEthContext() (*EthContext, error)
123125
GetLastConfirmedEnqueue() (*types.Transaction, error)
124126
GetLatestTransactionBatch() (*Batch, []*types.Transaction, error)
127+
GetLatestTransactionBatchIndex() (*uint64, error)
125128
GetTransactionBatch(uint64) (*Batch, []*types.Transaction, error)
126-
SyncStatus() (*SyncStatus, error)
129+
SyncStatus(Backend) (*SyncStatus, error)
127130
GetL1GasPrice() (*big.Int, error)
128131
}
129132

@@ -270,6 +273,43 @@ func (c *Client) GetLatestEnqueue() (*types.Transaction, error) {
270273
return tx, nil
271274
}
272275

276+
// GetLatestEnqueueIndex returns the latest `enqueue()` index
277+
func (c *Client) GetLatestEnqueueIndex() (*uint64, error) {
278+
tx, err := c.GetLatestEnqueue()
279+
if err != nil {
280+
return nil, err
281+
}
282+
index := tx.GetMeta().QueueIndex
283+
if index == nil {
284+
return nil, errors.New("Latest queue index is nil")
285+
}
286+
return index, nil
287+
}
288+
289+
// GetLatestTransactionIndex returns the latest CTC index that has been batch
290+
// submitted or not, depending on the backend
291+
func (c *Client) GetLatestTransactionIndex(backend Backend) (*uint64, error) {
292+
tx, err := c.GetLatestTransaction(backend)
293+
if err != nil {
294+
return nil, err
295+
}
296+
index := tx.GetMeta().Index
297+
if index == nil {
298+
return nil, errors.New("Latest index is nil")
299+
}
300+
return index, nil
301+
}
302+
303+
// GetLatestTransactionBatchIndex returns the latest transaction batch index
304+
func (c *Client) GetLatestTransactionBatchIndex() (*uint64, error) {
305+
batch, _, err := c.GetLatestTransactionBatch()
306+
if err != nil {
307+
return nil, err
308+
}
309+
index := batch.Index
310+
return &index, nil
311+
}
312+
273313
// batchedTransactionToTransaction converts a transaction into a
274314
// types.Transaction that can be consumed by the SyncService
275315
func batchedTransactionToTransaction(res *transaction, signer *types.EIP155Signer) (*types.Transaction, error) {
@@ -364,12 +404,15 @@ func batchedTransactionToTransaction(res *transaction, signer *types.EIP155Signe
364404
}
365405

366406
// GetTransaction will get a transaction by Canonical Transaction Chain index
367-
func (c *Client) GetTransaction(index uint64) (*types.Transaction, error) {
407+
func (c *Client) GetTransaction(index uint64, backend Backend) (*types.Transaction, error) {
368408
str := strconv.FormatUint(index, 10)
369409
response, err := c.client.R().
370410
SetPathParams(map[string]string{
371411
"index": str,
372412
}).
413+
SetQueryParams(map[string]string{
414+
"backend": backend.String(),
415+
}).
373416
SetResult(&TransactionResponse{}).
374417
Get("/transaction/index/{index}")
375418

@@ -385,9 +428,12 @@ func (c *Client) GetTransaction(index uint64) (*types.Transaction, error) {
385428

386429
// GetLatestTransaction will get the latest transaction, meaning the transaction
387430
// with the greatest Canonical Transaction Chain index
388-
func (c *Client) GetLatestTransaction() (*types.Transaction, error) {
431+
func (c *Client) GetLatestTransaction(backend Backend) (*types.Transaction, error) {
389432
response, err := c.client.R().
390433
SetResult(&TransactionResponse{}).
434+
SetQueryParams(map[string]string{
435+
"backend": backend.String(),
436+
}).
391437
Get("/transaction/latest")
392438

393439
if err != nil {
@@ -477,9 +523,12 @@ func (c *Client) GetLastConfirmedEnqueue() (*types.Transaction, error) {
477523
}
478524

479525
// SyncStatus will query the remote server to determine if it is still syncing
480-
func (c *Client) SyncStatus() (*SyncStatus, error) {
526+
func (c *Client) SyncStatus(backend Backend) (*SyncStatus, error) {
481527
response, err := c.client.R().
482528
SetResult(&SyncStatus{}).
529+
SetQueryParams(map[string]string{
530+
"backend": backend.String(),
531+
}).
483532
Get("/eth/syncing")
484533

485534
if err != nil {
@@ -533,8 +582,8 @@ func (c *Client) GetTransactionBatch(index uint64) (*Batch, []*types.Transaction
533582
// parseTransactionBatchResponse will turn a TransactionBatchResponse into a
534583
// Batch and its corresponding types.Transactions
535584
func parseTransactionBatchResponse(txBatch *TransactionBatchResponse, signer *types.EIP155Signer) (*Batch, []*types.Transaction, error) {
536-
if txBatch == nil {
537-
return nil, nil, nil
585+
if txBatch == nil || txBatch.Batch == nil {
586+
return nil, nil, errElementNotFound
538587
}
539588
batch := txBatch.Batch
540589
txs := make([]*types.Transaction, len(txBatch.Transactions))

l2geth/rollup/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ type Config struct {
4040
DataPrice *big.Int
4141
// The gas price to use for L2 congestion costs
4242
ExecutionPrice *big.Int
43+
// Represents the source of the transactions that is being synced
44+
Backend Backend
4345
// Only accept transactions with fees
4446
EnforceFees bool
4547
}

0 commit comments

Comments
 (0)