Skip to content

Commit 4e5839f

Browse files
author
colinlyguo
committed
add proposer tool
1 parent a77f141 commit 4e5839f

File tree

18 files changed

+396
-31
lines changed

18 files changed

+396
-31
lines changed

common/version/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"runtime/debug"
66
)
77

8-
var tag = "v4.5.4"
8+
var tag = "v4.5.5"
99

1010
var commit = func() string {
1111
if info, ok := debug.ReadBuildInfo(); ok {

database/cmd/app/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func resetDB(ctx *cli.Context) error {
4242
}
4343

4444
var version int64
45-
err = migrate.Rollback(db.DB, &version)
45+
err = migrate.ResetDB(db.DB)
4646
if err != nil {
4747
return err
4848
}

rollup/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,32 @@ make rollup_bins
3333
./build/bin/gas_oracle --config ./conf/config.json
3434
./build/bin/rollup_relayer --config ./conf/config.json
3535
```
36+
37+
## How to run the proposer tool?
38+
39+
### Set the configs
40+
41+
1. Set genesis config to enable desired hardforks in [`proposer-tool-genesis.json`](./proposer-tool-genesis.json).
42+
2. Set proposer config in [`proposer-tool-config.json`](./proposer-tool-config.json) for data analysis.
43+
44+
### Start the proposer tool using docker-compose.
45+
46+
```
47+
cd rollup
48+
DOCKER_BUILDKIT=1 docker-compose -f docker-compose-proposer-tool.yml up -d
49+
```
50+
51+
> Note: The port 5432 of database is mapped to the host machine. You can use `psql` or any db clients to connect to the database.
52+
53+
> The DSN for the database is `postgres://postgres:postgres@db:5432/scroll?sslmode=disable`.
54+
55+
56+
### Reset env
57+
```
58+
docker-compose -f docker-compose-proposer-tool.yml down -v
59+
```
60+
61+
If you need to rebuild the images, removing the old images is necessary. You can do this by running the following command:
62+
```
63+
docker images | grep rollup | awk '{print $3}' | xargs docker rmi -f
64+
```
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"math/big"
7+
"os"
8+
"os/signal"
9+
"time"
10+
11+
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/scroll-tech/da-codec/encoding"
13+
"github.com/scroll-tech/go-ethereum/common"
14+
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
15+
"github.com/scroll-tech/go-ethereum/ethclient"
16+
"github.com/scroll-tech/go-ethereum/log"
17+
"github.com/urfave/cli/v2"
18+
19+
"scroll-tech/common/database"
20+
"scroll-tech/common/types"
21+
"scroll-tech/common/utils"
22+
"scroll-tech/common/version"
23+
24+
"scroll-tech/rollup/internal/config"
25+
"scroll-tech/rollup/internal/controller/watcher"
26+
"scroll-tech/rollup/internal/orm"
27+
rutils "scroll-tech/rollup/internal/utils"
28+
)
29+
30+
var app *cli.App
31+
32+
func init() {
33+
// Set up proposer-tool app info.
34+
app = cli.NewApp()
35+
app.Action = action
36+
app.Name = "proposer-tool"
37+
app.Usage = "The Scroll Proposer Tool"
38+
app.Version = version.Version
39+
app.Flags = append(app.Flags, utils.CommonFlags...)
40+
app.Flags = append(app.Flags, utils.RollupRelayerFlags...)
41+
app.Commands = []*cli.Command{}
42+
app.Before = func(ctx *cli.Context) error {
43+
return utils.LogSetup(ctx)
44+
}
45+
}
46+
47+
func action(ctx *cli.Context) error {
48+
// Load config file.
49+
cfgFile := ctx.String(utils.ConfigFileFlag.Name)
50+
cfg, err := config.NewConfig(cfgFile)
51+
if err != nil {
52+
log.Crit("failed to load config file", "config file", cfgFile, "error", err)
53+
}
54+
55+
subCtx, cancel := context.WithCancel(ctx.Context)
56+
// Init db connection
57+
db, err := database.InitDB(cfg.DBConfig)
58+
if err != nil {
59+
log.Crit("failed to init db connection", "err", err)
60+
}
61+
defer func() {
62+
cancel()
63+
if err = database.CloseDB(db); err != nil {
64+
log.Crit("failed to close db connection", "error", err)
65+
}
66+
}()
67+
68+
// Init l2BlockOrm connection
69+
dbForReplay, err := database.InitDB(cfg.DBConfigForReplay)
70+
if err != nil {
71+
log.Crit("failed to init l2BlockOrm connection", "err", err)
72+
}
73+
defer func() {
74+
cancel()
75+
if err = database.CloseDB(dbForReplay); err != nil {
76+
log.Crit("failed to close l2BlockOrm connection", "error", err)
77+
}
78+
}()
79+
80+
// Init l2geth connection
81+
l2Client, err := ethclient.Dial(cfg.L2Config.Endpoint)
82+
if err != nil {
83+
log.Crit("failed to connect l2 geth", "config file", cfgFile, "error", err)
84+
}
85+
86+
genesisHeader, err := l2Client.HeaderByNumber(subCtx, big.NewInt(0))
87+
if err != nil {
88+
return fmt.Errorf("failed to retrieve L2 genesis header: %v", err)
89+
}
90+
91+
genesisTime := genesisHeader.Time
92+
currentTime := uint64(time.Now().Unix())
93+
timeDrift := currentTime - genesisTime
94+
95+
cfg.L2Config.ChunkProposerConfig.ChunkTimeoutSec += timeDrift
96+
cfg.L2Config.BatchProposerConfig.BatchTimeoutSec += timeDrift
97+
cfg.L2Config.BundleProposerConfig.BundleTimeoutSec += timeDrift
98+
99+
chunk := &encoding.Chunk{
100+
Blocks: []*encoding.Block{{
101+
Header: genesisHeader,
102+
Transactions: nil,
103+
WithdrawRoot: common.Hash{},
104+
RowConsumption: &gethTypes.RowConsumption{},
105+
}},
106+
}
107+
108+
var dbChunk *orm.Chunk
109+
dbChunk, err = orm.NewChunk(db).InsertChunk(subCtx, chunk, encoding.CodecV0, rutils.ChunkMetrics{})
110+
if err != nil {
111+
log.Crit("failed to insert chunk", "error", err)
112+
}
113+
114+
if err = orm.NewChunk(db).UpdateProvingStatus(subCtx, dbChunk.Hash, types.ProvingTaskVerified); err != nil {
115+
log.Crit("failed to update genesis chunk proving status", "error", err)
116+
}
117+
118+
batch := &encoding.Batch{
119+
Index: 0,
120+
TotalL1MessagePoppedBefore: 0,
121+
ParentBatchHash: common.Hash{},
122+
Chunks: []*encoding.Chunk{chunk},
123+
}
124+
125+
var dbBatch *orm.Batch
126+
dbBatch, err = orm.NewBatch(db).InsertBatch(subCtx, batch, encoding.CodecV0, rutils.BatchMetrics{})
127+
if err != nil {
128+
log.Crit("failed to insert batch", "error", err)
129+
}
130+
131+
if err = orm.NewChunk(db).UpdateBatchHashInRange(subCtx, 0, 0, dbBatch.Hash); err != nil {
132+
log.Crit("failed to update batch hash for chunks", "error", err)
133+
}
134+
135+
registry := prometheus.DefaultRegisterer
136+
137+
genesisPath := ctx.String(utils.Genesis.Name)
138+
genesis, err := utils.ReadGenesis(genesisPath)
139+
if err != nil {
140+
log.Crit("failed to read genesis", "genesis file", genesisPath, "error", err)
141+
}
142+
143+
// sanity check config
144+
if cfg.L2Config.BatchProposerConfig.MaxChunksPerBatch <= 0 {
145+
log.Crit("cfg.L2Config.BatchProposerConfig.MaxChunksPerBatch must be greater than 0")
146+
}
147+
if cfg.L2Config.ChunkProposerConfig.MaxL2GasPerChunk <= 0 {
148+
log.Crit("cfg.L2Config.ChunkProposerConfig.MaxL2GasPerChunk must be greater than 0")
149+
}
150+
151+
minCodecVersion := encoding.CodecVersion(ctx.Uint(utils.MinCodecVersionFlag.Name))
152+
chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, minCodecVersion, genesis.Config, dbForReplay, db, registry, true /* used by tool */)
153+
batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, minCodecVersion, genesis.Config, dbForReplay, db, registry)
154+
bundleProposer := watcher.NewBundleProposer(subCtx, cfg.L2Config.BundleProposerConfig, minCodecVersion, genesis.Config, db, registry)
155+
156+
go utils.Loop(subCtx, 100*time.Millisecond, chunkProposer.TryProposeChunk)
157+
go utils.Loop(subCtx, 100*time.Millisecond, batchProposer.TryProposeBatch)
158+
go utils.Loop(subCtx, 100*time.Millisecond, bundleProposer.TryProposeBundle)
159+
160+
// Finish start all proposer tool functions.
161+
log.Info("Start proposer-tool successfully", "version", version.Version)
162+
163+
// Catch CTRL-C to ensure a graceful shutdown.
164+
interrupt := make(chan os.Signal, 1)
165+
signal.Notify(interrupt, os.Interrupt)
166+
167+
// Wait until the interrupt signal is received from an OS signal.
168+
<-interrupt
169+
170+
return nil
171+
}
172+
173+
// Run proposer tool cmd instance.
174+
func Run() {
175+
if err := app.Run(os.Args); err != nil {
176+
_, _ = fmt.Fprintln(os.Stderr, err)
177+
os.Exit(1)
178+
}
179+
}

rollup/cmd/proposer_tool/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
import "scroll-tech/rollup/cmd/proposer_tool/app"
4+
5+
func main() {
6+
app.Run()
7+
}

rollup/cmd/rollup_relayer/app/app.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ func action(ctx *cli.Context) error {
102102
}
103103

104104
minCodecVersion := encoding.CodecVersion(ctx.Uint(utils.MinCodecVersionFlag.Name))
105-
chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, minCodecVersion, genesis.Config, db, registry)
106-
batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, minCodecVersion, genesis.Config, db, registry)
105+
chunkProposer := watcher.NewChunkProposer(subCtx, cfg.L2Config.ChunkProposerConfig, minCodecVersion, genesis.Config, db, db, registry, false /* not used by tool */)
106+
batchProposer := watcher.NewBatchProposer(subCtx, cfg.L2Config.BatchProposerConfig, minCodecVersion, genesis.Config, db, db, registry)
107107
bundleProposer := watcher.NewBundleProposer(subCtx, cfg.L2Config.BundleProposerConfig, minCodecVersion, genesis.Config, db, registry)
108108

109109
l2watcher := watcher.NewL2WatcherClient(subCtx, l2client, cfg.L2Config.Confirmations, cfg.L2Config.L2MessageQueueAddress, cfg.L2Config.WithdrawTrieRootSlot, genesis.Config, db, registry)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
version: '3'
2+
3+
services:
4+
db:
5+
image: postgres:14
6+
environment:
7+
- POSTGRES_USER=postgres
8+
- POSTGRES_PASSWORD=postgres
9+
- POSTGRES_DB=scroll
10+
ports:
11+
- "5432:5432"
12+
volumes:
13+
- postgres_data:/var/lib/postgresql/data
14+
healthcheck:
15+
test: ["CMD-SHELL", "pg_isready -U postgres"]
16+
interval: 5s
17+
timeout: 5s
18+
retries: 5
19+
20+
db-client:
21+
build:
22+
context: ..
23+
dockerfile: ./build/dockerfiles/db_cli.Dockerfile
24+
depends_on:
25+
db:
26+
condition: service_healthy
27+
command: ["reset", "--config", "/app/conf/proposer-tool-db-config.json"]
28+
volumes:
29+
- ./proposer-tool-db-config.json:/app/conf/proposer-tool-db-config.json
30+
31+
proposer-tool:
32+
build:
33+
context: ..
34+
dockerfile: ./rollup/proposer_tool.Dockerfile
35+
depends_on:
36+
db-client:
37+
condition: service_completed_successfully
38+
command: [
39+
"--config", "/app/conf/proposer-tool-config.json",
40+
"--genesis", "/app/conf/proposer-tool-genesis.json",
41+
"--min-codec-version", "4",
42+
"--log.debug", "--verbosity", "3"
43+
]
44+
volumes:
45+
- ./proposer-tool-config.json:/app/conf/proposer-tool-config.json
46+
- ./proposer-tool-genesis.json:/app/conf/proposer-tool-genesis.json
47+
restart: unless-stopped
48+
49+
volumes:
50+
postgres_data:

rollup/internal/config/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import (
1515

1616
// Config load configuration items.
1717
type Config struct {
18-
L1Config *L1Config `json:"l1_config"`
19-
L2Config *L2Config `json:"l2_config"`
20-
DBConfig *database.Config `json:"db_config"`
18+
L1Config *L1Config `json:"l1_config"`
19+
L2Config *L2Config `json:"l2_config"`
20+
DBConfig *database.Config `json:"db_config"`
21+
DBConfigForReplay *database.Config `json:"db_config_for_replay"`
2122
}
2223

2324
// NewConfig returns a new instance of Config.

rollup/internal/controller/watcher/batch_proposer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type BatchProposer struct {
5959
}
6060

6161
// NewBatchProposer creates a new BatchProposer instance.
62-
func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, minCodecVersion encoding.CodecVersion, chainCfg *params.ChainConfig, db *gorm.DB, reg prometheus.Registerer) *BatchProposer {
62+
func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, minCodecVersion encoding.CodecVersion, chainCfg *params.ChainConfig, l2BlockDB, db *gorm.DB, reg prometheus.Registerer) *BatchProposer {
6363
log.Info("new batch proposer",
6464
"maxL1CommitGasPerBatch", cfg.MaxL1CommitGasPerBatch,
6565
"maxL1CommitCalldataSizePerBatch", cfg.MaxL1CommitCalldataSizePerBatch,
@@ -73,7 +73,7 @@ func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, minC
7373
db: db,
7474
batchOrm: orm.NewBatch(db),
7575
chunkOrm: orm.NewChunk(db),
76-
l2BlockOrm: orm.NewL2Block(db),
76+
l2BlockOrm: orm.NewL2Block(l2BlockDB),
7777
maxL1CommitGasPerBatch: cfg.MaxL1CommitGasPerBatch,
7878
maxL1CommitCalldataSizePerBatch: cfg.MaxL1CommitCalldataSizePerBatch,
7979
batchTimeoutSec: cfg.BatchTimeoutSec,

0 commit comments

Comments
 (0)