Skip to content
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: follower node sync from DA #631

Closed
wants to merge 73 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
4fe6c3a
implement l1rpcfetcher and prepare for implementing da_syncer
NazariiDenha Feb 5, 2024
25bc860
finish da_syncer, add db access, small fixes
NazariiDenha Feb 13, 2024
deed82a
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Feb 13, 2024
635f744
fix lint
NazariiDenha Feb 13, 2024
69d6c39
address comments
NazariiDenha Feb 19, 2024
8bc5a6b
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Mar 18, 2024
2bef690
poc
NazariiDenha Apr 9, 2024
b6fc6dd
update poc, preprocess blocks before inserting to generate missing he…
NazariiDenha Apr 29, 2024
794c251
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Apr 29, 2024
5f11287
refactor code to new design with pipeline
NazariiDenha May 17, 2024
885bd3e
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha May 17, 2024
6b9e837
adapt for codecv0 types
NazariiDenha May 20, 2024
c6201c3
prepare for blob dta asource
NazariiDenha May 21, 2024
27a4e51
implement blob fethcer
NazariiDenha May 24, 2024
6991da0
implement blob fethcer
NazariiDenha May 24, 2024
e483219
fixes after testing and add synced l1 height to db
NazariiDenha Jun 7, 2024
48dd5d8
Merge branch 'feat/sync-directly-from-da' of github.com:scroll-tech/g…
NazariiDenha Jun 7, 2024
eb377fe
fixes and improvements after testing
NazariiDenha Jun 11, 2024
5a48000
fixes and improvements after testing
NazariiDenha Jun 11, 2024
01e5f9c
Merge branch 'feat/sync-directly-from-da' of github.com:scroll-tech/g…
NazariiDenha Jun 11, 2024
1a84506
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Jun 11, 2024
fd6d899
update codec version
NazariiDenha Jun 11, 2024
9b929ff
lint
NazariiDenha Jun 11, 2024
9b13959
update codec dependency
NazariiDenha Jun 17, 2024
20ca22d
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Jun 17, 2024
bf1d02e
goimports
NazariiDenha Jun 17, 2024
bc9b360
small fixes
NazariiDenha Jun 18, 2024
e55416e
fix lint, turn off handler, worker, miner during da syncing
NazariiDenha Jun 18, 2024
1ff0973
remove comments
NazariiDenha Jul 2, 2024
b3726ff
support blocknative
NazariiDenha Jul 8, 2024
6e0ccdb
fix
NazariiDenha Jul 9, 2024
cc65d00
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Jul 9, 2024
49c3c15
fix lint
NazariiDenha Jul 9, 2024
e825a42
fix bug with decoding [parentbatch
NazariiDenha Jul 14, 2024
750c615
support codec v3
NazariiDenha Jul 15, 2024
e3ced13
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Jul 24, 2024
cda4058
address comments
NazariiDenha Jul 24, 2024
f3a1c5d
fix: nil pointer when enabling --da.sync=true
jonastheis Jul 24, 2024
2931099
fix: block not being inserted due to Clique verification
jonastheis Jul 25, 2024
1c36c2c
refactor: compose DA types for more cohesion, maintainability and cod…
jonastheis Jul 30, 2024
e587c98
feat: execute blocks only once
jonastheis Jul 26, 2024
9dc17cb
refactor: introduce partial header and partial block for data from DA…
jonastheis Jul 26, 2024
dbdbc88
minor cleanup
jonastheis Jul 26, 2024
26dbf42
feat: fix issue with not specifying difficulty
jonastheis Jul 29, 2024
0f8e35c
refactor: compose DA types for more cohesion, maintainability and cod…
jonastheis Jul 25, 2024
912af16
feat: implement generic min heap
jonastheis Jul 29, 2024
bdb575d
feat: use generic min heap instead of map in BatchQueue
jonastheis Jul 29, 2024
362d160
fix compile errors after rebase
jonastheis Jul 30, 2024
329dd54
disable all p2p networking
NazariiDenha Aug 4, 2024
15ec7c4
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Aug 4, 2024
d958069
chore: auto version bump [bot]
NazariiDenha Aug 4, 2024
69e1a9e
v3 finalization
NazariiDenha Aug 4, 2024
0fd2a08
feat: add shrinking map that shrinks itself after a certain number of…
jonastheis Aug 6, 2024
3f68f2c
feat: use shrinking map in batch queue to delete specific elements fr…
jonastheis Aug 6, 2024
53bdb18
feat: execute blocks only once
jonastheis Jul 26, 2024
5243d59
refactor: introduce partial header and partial block for data from DA…
jonastheis Jul 26, 2024
7018b5b
minor cleanup
jonastheis Jul 26, 2024
fe33d83
feat: fix issue with not specifying difficulty
jonastheis Jul 29, 2024
d279e83
Merge remote-tracking branch 'origin/feat/sync-directly-from-da' into…
jonastheis Aug 6, 2024
d3ca47e
feat: implement simple pipeline reset (#941)
jonastheis Aug 6, 2024
19ed11d
feat: remove changes to Clique as we're not verifying signatures when…
jonastheis Aug 6, 2024
a6461d5
feat: only request finalized block number when necessary
jonastheis Aug 6, 2024
85bbc98
minor cleanup and comments
jonastheis Aug 7, 2024
485c229
cycle over list of blob clients (#960)
NazariiDenha Aug 7, 2024
f8eadfe
Merge branch 'develop' into feat/sync-directly-from-da
0xmountaintop Aug 8, 2024
399dcfc
feat: introduce custom errors and mark RPC related errors as temporar…
jonastheis Aug 13, 2024
9e1769f
fix blob_client_list
NazariiDenha Aug 15, 2024
0649954
chore: auto version bump [bot]
NazariiDenha Aug 15, 2024
0b2fe3b
feat: enable prefetching in BuildAndWriteBlock
jonastheis Aug 16, 2024
9e3c838
(follower_node)support beacon node client as blob provider (#988)
NazariiDenha Aug 19, 2024
787c955
update codec version
NazariiDenha Aug 26, 2024
dcd9c5c
Merge branch 'develop' of github.com:scroll-tech/go-ethereum into fea…
NazariiDenha Aug 26, 2024
4a66bf3
support codec v4
NazariiDenha Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ var (
utils.L1DeploymentBlockFlag,
utils.CircuitCapacityCheckEnabledFlag,
utils.RollupVerifyEnabledFlag,
utils.DaSyncEnabledFlag,
utils.DAModeFlag,
utils.DASnapshotFileFlag,
}

rpcFlags = []cli.Flag{
Expand Down
30 changes: 30 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import (
"github.com/scroll-tech/go-ethereum/p2p/nat"
"github.com/scroll-tech/go-ethereum/p2p/netutil"
"github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rollup/da_syncer"
"github.com/scroll-tech/go-ethereum/rollup/tracing"
"github.com/scroll-tech/go-ethereum/rpc"
)
Expand Down Expand Up @@ -848,6 +849,22 @@ var (
Name: "rpc.getlogs.maxrange",
Usage: "Limit max fetched block range for `eth_getLogs` method",
}

// Da syncing settings
DaSyncEnabledFlag = cli.BoolFlag{
Name: "da.sync",
Usage: "Enable node syncing from DA",
}
defaultDa = ethconfig.Defaults.DA.FetcherMode
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
DAModeFlag = TextMarshalerFlag{
Name: "da.mode",
Usage: `Da sync sync mode ("l1rpc" or "snapshot")`,
Value: &defaultDa,
}
DASnapshotFileFlag = cli.StringFlag{
Name: "da.snapshot.file",
Usage: "Snapshot file to sync from da",
}
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1559,6 +1576,18 @@ func setEnableRollupVerify(ctx *cli.Context, cfg *ethconfig.Config) {
}
}

func setDa(ctx *cli.Context, cfg *ethconfig.Config) {
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
if ctx.GlobalIsSet(DaSyncEnabledFlag.Name) {
cfg.EnableDASyncing = ctx.GlobalBool(DaSyncEnabledFlag.Name)
if ctx.GlobalIsSet(DAModeFlag.Name) {
cfg.DA.FetcherMode = *GlobalTextMarshaler(ctx, DAModeFlag.Name).(*da_syncer.FetcherMode)
}
if ctx.GlobalIsSet(DASnapshotFileFlag.Name) {
cfg.DA.SnapshotFilePath = ctx.GlobalString(DASnapshotFileFlag.Name)
}
}
}

func setMaxBlockRange(ctx *cli.Context, cfg *ethconfig.Config) {
if ctx.GlobalIsSet(MaxBlockRangeFlag.Name) {
cfg.MaxBlockRange = ctx.GlobalInt64(MaxBlockRangeFlag.Name)
Expand Down Expand Up @@ -1634,6 +1663,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
setLes(ctx, cfg)
setCircuitCapacityCheck(ctx, cfg)
setEnableRollupVerify(ctx, cfg)
setDa(ctx, cfg)
setMaxBlockRange(ctx, cfg)

// Cap the cache allowance and tune the garbage collector
Expand Down
39 changes: 39 additions & 0 deletions core/rawdb/accessors_da_syncer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package rawdb

import (
"math/big"

"github.com/scroll-tech/go-ethereum/ethdb"
"github.com/scroll-tech/go-ethereum/log"
)

// WriteDASyncedL1BlockNumber writes the highest synced L1 block number to the database.
func WriteDASyncedL1BlockNumber(db ethdb.KeyValueWriter, L1BlockNumber uint64) {
value := big.NewInt(0).SetUint64(L1BlockNumber).Bytes()

if err := db.Put(daSyncedL1BlockNumberKey, value); err != nil {
log.Crit("Failed to update da synced L1 block number", "err", err)
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
}
}

// ReadDASyncedL1BlockNumber retrieves the highest synced L1 block number.
func ReadDASyncedL1BlockNumber(db ethdb.Reader) *uint64 {
data, err := db.Get(daSyncedL1BlockNumberKey)
if err != nil && isNotFoundErr(err) {
return nil
}
if err != nil {
log.Crit("Failed to read da synced L1 block number from database", "err", err)
}
vyzo marked this conversation as resolved.
Show resolved Hide resolved
if len(data) == 0 {
return nil
}

number := new(big.Int).SetBytes(data)
if !number.IsUint64() {
log.Crit("Unexpected da synced L1 block number in database", "number", number)
}
vyzo marked this conversation as resolved.
Show resolved Hide resolved

value := number.Uint64()
return &value
}
3 changes: 3 additions & 0 deletions core/rawdb/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ var (
batchMetaPrefix = []byte("R-bm")
finalizedL2BlockNumberKey = []byte("R-finalized")

// Scroll da syncer store
daSyncedL1BlockNumberKey = []byte("LastDASyncedL1BlockNumber")

// Row consumption
rowConsumptionPrefix = []byte("rc") // rowConsumptionPrefix + hash -> row consumption by block

Expand Down
13 changes: 13 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import (
"github.com/scroll-tech/go-ethereum/p2p/enode"
"github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rlp"
"github.com/scroll-tech/go-ethereum/rollup/da_syncer"
"github.com/scroll-tech/go-ethereum/rollup/rollup_sync_service"
"github.com/scroll-tech/go-ethereum/rollup/sync_service"
"github.com/scroll-tech/go-ethereum/rollup/tracing"
Expand All @@ -73,6 +74,7 @@ type Ethereum struct {
txPool *core.TxPool
syncService *sync_service.SyncService
rollupSyncService *rollup_sync_service.RollupSyncService
daSyncer *da_syncer.DaSyncer
blockchain *core.BlockChain
handler *handler
ethDialCandidates enode.Iterator
Expand Down Expand Up @@ -233,6 +235,14 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client sync_service.EthCl
eth.rollupSyncService.Start()
}

if config.EnableDASyncing {
eth.daSyncer, err = da_syncer.NewDaSyncer(context.Background(), chainConfig, eth.chainDb, l1Client, stack.Config().L1DeploymentBlock, config.DA)
if err != nil {
return nil, fmt.Errorf("cannot initialize da syncer: %w", err)
}
eth.daSyncer.Start()
}

// Permit the downloader to use the trie cache allowance during fast sync
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
checkpoint := config.Checkpoint
Expand Down Expand Up @@ -592,6 +602,9 @@ func (s *Ethereum) Stop() error {
if s.config.EnableRollupVerify {
s.rollupSyncService.Stop()
}
if s.config.EnableDASyncing {
s.daSyncer.Stop()
}
s.miner.Close()
s.blockchain.Stop()
s.engine.Close()
Expand Down
10 changes: 10 additions & 0 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/scroll-tech/go-ethereum/miner"
"github.com/scroll-tech/go-ethereum/node"
"github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rollup/da_syncer"
)

// FullNodeGPO contains default gasprice oracle settings for full node.
Expand Down Expand Up @@ -93,6 +94,9 @@ var Defaults = Config{
GPO: FullNodeGPO,
RPCTxFeeCap: 1, // 1 ether
MaxBlockRange: -1, // Default unconfigured value: no block range limit for backward compatibility
DA: da_syncer.Config{
FetcherMode: da_syncer.L1RPC,
},
}

func init() {
Expand Down Expand Up @@ -217,6 +221,12 @@ type Config struct {

// Max block range for eth_getLogs api method
MaxBlockRange int64

// Enable syncing node from DA
EnableDASyncing bool

// DA syncer config
DA da_syncer.Config
}

// CreateConsensusEngine creates a consensus engine for the given chain configuration.
Expand Down
55 changes: 55 additions & 0 deletions rollup/da_syncer/abi.go
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
NazariiDenha marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package da_syncer

import (
"fmt"
"math/big"

"github.com/scroll-tech/go-ethereum/accounts/abi"
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
)

// scrollChainMetaData contains ABI of the ScrollChain contract.
var scrollChainMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_chainId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"batchIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"batchHash\",\"type\":\"bytes32\"}],\"name\":\"CommitBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"batchIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"batchHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"withdrawRoot\",\"type\":\"bytes32\"}],\"name\":\"FinalizeBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"batchIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"batchHash\",\"type\":\"bytes32\"}],\"name\":\"RevertBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxNumTxInChunk\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newMaxNumTxInChunk\",\"type\":\"uint256\"}],\"name\":\"UpdateMaxNumTxInChunk\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"UpdateProver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"UpdateSequencer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldVerifier\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newVerifier\",\"type\":\"address\"}],\"name\":\"UpdateVerifier\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"addProver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"addSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"_version\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_parentBatchHeader\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"_chunks\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"_skippedL1MessageBitmap\",\"type\":\"bytes\"}],\"name\":\"commitBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"committedBatches\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_batchHeader\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_prevStateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_postStateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_withdrawRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_aggrProof\",\"type\":\"bytes\"}],\"name\":\"finalizeBatchWithProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"finalizedStateRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_batchHeader\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_stateRoot\",\"type\":\"bytes32\"}],\"name\":\"importGenesisBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_messageQueue\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_maxNumTxInChunk\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_batchIndex\",\"type\":\"uint256\"}],\"name\":\"isBatchFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isProver\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isSequencer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastFinalizedBatchIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"layer2ChainId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxNumTxInChunk\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageQueue\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"removeProver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"removeSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_batchHeader\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_count\",\"type\":\"uint256\"}],\"name\":\"revertBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_status\",\"type\":\"bool\"}],\"name\":\"setPause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxNumTxInChunk\",\"type\":\"uint256\"}],\"name\":\"updateMaxNumTxInChunk\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newVerifier\",\"type\":\"address\"}],\"name\":\"updateVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
}

// L1CommitBatchEvent represents a CommitBatch event raised by the ScrollChain contract.
type L1CommitBatchEvent struct {
BatchIndex *big.Int
BatchHash common.Hash
}

// L1RevertBatchEvent represents a RevertBatch event raised by the ScrollChain contract.
type L1RevertBatchEvent struct {
BatchIndex *big.Int
BatchHash common.Hash
}

// L1FinalizeBatchEvent represents a FinalizeBatch event raised by the ScrollChain contract.
type L1FinalizeBatchEvent struct {
BatchIndex *big.Int
BatchHash common.Hash
StateRoot common.Hash
WithdrawRoot common.Hash
}

// UnpackLog unpacks a retrieved log into the provided output structure.
func UnpackLog(c *abi.ABI, out interface{}, event string, log types.Log) error {
if log.Topics[0] != c.Events[event].ID {
return fmt.Errorf("event signature mismatch")
}
if len(log.Data) > 0 {
if err := c.UnpackIntoInterface(out, event, log.Data); err != nil {
return err
}
}
var indexed abi.Arguments
for _, arg := range c.Events[event].Inputs {
if arg.Indexed {
indexed = append(indexed, arg)
}
}
return abi.ParseTopics(out, indexed, log.Topics[1:])
}
36 changes: 36 additions & 0 deletions rollup/da_syncer/block_context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package da_syncer

import (
"encoding/binary"
"errors"
"math/big"
)

// BlockContext represents the essential data of a block in the ScrollChain.
// It provides an overview of block attributes including hash values, block numbers, gas details, and transaction counts.
type BlockContext struct {
BlockNumber uint64
Timestamp uint64
BaseFee *big.Int
GasLimit uint64
NumTransactions uint16
NumL1Messages uint16
}

type BlockContexts []*BlockContext

func decodeBlockContext(encodedBlockContext []byte) (*BlockContext, error) {
if len(encodedBlockContext) != blockContextByteSize {
return nil, errors.New("block encoding is not 60 bytes long")
}
baseFee := big.NewInt(0).SetBytes(encodedBlockContext[16:48])

return &BlockContext{
BlockNumber: binary.BigEndian.Uint64(encodedBlockContext[0:8]),
Timestamp: binary.BigEndian.Uint64(encodedBlockContext[8:16]),
BaseFee: baseFee,
GasLimit: binary.BigEndian.Uint64(encodedBlockContext[48:56]),
NumTransactions: binary.BigEndian.Uint16(encodedBlockContext[56:58]),
NumL1Messages: binary.BigEndian.Uint16(encodedBlockContext[58:60]),
}, nil
}
72 changes: 72 additions & 0 deletions rollup/da_syncer/chunk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package da_syncer

import (
"encoding/binary"
"fmt"
)

const blockContextByteSize = 60

type Chunk struct {
BlockContexts BlockContexts
L2Txs [][]byte
}

type Chunks []*Chunk

// decodeChunks decodes the provided chunks into a list of chunks.
func decodeChunks(chunksData [][]byte) (Chunks, error) {
var chunks Chunks
for _, chunk := range chunksData {
if len(chunk) < 1 {
return nil, fmt.Errorf("invalid chunk, length is less than 1")
}

numBlocks := int(chunk[0])
if len(chunk) < 1+numBlocks*blockContextByteSize {
return nil, fmt.Errorf("chunk size doesn't match with numBlocks, byte length of chunk: %v, expected length: %v", len(chunk), 1+numBlocks*blockContextByteSize)
}

blockContexts := make(BlockContexts, numBlocks)
for i := 0; i < numBlocks; i++ {
startIdx := 1 + i*blockContextByteSize // add 1 to skip numBlocks byte
endIdx := startIdx + blockContextByteSize
blockContext, err := decodeBlockContext(chunk[startIdx:endIdx])
if err != nil {
return nil, err
}
blockContexts[i] = blockContext
}

var l2Txs [][]byte
txLen := 0

for currentIndex := 1 + numBlocks*blockContextByteSize; currentIndex < len(chunk); currentIndex += 4 + txLen {
if len(chunk) < currentIndex+4 {
return nil, fmt.Errorf("chunk size doesn't match, next tx size is less then 4, byte length of chunk: %v, expected length: %v", len(chunk), currentIndex+4)
}
txLen = int(binary.BigEndian.Uint32(chunk[currentIndex : currentIndex+4]))
if len(chunk) < currentIndex+4+txLen {
return nil, fmt.Errorf("chunk size doesn't match with next tx length, byte length of chunk: %v, expected length: %v", len(chunk), currentIndex+4+txLen)
}
txData := chunk[currentIndex+4 : currentIndex+4+txLen]
l2Txs = append(l2Txs, txData)
}

chunks = append(chunks, &Chunk{
BlockContexts: blockContexts,
L2Txs: l2Txs,
})
}
return chunks, nil
}

func countTotalL1MessagePopped(chunks Chunks) uint64 {
var total uint64 = 0
for _, chunk := range chunks {
for _, block := range chunk.BlockContexts {
total += uint64(block.NumL1Messages)
}
}
return total
}
Loading
Loading