Compare commits

..

18 Commits

Author SHA1 Message Date
HAOYUatHZ
38551c4eeb refactor: rename bridge to rollup (#644)
Co-authored-by: HAOYUatHZ <HAOYUatHZ@users.noreply.github.com>
2023-09-02 15:42:01 +08:00
HAOYUatHZ
82330621ce docs(): update README 2023-09-02 15:08:37 +08:00
maskpp
237d048ce6 feat(prover): update l2geth version and enable use compression when get trace (#915)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <HAOYUatHZ@users.noreply.github.com>
2023-09-02 14:38:47 +08:00
Haichen Shen
38b440b1fa docs(contract): Update readme (#378)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Orest Tarasiuk <830847+OrestTa@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-09-01 20:22:09 -07:00
Péter Garamvölgyi
0ed3d68fc3 ci: remove message_relayer Github Action (#914) 2023-09-01 19:44:36 +02:00
Nazarii Denha
2847d02498 refactor(bridge): remove message-relayer and related code (#670)
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: NazariiDenha <NazariiDenha@users.noreply.github.com>
Co-authored-by: colinlyguo <colinlyguo@scroll.io>
2023-09-01 19:04:09 +02:00
Xi Lin
a7d9bf3488 fix(contracts): OZ-N05 Lack of Logs on Sensitive Actions (#908)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 22:55:11 +08:00
Xi Lin
255eb5f307 fix(contracts): OZ-L02 Utilizing Deprecated Function From Library (#902)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 22:42:20 +08:00
Haichen Shen
0955382aec fix(ci): enable the bump-version bot when PR is updated (#905)
Co-authored-by: icemelon <icemelon@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 22:41:23 +08:00
Xi Lin
07961f751e fix(contracts): OZ-N01 Variable Cast is Unnecessary (#903)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 22:18:17 +08:00
Xi Lin
bbd5a5a9c2 fix(contracts): OZ-N02 Incorrect Function Visibility (#904)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 21:58:47 +08:00
Xi Lin
2e1f42fcb6 fix(contracts): OZ-N04 Implicit Type Casting (#907)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 19:45:35 +08:00
Xi Lin
bcdbe1f119 fix(contracts): OZ-N07 Naming Issue (#910)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 19:29:57 +08:00
Xi Lin
6034c43bb1 fix(contracts): OZ-N06 Unpinned Compiler Version (#909) 2023-09-01 19:20:10 +08:00
colin
f9da81d587 feat(rollup-relayer): use db gas estimation as min gas limit (#901)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
Co-authored-by: Xi Lin <zimpha@gmail.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-09-01 14:54:57 +08:00
Xi Lin
38f64e70b7 feat(contracts): bench test for ScrollChain (#721)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <HAOYUatHZ@users.noreply.github.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
Co-authored-by: zimpha <zimpha@users.noreply.github.com>
Co-authored-by: icemelon <icemelon@users.noreply.github.com>
2023-08-31 23:52:50 -07:00
Haichen Shen
44b924170a fix(ci): don't trigger CI for version change (#898)
Co-authored-by: icemelon <icemelon@users.noreply.github.com>
2023-08-31 23:06:32 -07:00
georgehao
227f09a2cf feat(coordinator): pretty log (#900)
Co-authored-by: georgehao <georgehao@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <haoyu@protonmail.com>
2023-09-01 12:56:03 +08:00
126 changed files with 1292 additions and 1456 deletions

View File

@@ -20,7 +20,7 @@ Your PR title must follow [conventional commits](https://www.conventionalcommits
### Deployment tag versioning
Has `tag` in `common/version.go` been updated?
Has `tag` in `common/version.go` been updated or have you added `bump-version` label to this PR?
- [ ] No, this PR doesn't involve a new deployment, git tag, docker image tag
- [ ] Yes

View File

@@ -2,15 +2,17 @@ name: Bump Version
on:
pull_request:
branches: [develop]
branches: [ develop ]
types:
- opened
- reopened
- synchronize
- ready_for_review
- labeled
jobs:
try-to-bump:
if: contains(github.event.pull_request.labels.*.name, 'bump-version')
runs-on: ubuntu-latest
steps:
- name: Checkout code

View File

@@ -9,6 +9,7 @@ on:
- alpha
paths:
- 'common/**'
- '!common/version/version.go'
- '.github/workflows/common.yml'
pull_request:
types:
@@ -18,6 +19,7 @@ on:
- ready_for_review
paths:
- 'common/**'
- '!common/version/version.go'
- '.github/workflows/common.yml'
jobs:

View File

@@ -10,6 +10,7 @@ on:
paths:
- 'coordinator/**'
- 'common/**'
- '!common/version/version.go'
- 'database/**'
- '.github/workflows/coordinator.yml'
pull_request:
@@ -21,6 +22,7 @@ on:
paths:
- 'coordinator/**'
- 'common/**'
- '!common/version/version.go'
- 'database/**'
- '.github/workflows/coordinator.yml'

View File

@@ -10,6 +10,7 @@ on:
paths:
- 'database/**'
- 'common/**'
- '!common/version/version.go'
- '.github/workflows/database.yml'
pull_request:
types:
@@ -20,6 +21,7 @@ on:
paths:
- 'database/**'
- 'common/**'
- '!common/version/version.go'
- '.github/workflows/database.yml'
jobs:

View File

@@ -48,27 +48,6 @@ jobs:
tags: scrolltech/gas-oracle:${{github.ref_name}}
# cache-from: type=gha,scope=${{ github.workflow }}
# cache-to: type=gha,scope=${{ github.workflow }}
msg_relayer:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push msg_relayer docker
uses: docker/build-push-action@v2
with:
context: .
file: ./build/dockerfiles/msg_relayer.Dockerfile
push: true
tags: scrolltech/msg-relayer:${{github.ref_name}}
# cache-from: type=gha,scope=${{ github.workflow }}
# cache-to: type=gha,scope=${{ github.workflow }}
rollup_relayer:
runs-on: ubuntu-latest
steps:

View File

@@ -36,7 +36,7 @@ jobs:
- name: Build prerequisites
run: |
make dev_docker
make -C bridge mock_abi
make -C rollup mock_abi
make -C common/bytecode all
- name: Run integration tests
run: |

View File

@@ -1,4 +1,4 @@
name: Bridge
name: Rollup
on:
push:
@@ -8,10 +8,11 @@ on:
- develop
- alpha
paths:
- 'bridge/**'
- 'rollup/**'
- 'common/**'
- '!common/version/version.go'
- 'database/**'
- '.github/workflows/bridge.yml'
- '.github/workflows/rollup.yml'
pull_request:
types:
- opened
@@ -19,10 +20,11 @@ on:
- synchronize
- ready_for_review
paths:
- 'bridge/**'
- 'rollup/**'
- 'common/**'
- '!common/version/version.go'
- 'database/**'
- '.github/workflows/bridge.yml'
- '.github/workflows/rollup.yml'
jobs:
check:
@@ -44,7 +46,7 @@ jobs:
- name: Install Geth Tools
uses: gacts/install-geth-tools@v1
- name: Lint
working-directory: 'bridge'
working-directory: 'rollup'
run: |
rm -rf $HOME/.cache/golangci-lint
make mock_abi
@@ -62,14 +64,14 @@ jobs:
- name: Install goimports
run: go install golang.org/x/tools/cmd/goimports
- name: Run goimports lint
run: goimports -local scroll-tech/bridge/ -w .
working-directory: 'bridge'
run: goimports -local scroll-tech/rollup/ -w .
working-directory: 'rollup'
- name: Run go mod tidy
run: go mod tidy
working-directory: 'bridge'
working-directory: 'rollup'
# If there are any diffs from goimports or go mod tidy, fail.
- name: Verify no changes from goimports and go mod tidy
working-directory: 'bridge'
working-directory: 'rollup'
run: |
if [ -n "$(git status --porcelain)" ]; then
exit 1
@@ -95,13 +97,13 @@ jobs:
- name: Build prerequisites
run: |
make dev_docker
make -C bridge mock_abi
- name: Build bridge binaries
working-directory: 'bridge'
make -C rollup mock_abi
- name: Build rollup binaries
working-directory: 'rollup'
run: |
make bridge_bins
- name: Test bridge packages
working-directory: 'bridge'
make rollup_bins
- name: Test rollup packages
working-directory: 'rollup'
run: |
go test -v -race -gcflags="-l" -ldflags="-s=false" -coverprofile=coverage.txt -covermode=atomic ./...
- name: Upload coverage reports to Codecov
@@ -109,7 +111,7 @@ jobs:
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
flags: bridge
flags: rollup
# docker-build:
# if: github.event.pull_request.draft == false
# runs-on: ubuntu-latest

View File

@@ -1,6 +1,6 @@
.PHONY: check update dev_docker build_test_docker run_test_docker clean
L2GETH_TAG=scroll-v4.3.34
L2GETH_TAG=scroll-v4.3.55
help: ## Display this help message
@grep -h \
@@ -8,7 +8,7 @@ help: ## Display this help message
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
lint: ## The code's format and security checks.
make -C bridge lint
make -C rollup lint
make -C common lint
make -C coordinator lint
make -C database lint
@@ -17,7 +17,7 @@ lint: ## The code's format and security checks.
update: ## update dependencies
go work sync
cd $(PWD)/bridge/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
cd $(PWD)/rollup/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
cd $(PWD)/bridge-history-api/ && go get -u github.com/ethereum/go-ethereum@latest && go mod tidy
cd $(PWD)/common/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
cd $(PWD)/coordinator/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
@@ -25,7 +25,7 @@ update: ## update dependencies
cd $(PWD)/prover/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
cd $(PWD)/prover-stats-api/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
cd $(PWD)/tests/integration-test/ && go get -u github.com/scroll-tech/go-ethereum@${L2GETH_TAG} && go mod tidy
goimports -local $(PWD)/bridge/ -w .
goimports -local $(PWD)/rollup/ -w .
goimports -local $(PWD)/bridge-history-api/ -w .
goimports -local $(PWD)/common/ -w .
goimports -local $(PWD)/coordinator/ -w .

View File

@@ -15,14 +15,14 @@ docker pull postgres
make dev_docker
```
## Testing Bridge & Coordinator
## Testing Rollup & Coordinator
### For Non-Apple Silicon (M1/M2) Macs
Run the tests using the following commands:
```bash
go test -v -race -covermode=atomic scroll-tech/bridge/...
go test -v -race -covermode=atomic scroll-tech/rollup/...
go test -tags="mock_verifier" -v -race -covermode=atomic scroll-tech/coordinator/...
go test -v -race -covermode=atomic scroll-tech/database/...
go test -v -race -covermode=atomic scroll-tech/common/...
@@ -55,7 +55,7 @@ This command runs a Docker container named `scroll_test_container` from the `scr
Once the Docker container is running, execute the tests using the following commands:
```bash
go test -v -race -covermode=atomic scroll-tech/bridge/...
go test -v -race -covermode=atomic scroll-tech/rollup/...
go test -tags="mock_verifier" -v -race -covermode=atomic scroll-tech/coordinator/...
go test -v -race -covermode=atomic scroll-tech/database/...
go test -v -race -covermode=atomic scroll-tech/common/...

View File

@@ -89,9 +89,6 @@ var (
// L2FailedRelayedMessageEventSignature = keccak256("FailedRelayedMessage(bytes32)")
L2FailedRelayedMessageEventSignature common.Hash
// L2ImportBlockEventSignature = keccak256("ImportBlock(bytes32,uint256,uint256,uint256,bytes32)")
L2ImportBlockEventSignature common.Hash
// L2AppendMessageEventSignature = keccak256("AppendMessage(uint256,bytes32)")
L2AppendMessageEventSignature common.Hash
)
@@ -153,8 +150,6 @@ func init() {
L2RelayedMessageEventSignature = L2ScrollMessengerABI.Events["RelayedMessage"].ID
L2FailedRelayedMessageEventSignature = L2ScrollMessengerABI.Events["FailedRelayedMessage"].ID
L2ImportBlockEventSignature = L1BlockContainerABI.Events["ImportBlock"].ID
L2AppendMessageEventSignature = L2MessageQueueABI.Events["AppendMessage"].ID
}

View File

@@ -1,36 +0,0 @@
# Bridge
This repo contains the Scroll bridge.
In addition, launching the bridge will launch a separate instance of l2geth, and sets up a communication channel
between the two, over JSON-RPC sockets.
Something we should pay attention is that all private keys inside sender instance cannot be duplicated.
## Dependency
+ install `abigen`
``` bash
go install -v github.com/scroll-tech/go-ethereum/cmd/abigen
```
## Build
```bash
make clean
make bridge
```
## Start
* use default ports and config.json
```bash
./build/bin/bridge --http
```
* use specified ports and config.json
```bash
./build/bin/bridge --config ./config.json --http --http.addr localhost --http.port 8290
```

View File

@@ -1,7 +0,0 @@
package main
import "scroll-tech/bridge/cmd/event_watcher/app"
func main() {
app.Run()
}

View File

@@ -1,7 +0,0 @@
package main
import "scroll-tech/bridge/cmd/gas_oracle/app"
func main() {
app.Run()
}

View File

@@ -1,94 +0,0 @@
package app
import (
"context"
"fmt"
"os"
"os/signal"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/scroll-tech/go-ethereum/log"
"github.com/urfave/cli/v2"
"scroll-tech/common/database"
"scroll-tech/common/metrics"
"scroll-tech/common/utils"
"scroll-tech/common/version"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/relayer"
)
var app *cli.App
func init() {
// Set up message-relayer app info.
app = cli.NewApp()
app.Action = action
app.Name = "message-relayer"
app.Usage = "The Scroll Message Relayer"
app.Description = "Message Relayer contains two main service: 1) relay l1 message to l2. 2) relay l2 message to l1."
app.Version = version.Version
app.Flags = append(app.Flags, utils.CommonFlags...)
app.Commands = []*cli.Command{}
app.Before = func(ctx *cli.Context) error {
return utils.LogSetup(ctx)
}
// Register `message-relayer-test` app for integration-test.
utils.RegisterSimulation(app, utils.MessageRelayerApp)
}
func action(ctx *cli.Context) error {
// Load config file.
cfgFile := ctx.String(utils.ConfigFileFlag.Name)
cfg, err := config.NewConfig(cfgFile)
if err != nil {
log.Crit("failed to load config file", "config file", cfgFile, "error", err)
}
subCtx, cancel := context.WithCancel(ctx.Context)
// Init db connection
db, err := database.InitDB(cfg.DBConfig)
if err != nil {
log.Crit("failed to init db connection", "err", err)
}
defer func() {
cancel()
if err = database.CloseDB(db); err != nil {
log.Error("can not close ormFactory", "error", err)
}
}()
registry := prometheus.DefaultRegisterer
metrics.Server(ctx, registry.(*prometheus.Registry))
l1relayer, err := relayer.NewLayer1Relayer(ctx.Context, db, cfg.L1Config.RelayerConfig, registry)
if err != nil {
log.Error("failed to create new l1 relayer", "config file", cfgFile, "error", err)
return err
}
// Start l1relayer process
go utils.Loop(subCtx, 10*time.Second, l1relayer.ProcessSavedEvents)
// Finish start all message relayer functions
log.Info("Start message-relayer successfully")
// Catch CTRL-C to ensure a graceful shutdown.
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
// Wait until the interrupt signal is received from an OS signal.
<-interrupt
return nil
}
// Run message_relayer cmd instance.
func Run() {
if err := app.Run(os.Args); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

View File

@@ -1,7 +0,0 @@
package main
import "scroll-tech/bridge/cmd/msg_relayer/app"
func main() {
app.Run()
}

View File

@@ -1,7 +0,0 @@
package main
import "scroll-tech/bridge/cmd/rollup_relayer/app"
func main() {
app.Run()
}

View File

@@ -1,54 +0,0 @@
package relayer
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type l1RelayerMetrics struct {
bridgeL1RelayedMsgsTotal prometheus.Counter
bridgeL1RelayedMsgsFailureTotal prometheus.Counter
bridgeL1RelayerGasPriceOraclerRunTotal prometheus.Counter
bridgeL1RelayerLastGasPrice prometheus.Gauge
bridgeL1MsgsRelayedConfirmedTotal prometheus.Counter
bridgeL1GasOraclerConfirmedTotal prometheus.Counter
}
var (
initL1RelayerMetricOnce sync.Once
l1RelayerMetric *l1RelayerMetrics
)
func initL1RelayerMetrics(reg prometheus.Registerer) *l1RelayerMetrics {
initL1RelayerMetricOnce.Do(func() {
l1RelayerMetric = &l1RelayerMetrics{
bridgeL1RelayedMsgsTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer1_msg_relayed_total",
Help: "The total number of the l1 relayed message.",
}),
bridgeL1RelayedMsgsFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer1_msg_relayed_failure_total",
Help: "The total number of the l1 relayed failure message.",
}),
bridgeL1MsgsRelayedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer1_relayed_confirmed_total",
Help: "The total number of layer1 relayed confirmed",
}),
bridgeL1RelayerGasPriceOraclerRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer1_gas_price_oracler_total",
Help: "The total number of layer1 gas price oracler run total",
}),
bridgeL1RelayerLastGasPrice: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_layer1_gas_price_latest_gas_price",
Help: "The latest gas price of bridge relayer l1",
}),
bridgeL1GasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer1_gas_oracler_confirmed_total",
Help: "The total number of layer1 relayed confirmed",
}),
}
})
return l1RelayerMetric
}

View File

@@ -1,84 +0,0 @@
package relayer
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type l2RelayerMetrics struct {
bridgeL2RelayerProcessPendingBatchTotal prometheus.Counter
bridgeL2RelayerProcessPendingBatchSuccessTotal prometheus.Counter
bridgeL2RelayerGasPriceOraclerRunTotal prometheus.Counter
bridgeL2RelayerLastGasPrice prometheus.Gauge
bridgeL2RelayerProcessCommittedBatchesTotal prometheus.Counter
bridgeL2RelayerProcessCommittedBatchesFinalizedTotal prometheus.Counter
bridgeL2RelayerProcessCommittedBatchesFinalizedSuccessTotal prometheus.Counter
bridgeL2BatchesCommittedConfirmedTotal prometheus.Counter
bridgeL2BatchesFinalizedConfirmedTotal prometheus.Counter
bridgeL2BatchesGasOraclerConfirmedTotal prometheus.Counter
bridgeL2ChainMonitorLatestFailedCall prometheus.Counter
bridgeL2ChainMonitorLatestFailedBatchStatus prometheus.Counter
}
var (
initL2RelayerMetricOnce sync.Once
l2RelayerMetric *l2RelayerMetrics
)
func initL2RelayerMetrics(reg prometheus.Registerer) *l2RelayerMetrics {
initL2RelayerMetricOnce.Do(func() {
l2RelayerMetric = &l2RelayerMetrics{
bridgeL2RelayerProcessPendingBatchTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_pending_batch_total",
Help: "The total number of layer2 process pending batch",
}),
bridgeL2RelayerProcessPendingBatchSuccessTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_pending_batch_success_total",
Help: "The total number of layer2 process pending success batch",
}),
bridgeL2RelayerGasPriceOraclerRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_gas_price_oracler_total",
Help: "The total number of layer2 gas price oracler run total",
}),
bridgeL2RelayerLastGasPrice: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_layer2_gas_price_latest_gas_price",
Help: "The latest gas price of bridge relayer l2",
}),
bridgeL2RelayerProcessCommittedBatchesTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_committed_batches_total",
Help: "The total number of layer2 process committed batches run total",
}),
bridgeL2RelayerProcessCommittedBatchesFinalizedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_committed_batches_finalized_total",
Help: "The total number of layer2 process committed batches finalized total",
}),
bridgeL2RelayerProcessCommittedBatchesFinalizedSuccessTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_committed_batches_finalized_success_total",
Help: "The total number of layer2 process committed batches finalized success total",
}),
bridgeL2BatchesCommittedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_committed_batches_confirmed_total",
Help: "The total number of layer2 process committed batches confirmed total",
}),
bridgeL2BatchesFinalizedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_finalized_batches_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",
}),
bridgeL2BatchesGasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_process_gras_oracler_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",
}),
bridgeL2ChainMonitorLatestFailedCall: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_chain_monitor_latest_failed_batch_call",
Help: "The total number of failed call chain_monitor api",
}),
bridgeL2ChainMonitorLatestFailedBatchStatus: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_layer2_chain_monitor_latest_failed_batch_status",
Help: "The total number of failed batch status get from chain_monitor",
}),
}
})
return l2RelayerMetric
}

View File

@@ -1,83 +0,0 @@
package tests
import (
"context"
"math/big"
"testing"
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
"github.com/scroll-tech/go-ethereum/common"
geth_types "github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/rpc"
"github.com/stretchr/testify/assert"
"scroll-tech/common/database"
"scroll-tech/common/types"
"scroll-tech/bridge/internal/controller/relayer"
"scroll-tech/bridge/internal/controller/watcher"
"scroll-tech/bridge/internal/orm"
)
func testRelayL1MessageSucceed(t *testing.T) {
db := setupDB(t)
defer database.CloseDB(db)
prepareContracts(t)
l1Cfg := bridgeApp.Config.L1Config
l2Cfg := bridgeApp.Config.L2Config
// Create L1Relayer
l1Relayer, err := relayer.NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig, nil)
assert.NoError(t, err)
// Create L1Watcher
confirmations := rpc.LatestBlockNumber
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, 0, confirmations, l1Cfg.L1MessengerAddress,
l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db, nil)
// Create L2Watcher
l2Watcher := watcher.NewL2WatcherClient(context.Background(), l2Client, confirmations, l2Cfg.L2MessengerAddress,
l2Cfg.L2MessageQueueAddress, l2Cfg.WithdrawTrieRootSlot, db, nil)
// send message through l1 messenger contract
nonce, err := l1MessengerInstance.MessageNonce(&bind.CallOpts{})
assert.NoError(t, err)
sendTx, err := l1MessengerInstance.SendMessage(l1Auth, l2Auth.From, big.NewInt(0), common.Hex2Bytes("00112233"), big.NewInt(0))
assert.NoError(t, err)
sendReceipt, err := bind.WaitMined(context.Background(), l1Client, sendTx)
assert.NoError(t, err)
if sendReceipt.Status != geth_types.ReceiptStatusSuccessful || err != nil {
t.Fatalf("Call failed")
}
// l1 watch process events
l1Watcher.FetchContractEvent()
l1MessageOrm := orm.NewL1Message(db)
// check db status
msg, err := l1MessageOrm.GetL1MessageByQueueIndex(nonce.Uint64())
assert.NoError(t, err)
assert.Equal(t, types.MsgStatus(msg.Status), types.MsgPending)
assert.Equal(t, msg.Target, l2Auth.From.String())
// process l1 messages
l1Relayer.ProcessSavedEvents()
l1Message, err := l1MessageOrm.GetL1MessageByQueueIndex(nonce.Uint64())
assert.NoError(t, err)
assert.NotEmpty(t, l1Message.Layer2Hash)
assert.Equal(t, types.MsgStatus(l1Message.Status), types.MsgSubmitted)
relayTx, _, err := l2Client.TransactionByHash(context.Background(), common.HexToHash(l1Message.Layer2Hash))
assert.NoError(t, err)
relayTxReceipt, err := bind.WaitMined(context.Background(), l2Client, relayTx)
assert.NoError(t, err)
assert.Equal(t, len(relayTxReceipt.Logs), 1)
// fetch message relayed events
l2Watcher.FetchContractEvent()
msg, err = l1MessageOrm.GetL1MessageByQueueIndex(nonce.Uint64())
assert.NoError(t, err)
assert.Equal(t, types.MsgStatus(msg.Status), types.MsgConfirmed)
}

View File

@@ -20,7 +20,7 @@ RUN find ./ | grep libzktrie.so | xargs -I{} cp {} /app/target/release/
FROM scrolltech/go-rust-builder:go-1.19-rust-nightly-2022-12-10 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/

View File

@@ -3,7 +3,7 @@ FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/

View File

@@ -3,7 +3,7 @@ FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/
@@ -18,7 +18,7 @@ FROM base as builder
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
cd /src/bridge/cmd/event_watcher/ && go build -v -p 4 -o /bin/event_watcher
cd /src/rollup/cmd/event_watcher/ && go build -v -p 4 -o /bin/event_watcher
# Pull event_watcher into a second stage deploy alpine container
FROM alpine:latest

View File

@@ -3,7 +3,7 @@ FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/
@@ -18,7 +18,7 @@ FROM base as builder
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
cd /src/bridge/cmd/gas_oracle/ && go build -v -p 4 -o /bin/gas_oracle
cd /src/rollup/cmd/gas_oracle/ && go build -v -p 4 -o /bin/gas_oracle
# Pull gas_oracle into a second stage deploy alpine container
FROM alpine:latest

View File

@@ -1,28 +0,0 @@
# Download Go dependencies
FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/
COPY ./prover-stats-api/go.* ./prover-stats-api/
COPY ./prover/go.* ./prover/
COPY ./tests/integration-test/go.* ./tests/integration-test/
COPY ./bridge-history-api/go.* ./bridge-history-api/
RUN go mod download -x
# Build msg_relayer
FROM base as builder
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
cd /src/bridge/cmd/msg_relayer/ && go build -v -p 4 -o /bin/msg_relayer
# Pull msg_relayer into a second stage deploy alpine container
FROM alpine:latest
COPY --from=builder /bin/msg_relayer /bin/
ENTRYPOINT ["msg_relayer"]

View File

@@ -1,5 +0,0 @@
assets/
docs/
l2geth/
rpc-gateway/
*target/*

View File

@@ -3,7 +3,7 @@ FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/

View File

@@ -3,7 +3,7 @@ FROM scrolltech/go-alpine-builder:1.19 as base
WORKDIR /src
COPY go.work* ./
COPY ./bridge/go.* ./bridge/
COPY ./rollup/go.* ./rollup/
COPY ./common/go.* ./common/
COPY ./coordinator/go.* ./coordinator/
COPY ./database/go.* ./database/
@@ -18,7 +18,7 @@ FROM base as builder
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
cd /src/bridge/cmd/rollup_relayer/ && go build -v -p 4 -o /bin/rollup_relayer
cd /src/rollup/cmd/rollup_relayer/ && go build -v -p 4 -o /bin/rollup_relayer
# Pull rollup_relayer into a second stage deploy alpine container
FROM alpine:latest

View File

@@ -3,7 +3,7 @@ set -uex
profile_name=$1
exclude_dirs=("scroll-tech/bridge/cmd" "scroll-tech/bridge/tests" "scroll-tech/bridge/mock_bridge" "scroll-tech/coordinator/cmd" "scroll-tech/coordinator/internal/logic/verifier")
exclude_dirs=("scroll-tech/rollup/cmd" "scroll-tech/rollup/tests" "scroll-tech/rollup/mock_bridge" "scroll-tech/coordinator/cmd" "scroll-tech/coordinator/internal/logic/verifier")
all_packages=$(go list ./... | grep -v "^scroll-tech/${profile_name}$")
coverpkg="scroll-tech/${profile_name}"

View File

@@ -6,7 +6,7 @@ flag_management:
default_rules:
carryforward: true
individual_flags:
- name: bridge
- name: rollup
statuses:
- type: project
target: auto

View File

@@ -1,4 +1,4 @@
FROM scrolltech/l2geth:scroll-v4.3.34
FROM scrolltech/l2geth:scroll-v4.3.55
RUN mkdir -p /l2geth/keystore

View File

@@ -14,7 +14,7 @@ require (
github.com/modern-go/reflect2 v1.0.2
github.com/orcaman/concurrent-map v1.0.0
github.com/prometheus/client_golang v1.14.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.7
gorm.io/driver/postgres v1.5.0

View File

@@ -434,8 +434,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/zktrie v0.6.0 h1:xLrMAO31Yo2BiPg1jtYKzcjpEFnXy8acbB7iIsyshPs=
github.com/scroll-tech/zktrie v0.6.0/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=

View File

@@ -0,0 +1,55 @@
package version
import (
"strconv"
"strings"
)
// CheckScrollProverVersion check the "scroll-prover" version, if it's different from the local one, return false
func CheckScrollProverVersion(proverVersion string) bool {
// note the the version is in fact in the format of "tag-commit-scroll_prover-halo2",
// so split-by-'-' length should be 4
remote := strings.Split(proverVersion, "-")
if len(remote) != 4 {
return false
}
local := strings.Split(Version, "-")
if len(local) != 4 {
return false
}
// compare the `scroll_prover` version
return remote[2] == local[2]
}
// CheckScrollProverVersionTag check the "scroll-prover" version's tag, if it's too old, return false
func CheckScrollProverVersionTag(proverVersion string) bool {
// note the the version is in fact in the format of "tag-commit-scroll_prover-halo2",
// so split-by-'-' length should be 4
remote := strings.Split(proverVersion, "-")
if len(remote) != 4 {
return false
}
remoteTagNums := strings.Split(strings.TrimPrefix(remote[0], "v"), ".")
if len(remoteTagNums) != 3 {
return false
}
remoteTagMajor, err := strconv.Atoi(remoteTagNums[0])
if err != nil {
return false
}
remoteTagMinor, err := strconv.Atoi(remoteTagNums[1])
if err != nil {
return false
}
remoteTagPatch, err := strconv.Atoi(remoteTagNums[2])
if err != nil {
return false
}
if remoteTagMajor < 4 {
return false
}
if remoteTagMinor == 1 && remoteTagPatch < 98 {
return false
}
return true
}

View File

@@ -3,11 +3,9 @@ package version
import (
"fmt"
"runtime/debug"
"strconv"
"strings"
)
var tag = "v4.2.12"
var tag = "v4.2.17"
var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
@@ -31,52 +29,3 @@ var ZkVersion = "000000-000000"
// Version denote the version of scroll protocol, including the l2geth, relayer, coordinator, prover, contracts and etc.
var Version = fmt.Sprintf("%s-%s-%s", tag, commit, ZkVersion)
// CheckScrollProverVersion check the "scroll-prover" version, if it's different from the local one, return false
func CheckScrollProverVersion(proverVersion string) bool {
// note the the version is in fact in the format of "tag-commit-scroll_prover-halo2",
// so split-by-'-' length should be 4
remote := strings.Split(proverVersion, "-")
if len(remote) != 4 {
return false
}
local := strings.Split(Version, "-")
if len(local) != 4 {
return false
}
// compare the `scroll_prover` version
return remote[2] == local[2]
}
// CheckScrollProverVersionTag check the "scroll-prover" version's tag, if it's too old, return false
func CheckScrollProverVersionTag(proverVersion string) bool {
// note the the version is in fact in the format of "tag-commit-scroll_prover-halo2",
// so split-by-'-' length should be 4
remote := strings.Split(proverVersion, "-")
if len(remote) != 4 {
return false
}
remoteTagNums := strings.Split(strings.TrimPrefix(remote[0], "v"), ".")
if len(remoteTagNums) != 3 {
return false
}
remoteTagMajor, err := strconv.Atoi(remoteTagNums[0])
if err != nil {
return false
}
remoteTagMinor, err := strconv.Atoi(remoteTagNums[1])
if err != nil {
return false
}
remoteTagPatch, err := strconv.Atoi(remoteTagNums[2])
if err != nil {
return false
}
if remoteTagMajor < 4 {
return false
}
if remoteTagMinor == 1 && remoteTagPatch < 98 {
return false
}
return true
}

View File

@@ -1,78 +1,78 @@
# Scroll Contracts
Note: For more comprehensive documentation, see [`./docs/`](./docs).
This directory contains the solidity code for Scroll L1 bridge and rollup contracts and L2 bridge and pre-deployed contracts. The [`specs`](../specs/) folder describes the overall Scroll protocol including the cross-domain messaging and rollup process. You can also find contract APIs and more details in the [`docs`](./docs) folder.
## Directory Structure
```
integration-test
|- xxx.test.ts - "Hardhat integration tests"
lib
|- forge-std - "foundry dependency"
scripts
|- deploy_xxx.ts - "hardhat deploy script"
|- foundry - "foundry deploy scripts"
src
|- test
| `- xxx.t.sol - "Unit testi in solidity"
`- xxx.sol - "solidity contract"
.gitmodules - "foundry dependecy modules"
foundry.toml - "configure foundry"
hardhat.config.ts - "configure hardhat"
remappings.txt - "foundry dependency mappings"
<pre>
├── <a href="./docs/">docs</a>: Documentation for the contracts
├── <a href="./integration-test/">integration-test</a>: Hardhat integration tests
├── <a href="./lib/">lib</a>: External libraries and testing tools
├── <a href="./scripts">scripts</a>: Deployment scripts
├── <a href="./src">src</a>
│ ├── <a href="./src/gas-swap/">gas-swap</a>: Utility contract that allows gas payment in other tokens
│ ├── <a href="./src/interfaces/">interfaces</a>: Common contract interfaces
│ ├── <a href="./src/L1/">L1</a>: Contracts deployed on the L1 (Ethereum)
│ │ ├── <a href="./src/L1/gateways/">gateways</a>: Gateway router and token gateway contracts
│ │ ├── <a href="./src/L1/rollup/">rollup</a>: Rollup contracts for data availability and finalization
│ │ ├── <a href="./src/L1/IL1ScrollMessenger.sol">IL1ScrollMessenger.sol</a>: L1 Scroll messenger interface
│ │ └── <a href="./src/L1/L1ScrollMessenger.sol">L1ScrollMessenger.sol</a>: L1 Scroll messenger contract
│ ├── <a href="./src/L2/">L2</a>: Contracts deployed on the L2 (Scroll)
│ │ ├── <a href="./src/L2/gateways/">gateways</a>: Gateway router and token gateway contracts
│ │ ├── <a href="./src/L2/predeploys/">predeploys</a>: Pre-deployed contracts on L2
│ │ ├── <a href="./src/L2/IL2ScrollMessenger.sol">IL2ScrollMessenger.sol</a>: L2 Scroll messenger interface
│ │ └── <a href="./src/L2/L2ScrollMessenger.sol">L2ScrollMessenger.sol</a>: L2 Scroll messenger contract
│ ├── <a href="./src/libraries/">libraries</a>: Shared contract libraries
│ ├── <a href="./src/misc/">misc</a>: Miscellaneous contracts
│ ├── <a href="./src/mocks/">mocks</a>: Mock contracts used in the testing
│ ├── <a href="./src/rate-limiter/">rate-limiter</a>: Rater limiter contract
│ └── <a href="./src/test/">test</a>: Unit tests in solidity
├── <a href="./foundry.toml">foundry.toml</a>: Foundry configuration
├── <a href="./hardhat.config.ts">hardhat.config.ts</a>: Hardhat configuration
├── <a href="./remappings.txt">remappings.txt</a>: Foundry dependency mappings
...
```
</pre>
## Dependencies
### Node.js
First install [`Node.js`](https://nodejs.org/en) and [`npm`](https://www.npmjs.com/).
Run the following command to install [`yarn`](https://classic.yarnpkg.com/en/):
```bash
npm install --global yarn
```
### Foundry
First run the command below to get foundryup, the Foundry toolchain installer:
Install `foundryup`, the Foundry toolchain installer:
```bash
curl -L https://foundry.paradigm.xyz | bash
```
If you do not want to use the redirect, feel free to manually download the foundryup installation script from [here](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup).
If you do not want to use the redirect, feel free to manually download the `foundryup` installation script from [here](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup).
Then, run `foundryup` in a new terminal session or after reloading your `PATH`.
Then, run `foundryup` in a new terminal session or after reloading `PATH`.
Other ways to install Foundry can be found [here](https://github.com/foundry-rs/foundry#installation).
### Hardhat
Run the following command to install [Hardhat](https://hardhat.org/) and other dependencies.
```
yarn install
```
## Build
- Run `git submodule update --init --recursive` to initialise git submodules.
- Run `git submodule update --init --recursive` to initialize git submodules.
- Run `yarn prettier:solidity` to run linting in fix mode, will auto-format all solidity codes.
- Run `yarn prettier` to run linting in fix mode, will auto-format all typescript codes.
- Run `yarn prepare` to install the precommit linting hook
- Run `yarn prepare` to install the precommit linting hook.
- Run `forge build` to compile contracts with foundry.
- Run `npx hardhat compile` to compile with hardhat.
- Run `forge test -vvv` to run foundry units tests. It will compile all contracts before running the unit tests.
- Run `npx hardhat test` to run integration tests. It may not compile all contracts before running, it's better to run `npx hardhat compile` first.
## TODO
- [ ] unit tests
- [ ] L1 Messenger
- [x] L1 Gateways
- [x] L1 Gateway Router
- [ ] L2 Messenger
- [x] L2 Gateways
- [x] L2 Gateway Router
- [x] ScrollStandardERC20Factory
- [x] Whitelist
- [ ] SimpleGasOracle
- [ ] integration tests
- [x] ERC20Gateway
- [x] GatewayRouter
- [ ] ZKRollup contracts
- [x] Gas Oracle contracts for cross chain message call
- [ ] ERC721/ERC115 interface design
- [ ] add proof verification codes
- [ ] security analysis

View File

@@ -1,33 +0,0 @@
# Cross Domain Messaging
Like other layer 2 protocol, Scroll allow dapps to communicate between layer 1 and layer 2. More specifically, dapps on layer 1 can trigger contract functions in layer 2, and vice versa.
## Message Between L1 and L2
The Scroll protocol implements two core contracts `L1ScrollMessenger` and `L2ScrollMessenger` to enable cross domain messaging. The only entry to send cross domain message is to call the following function:
```solidity
function sendMessage(
address _to,
bytes memory _message,
uint256 _gasLimit
) external payable
```
The function is attached in both messenger in layer 1 and layer 2. After that, the Sequencer will handle the rest part for you. We will explain the detailed workflow in the following docs.
### Send Message from L1 to L2
As described above, the first step is to call `L1ScrollMessenger.sendMessage` in layer 1. The `L1ScrollMessenger` contract will emit a `SentMessage` event, which will be notified by the Sequencer. The Sequencer will for the confirmation of the function call in layer 1. Normally, the Sequencer will wait for 10-20 blocks. After that, the Sequencer will initiate a transaction in layer 2, calling function `L2ScrollMessenger.relayMessage` and finally, the message is executed in layer 2.
The execution in layer 2 may be failed due to out of gas problem. In such case, one can call `L1ScrollMessenger.replayMessage` to replace the message with a larger gas limit. And the Sequencer will follow the steps and execute the message again in layer 2.
### Send Message from L2 to L1
Similar to sending message from L1 to L2, you should call `L2ScrollMessenger.sendMessage` first in layer 2. The `L2ScrollMessenger` contract will emit a `SentMessage` event, which will be notified by the Sequencer. Unlike above, the Sequencer will first batch submit layer 2 transactions (or block) to `ZKRollup` contract in layer 1. Then the Sequencer will wait the proof generated by prover and submit the proof to `ZKRollup` contract in layer 1 again. Finally, anyone can call `L1ScrollMessenger.relayMessageWithProof` with correct proof to execute the message in layer 1.
Currently, for the safety reason, we only allow privileged contracts to send cross domain messages. And only privileged accounts can call `L2ScrollMessenger.relayMessage`.
## Fee For Sending Message
to be discussed.

View File

@@ -1,22 +0,0 @@
# Overview
![](./assets/overview.png)
The above picture is the overview of the contract design. There are several components both in layer 1 and layer 2: L1/L2 Scroll Messenger, various L1/L2 Gateways and L1/L2 Gateway Router. Besides these, there is a Rollup component only in layer 1.
The followings are the detailed docs for each component (docs are generated automatically by `@primitivefi/hardhat-dodoc` plugin):
- [L1 Scroll Messenger](./apis/L1ScrollMessenger.md) and [L2 Scroll Messenger](./apis/L2ScrollMessenger.md): Main entry for sending and relaying cross domain message.
- [Rollup](./apis/ZKRollup.md)
- [L1 Gateway Router](./apis/L1GatewayRouter.md) and [L2 Gateway Router](./apis/L2GatewayRouter.md): Router contract for depositing/withdrawing Ethers and ERC20 tokens.
- L1/L2 Gateways:
- [L1 Standard ERC20 Gateway](./apis/L1StandardERC20Gateway.md) and [L2 Standard ERC20 Gateway](./apis/L2StandardERC20Gateway.md)
- [L1 WETH Gateway](./apis/L1WETHGateway.md) and [L2 WETH Gateway](./apis/L2WETHGateway.md)
- [L1 ERC721 Gateway](./apis/L1ERC721Gateway.md) and [L2 ERC721 Gateway](./apis/L2ERC721Gateway.md)
- [L1 ERC1155 Gateway](./apis/L1ERC1155Gateway.md) and [L2 ERC1155 Gateway](./apis/L2ERC1155Gateway.md)
- [ScrollStandardERC20Factory](./apis/ScrollStandardERC20Factory.md): The `ScrollStandardERC20` token factory used by `L2StandardERC20Gateway`.
There are two main applications: Token Bridge and Cross Domain Messaging. You can find the documentations in the links below:
- [Token Bridge](./TokenBridge.md): moving token from layer 1 to layer 2, or from layer 2 to layer 1.
- [Cross Domain Messaging](./CrossDomainMessaging.md): sending data to layer 2 from layer 1, or sending data to layer 2 from layer 1. Basically, it will help to trigger function call cross layer. The token bridge also use cross domain messaging to achieve its functionality.

View File

@@ -1,134 +0,0 @@
# Bridge Token Between Layer 1 and Layer 2
The Token Bridge of Scroll Protocol offers a way to move assets from layer 1 to layer 2 and back, including Ether, ERC20 token, ERC-721 token, ERC-1155 token, etc. The asset should be deposited and locked in layer 1 and then in exchange of the same amount of an equivalent token on layer 2. For example, if you deposit 1000 Ether in layer 1, you will get 1000 Ether in layer 2 for return. And if you withdraw 1000 Ether in layer 2, you will get 1000 Ether in layer 1 for return.
The Ether and ERC20 tokens can be deposited or withdrawn using one single contract `GatewayRouter` (`L1GatewayRouter` in layer 1 and `L2GatewayRouter` in layer 2). The ERC-721 tokens and ERC-1155 tokens can be deposited or withdrawn using the corresponding `ERC1155Gateway` and `ERC721Gateway` in layer 1 or layer 2 (They may be integrated into `GatewayRouter` in the future).
## Bridge Ether
To bridge Ether from layer 1 to layer 2, one can use `L1GatewayRouter.depositETH`. This will transfer ethers to the `L1ScrollMessenger` contract on the layer 1 and credits the same amount of ether to you in layer 2 at the specified address.
```solidity
function depositETH(uint256 _gasLimit) external payable;
function depositETH(address _to, uint256 _gasLimit) external payable;
```
In the layer 1, all deposited Ether will be locked in `L1ScrollMessenger` contract. It means your deposited Ether will firstly be transfered to `L1GatewayRouter` contract and then to `L1ScrollMessenger` contract.
To withdraw Ether from layer 2 to layer 1, one can use `L2GatewayRouter.withdrawETH`.
```solidity
function withdrawETH(uint256 _gasLimit) external payable;
function withdrawETH(address _to, uint256 _gasLimit) external payable;
```
In layer 2, the `L2ScrollMessenger` holds infinite amount of Ether at the beginning. All your withdrawn Ether will be transfered back to `L2ScrollMessenger`, just like the process in layer 1.
In addition, you can actually call `sendMessage` from the `L1ScrollMessenger` or `L2ScrollMessenger` contract to deposit or withdraw Ether. The `L1GatewayRouter.depositETH` and `L2GatewayRouter.withdrawETH` are just alias for `L1ScrollMessenger/L2ScrollMessenger.sendMessage`.
## Bridge ERC20 Tokens
We use the similar design as [Arbitrum protocol](https://developer.offchainlabs.com/docs/bridging_assets#bridging-erc20-tokens) do. Several gateway contracts are used to bridge different kinds of ERC20 tokens, such as Wrapped Ether, standard ERC20 tokens, etc.
We implement a `StandardERC20Gateway` to deposit and withdraw standard ERC20 tokens. The standard procedure to deposit ERC20 tokens is to call `L1GatewayRouter.depositERC20` in layer 1. The token will be locked in `L1StandardERC20Gateway` contract in layer 1. The the standard procedure to withdraw ERC20 tokens is to call `L2GatewayRouter.withdrawRC20` in layer 2 and the token will be burned in layer 2.
For many other non-standard ERC20 tokens, we provide a custom ERC20 gateway. Anyone can implement such gateway as long as it implements all required interfaces. We implement the Wrapped Ether gateway as an example. To deposit or withdraw Wrapped Ether, one should first unwrap it to Ether, then transfer the Ether to `ScrollMessenger` just like Ether bridging.
### Passing data when depositing ERC20 tokens
The Scroll protocol offer a way to call another contract after depositing the token in layer 2 by calling `L1GatewayRouter.depositERC20AndCall` in layer 1. The ERC20 token in layer 2 implements the [ERC 677 Standard](https://github.com/ethereum/EIPs/issues/677). By using `transferAndCall` function, we can transfer the token to corresponding recipient in layer 2 and then call the recipient with passed data.
```solidity
function depositERC20AndCall(
address _token,
address _to,
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) external;
```
Like Bridging Ether, all above functionality can be achieved by calling corresponding function in ERC20Gateway contract.
## Bridge ERC-721/ERC-1155 Tokens
The depositing/withdrawing ERC-721 or ERC-1155 tokens works very similar to ERC20 tokens. One can use the following function to deposit ERC-721/ERC-1155 tokens in layer 1.
```solidity
function depositERC1155(
address _token,
uint256 _tokenId,
uint256 _amount,
uint256 _gasLimit
) external;
function depositERC1155(
address _token,
address _to,
uint256 _tokenId,
uint256 _amount,
uint256 _gasLimit
) external;
function depositERC721(
address _token,
uint256 _tokenId,
uint256 _gasLimit
) external;
function depositERC721(
address _token,
address _to,
uint256 _tokenId,
uint256 _gasLimit
) external;
```
One can use the following function to withdraw ERC-721/ERC-1155 tokens in layer 2.
```solidity
function withdrawERC1155(
address _token,
uint256 _tokenId,
uint256 _amount,
uint256 _gasLimit
) external;
function withdrawERC1155(
address _token,
address _to,
uint256 _tokenId,
uint256 _amount,
uint256 _gasLimit
) external;
function withdrawERC721(
address _token,
uint256 _tokenId,
uint256 _gasLimit
) external;
function withdrawERC721(
address _token,
address _to,
uint256 _tokenId,
uint256 _gasLimit
) external;
```
To save the gas usage, we also provide a batch deposit/withdraw function, such as `batchDepositERC1155` and `batchDepositERC721`, by passing a list of token ids to the function.
## Drop Depositing/Withdrawing
Coming soon...
## Force Exit
Coming soon...

View File

@@ -0,0 +1,571 @@
# ScrollChain
> ScrollChain
This contract maintains data for the Scroll rollup.
## Methods
### commitBatch
```solidity
function commitBatch(uint8 _version, bytes _parentBatchHeader, bytes[] _chunks, bytes _skippedL1MessageBitmap) external nonpayable
```
Commit a batch of transactions on layer 1.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _version | uint8 | undefined |
| _parentBatchHeader | bytes | undefined |
| _chunks | bytes[] | undefined |
| _skippedL1MessageBitmap | bytes | undefined |
### committedBatches
```solidity
function committedBatches(uint256) external view returns (bytes32)
```
Return the batch hash of a committed batch.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bytes32 | undefined |
### finalizeBatchWithProof
```solidity
function finalizeBatchWithProof(bytes _batchHeader, bytes32 _prevStateRoot, bytes32 _postStateRoot, bytes32 _withdrawRoot, bytes _aggrProof) external nonpayable
```
Finalize a committed batch on layer 1.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _batchHeader | bytes | undefined |
| _prevStateRoot | bytes32 | undefined |
| _postStateRoot | bytes32 | undefined |
| _withdrawRoot | bytes32 | undefined |
| _aggrProof | bytes | undefined |
### finalizedStateRoots
```solidity
function finalizedStateRoots(uint256) external view returns (bytes32)
```
Return the state root of a committed batch.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bytes32 | undefined |
### importGenesisBatch
```solidity
function importGenesisBatch(bytes _batchHeader, bytes32 _stateRoot) external nonpayable
```
Import layer 2 genesis block
#### Parameters
| Name | Type | Description |
|---|---|---|
| _batchHeader | bytes | undefined |
| _stateRoot | bytes32 | undefined |
### initialize
```solidity
function initialize(address _messageQueue, address _verifier, uint256 _maxNumL2TxInChunk) external nonpayable
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| _messageQueue | address | undefined |
| _verifier | address | undefined |
| _maxNumL2TxInChunk | uint256 | undefined |
### isBatchFinalized
```solidity
function isBatchFinalized(uint256 _batchIndex) external view returns (bool)
```
Return whether the batch is finalized by batch index.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _batchIndex | uint256 | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bool | undefined |
### isProver
```solidity
function isProver(address) external view returns (bool)
```
Whether an account is a prover.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bool | undefined |
### isSequencer
```solidity
function isSequencer(address) external view returns (bool)
```
Whether an account is a sequencer.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bool | undefined |
### lastFinalizedBatchIndex
```solidity
function lastFinalizedBatchIndex() external view returns (uint256)
```
The latest finalized batch index.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined |
### layer2ChainId
```solidity
function layer2ChainId() external view returns (uint64)
```
The chain id of the corresponding layer 2 chain.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint64 | undefined |
### maxNumL2TxInChunk
```solidity
function maxNumL2TxInChunk() external view returns (uint256)
```
The maximum number of transactions allowed in each chunk.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined |
### messageQueue
```solidity
function messageQueue() external view returns (address)
```
The address of L1MessageQueue.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### owner
```solidity
function owner() external view returns (address)
```
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### renounceOwnership
```solidity
function renounceOwnership() external nonpayable
```
*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.*
### revertBatch
```solidity
function revertBatch(bytes _batchHeader, uint256 _count) external nonpayable
```
Revert a pending batch.
*one can only revert unfinalized batches.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _batchHeader | bytes | undefined |
| _count | uint256 | undefined |
### transferOwnership
```solidity
function transferOwnership(address newOwner) external nonpayable
```
*Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| newOwner | address | undefined |
### updateMaxNumL2TxInChunk
```solidity
function updateMaxNumL2TxInChunk(uint256 _maxNumL2TxInChunk) external nonpayable
```
Update the value of `maxNumL2TxInChunk`.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _maxNumL2TxInChunk | uint256 | The new value of `maxNumL2TxInChunk`. |
### updateProver
```solidity
function updateProver(address _account, bool _status) external nonpayable
```
Update the status of prover.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _account | address | The address of account to update. |
| _status | bool | The status of the account to update. |
### updateSequencer
```solidity
function updateSequencer(address _account, bool _status) external nonpayable
```
Update the status of sequencer.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _account | address | The address of account to update. |
| _status | bool | The status of the account to update. |
### updateVerifier
```solidity
function updateVerifier(address _newVerifier) external nonpayable
```
Update the address verifier contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newVerifier | address | The address of new verifier contract. |
### verifier
```solidity
function verifier() external view returns (address)
```
The address of RollupVerifier.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### withdrawRoots
```solidity
function withdrawRoots(uint256) external view returns (bytes32)
```
Return the message root of a committed batch.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _0 | uint256 | undefined |
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | bytes32 | undefined |
## Events
### CommitBatch
```solidity
event CommitBatch(bytes32 indexed batchHash)
```
Emitted when a new batch is committed.
#### Parameters
| Name | Type | Description |
|---|---|---|
| batchHash `indexed` | bytes32 | undefined |
### FinalizeBatch
```solidity
event FinalizeBatch(bytes32 indexed batchHash, bytes32 stateRoot, bytes32 withdrawRoot)
```
Emitted when a batch is finalized.
#### Parameters
| Name | Type | Description |
|---|---|---|
| batchHash `indexed` | bytes32 | undefined |
| stateRoot | bytes32 | undefined |
| withdrawRoot | bytes32 | undefined |
### OwnershipTransferred
```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
```
#### Parameters
| Name | Type | Description |
|---|---|---|
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### RevertBatch
```solidity
event RevertBatch(bytes32 indexed batchHash)
```
revert a pending batch.
#### Parameters
| Name | Type | Description |
|---|---|---|
| batchHash `indexed` | bytes32 | undefined |
### UpdateMaxNumL2TxInChunk
```solidity
event UpdateMaxNumL2TxInChunk(uint256 oldMaxNumL2TxInChunk, uint256 newMaxNumL2TxInChunk)
```
Emitted when the value of `maxNumL2TxInChunk` is updated.
#### Parameters
| Name | Type | Description |
|---|---|---|
| oldMaxNumL2TxInChunk | uint256 | The old value of `maxNumL2TxInChunk`. |
| newMaxNumL2TxInChunk | uint256 | The new value of `maxNumL2TxInChunk`. |
### UpdateProver
```solidity
event UpdateProver(address indexed account, bool status)
```
Emitted when owner updates the status of prover.
#### Parameters
| Name | Type | Description |
|---|---|---|
| account `indexed` | address | The address of account updated. |
| status | bool | The status of the account updated. |
### UpdateSequencer
```solidity
event UpdateSequencer(address indexed account, bool status)
```
Emitted when owner updates the status of sequencer.
#### Parameters
| Name | Type | Description |
|---|---|---|
| account `indexed` | address | The address of account updated. |
| status | bool | The status of the account updated. |
### UpdateVerifier
```solidity
event UpdateVerifier(address oldVerifier, address newVerifier)
```
Emitted when the address of rollup verifier is updated.
#### Parameters
| Name | Type | Description |
|---|---|---|
| oldVerifier | address | The address of old rollup verifier. |
| newVerifier | address | The address of new rollup verifier. |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 KiB

View File

@@ -84,11 +84,14 @@ const config: HardhatUserConfig = {
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
mocha: {
timeout: 10000000,
},
dodoc: {
runOnCompile: true,
keepFileStructure: false,
include: [
"ZKRollup",
"ScrollChain",
"L1ScrollMessenger",
"L2ScrollMessenger",
"L1GatewayRouter",
@@ -115,8 +118,9 @@ const config: HardhatUserConfig = {
"IL1ERC1155Gateway",
"IL2ERC1155Gateway",
"IScrollStandardERC20Factory",
"IZKRollup",
"WrappedEther",
"IScrollChain",
"ScrollChainCommitmentVerifier",
"WETH9",
],
},
};

View File

@@ -1,5 +1,6 @@
/* eslint-disable node/no-unpublished-import */
/* eslint-disable node/no-missing-import */
import { concat } from "ethers/lib/utils";
import { constants } from "ethers";
import { ethers } from "hardhat";
import { ScrollChain, L1MessageQueue } from "../typechain";
@@ -11,22 +12,27 @@ describe("ScrollChain", async () => {
beforeEach(async () => {
const [deployer] = await ethers.getSigners();
const ProxyAdmin = await ethers.getContractFactory("ProxyAdmin", deployer);
const admin = await ProxyAdmin.deploy();
await admin.deployed();
const TransparentUpgradeableProxy = await ethers.getContractFactory("TransparentUpgradeableProxy", deployer);
const L1MessageQueue = await ethers.getContractFactory("L1MessageQueue", deployer);
queue = await L1MessageQueue.deploy();
await queue.deployed();
const queueImpl = await L1MessageQueue.deploy();
await queueImpl.deployed();
const queueProxy = await TransparentUpgradeableProxy.deploy(queueImpl.address, admin.address, "0x");
await queueProxy.deployed();
queue = await ethers.getContractAt("L1MessageQueue", queueProxy.address, deployer);
const RollupVerifier = await ethers.getContractFactory("RollupVerifier", deployer);
const verifier = await RollupVerifier.deploy();
await verifier.deployed();
const ScrollChain = await ethers.getContractFactory("ScrollChain", deployer);
const chainImpl = await ScrollChain.deploy(0);
await chainImpl.deployed();
const chainProxy = await TransparentUpgradeableProxy.deploy(chainImpl.address, admin.address, "0x");
await chainProxy.deployed();
chain = await ethers.getContractAt("ScrollChain", chainProxy.address, deployer);
const ScrollChain = await ethers.getContractFactory("ScrollChain", {
signer: deployer,
libraries: { RollupVerifier: verifier.address },
});
chain = await ScrollChain.deploy(0);
await chain.deployed();
await chain.initialize(queue.address, constants.AddressZero, 44);
await chain.initialize(queue.address, constants.AddressZero, 100);
await chain.addSequencer(deployer.address);
await queue.initialize(
constants.AddressZero,
@@ -38,79 +44,54 @@ describe("ScrollChain", async () => {
});
// @note skip this benchmark tests
/*
it("should succeed", async () => {
await chain.importGenesisBatch({
blocks: [
{
blockHash: "0x92826bd3aad2ef70d8061dc4e25150b305d1233d9cd7579433a77d6eb01dae1c",
parentHash: constants.HashZero,
blockNumber: 0,
timestamp: 1639724192,
baseFee: 1000000000,
gasLimit: 940000000,
numTransactions: 0,
numL1Messages: 0,
},
],
prevStateRoot: constants.HashZero,
newStateRoot: "0x1b186a7a90ec3b41a2417062fe44dce8ce82ae76bfbb09eae786a4f1be1895f5",
withdrawTrieRoot: constants.HashZero,
batchIndex: 0,
parentBatchHash: constants.HashZero,
l2Transactions: [],
});
const parentBatchHash = await chain.lastFinalizedBatchHash();
it.skip("should succeed", async () => {
const batchHeader0 = new Uint8Array(89);
batchHeader0[25] = 1;
await chain.importGenesisBatch(batchHeader0, "0x0000000000000000000000000000000000000000000000000000000000000001");
const parentBatchHash = await chain.committedBatches(0);
console.log("genesis batch hash:", parentBatchHash);
console.log(`ChunkPerBatch`, `BlockPerChunk`, `TxPerBlock`, `BytesPerTx`, `TotalBytes`, `EstimateGas`);
for (let numChunks = 3; numChunks <= 6; ++numChunks) {
for (let numBlocks = 1; numBlocks <= 5; ++numBlocks) {
for (let numTx = 20; numTx <= Math.min(30, 100 / numBlocks); ++numTx) {
for (let txLength = 800; txLength <= 1000; txLength += 100) {
const txs: Array<Uint8Array> = [];
for (let i = 0; i < numTx; i++) {
const tx = new Uint8Array(4 + txLength);
let offset = 3;
for (let x = txLength; x > 0; x = Math.floor(x / 256)) {
tx[offset] = x % 256;
offset -= 1;
}
tx.fill(1, 4);
txs.push(tx);
}
const chunk = new Uint8Array(1 + 60 * numBlocks);
chunk[0] = numBlocks;
for (let i = 0; i < numBlocks; i++) {
chunk[1 + i * 60 + 57] = numTx;
}
const chunks: Array<Uint8Array> = [];
for (let i = 0; i < numChunks; i++) {
const txsInChunk: Array<Uint8Array> = [];
for (let j = 0; j < numBlocks; j++) {
txsInChunk.push(concat(txs));
}
chunks.push(concat([chunk, concat(txsInChunk)]));
}
for (let numTx = 1; numTx <= 25; ++numTx) {
for (let txLength = 100; txLength <= 1000; txLength += 100) {
const txs: Array<Uint8Array> = [];
for (let i = 0; i < numTx; i++) {
const tx = new Uint8Array(4 + txLength);
let offset = 3;
for (let x = txLength; x > 0; x = Math.floor(x / 256)) {
tx[offset] = x % 256;
offset -= 1;
const estimateGas = await chain.estimateGas.commitBatch(0, batchHeader0, chunks, "0x");
console.log(
`${numChunks}`,
`${numBlocks}`,
`${numTx}`,
`${txLength}`,
`${numChunks * numBlocks * numTx * (txLength + 1)}`,
`${estimateGas.toString()}`
);
}
tx.fill(1, 4);
txs.push(tx);
}
const batch = {
blocks: [
{
blockHash: "0xb5baa665b2664c3bfed7eb46e00ebc110ecf2ebd257854a9bf2b9dbc9b2c08f6",
parentHash: "0x92826bd3aad2ef70d8061dc4e25150b305d1233d9cd7579433a77d6eb01dae1c",
blockNumber: 1,
timestamp: numTx * 100000 + txLength,
baseFee: 0,
gasLimit: 0,
numTransactions: 0,
numL1Messages: 0,
},
],
prevStateRoot: "0x1b186a7a90ec3b41a2417062fe44dce8ce82ae76bfbb09eae786a4f1be1895f5",
newStateRoot: "0xb5baa665b2664c3bfed7eb46e00ebc110ecf2ebd257854a9bf2b9dbc9b2c08f6",
withdrawTrieRoot: "0xb5baa665b2664c3bfed7eb46e00ebc110ecf2ebd257854a9bf2b9dbc9b2c08f6",
batchIndex: 1,
parentBatchHash: parentBatchHash,
l2Transactions: concat(txs),
};
const estimateGas = await chain.estimateGas.commitBatch(batch);
const tx = await chain.commitBatch(batch, { gasLimit: estimateGas.mul(12).div(10) });
const receipt = await tx.wait();
console.log(
"Commit batch with l2TransactionsBytes:",
numTx * (txLength + 4),
"gasLimit:",
tx.gasLimit.toString(),
"estimateGas:",
estimateGas.toString(),
"gasUsed:",
receipt.gasUsed.toString()
);
}
}
});
*/
});

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity =0.8.16;
import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
@@ -10,6 +10,22 @@ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet
contract ScrollOwner is AccessControlEnumerable {
using EnumerableSet for EnumerableSet.Bytes32Set;
/**********
* Events *
**********/
/// @notice Emitted when the access to target contract is granted.
/// @param role The role to grant access.
/// @param target The address of target contract.
/// @param selectors The list of function selectors to grant access.
event GrantAccess(bytes32 indexed role, address indexed target, bytes4[] selectors);
/// @notice Emitted when the access to target contract is revoked.
/// @param role The role to revoke access.
/// @param target The address of target contract.
/// @param selectors The list of function selectors to revoke access.
event RevokeAccess(bytes32 indexed role, address indexed target, bytes4[] selectors);
/*************
* Variables *
*************/
@@ -69,7 +85,7 @@ contract ScrollOwner is AccessControlEnumerable {
uint256 _value,
bytes calldata _data,
bytes32 _role
) public payable onlyRole(_role) hasAccess(_target, bytes4(_data[0:4]), _role) {
) external payable onlyRole(_role) hasAccess(_target, bytes4(_data[0:4]), _role) {
_execute(_target, _value, _data);
}
@@ -95,10 +111,14 @@ contract ScrollOwner is AccessControlEnumerable {
for (uint256 i = 0; i < _selectors.length; i++) {
targetAccess[_target][_selectors[i]].add(_role);
}
emit GrantAccess(_role, _target, _selectors);
} else {
for (uint256 i = 0; i < _selectors.length; i++) {
targetAccess[_target][_selectors[i]].remove(_role);
}
emit RevokeAccess(_role, _target, _selectors);
}
}
@@ -114,9 +134,9 @@ contract ScrollOwner is AccessControlEnumerable {
address _target,
uint256 _value,
bytes calldata _data
) internal {
) private {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = address(_target).call{value: _value}(_data);
(bool success, ) = _target.call{value: _value}(_data);
if (!success) {
// solhint-disable-next-line no-inline-assembly
assembly {

View File

@@ -15,7 +15,7 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
* Structs *
***********/
struct TokenAmount {
struct ETHAmount {
// The timestamp when the amount is updated.
uint48 lastUpdateTs;
// The ETH limit in wei.
@@ -39,8 +39,8 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
* Variables *
*************/
/// @notice The token amount used in current period.
TokenAmount public currentPeriod;
/// @notice The ETH amount used in current period.
ETHAmount public currentPeriod;
/***************
* Constructor *
@@ -55,14 +55,10 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
revert PeriodIsZero();
}
if (_totalLimit == 0) {
revert TotalLimitIsZero();
}
periodDuration = _periodDuration;
spender = _spender;
currentPeriod.limit = _totalLimit;
_updateTotalLimit(_totalLimit);
}
/*****************************
@@ -80,9 +76,9 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
// check total limit
uint256 _currentTotalAmount;
TokenAmount memory _currentPeriod = currentPeriod;
ETHAmount memory _currentPeriod = currentPeriod;
if (_currentPeriod.lastUpdateTs < _currentPeriodStart) {
if (uint256(_currentPeriod.lastUpdateTs) < _currentPeriodStart) {
_currentTotalAmount = _amount;
} else {
_currentTotalAmount = _currentPeriod.amount + _amount;
@@ -101,9 +97,19 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
* Restricted Functions *
************************/
/// @notice Update the total token amount limit.
/// @notice Update the total ETH amount limit.
/// @param _newTotalLimit The new total limit.
function updateTotalLimit(uint104 _newTotalLimit) external onlyOwner {
_updateTotalLimit(_newTotalLimit);
}
/**********************
* Internal Functions *
**********************/
/// @dev Internal function to update the total token amount limit.
/// @param _newTotalLimit The new total limit.
function _updateTotalLimit(uint104 _newTotalLimit) private {
if (_newTotalLimit == 0) {
revert TotalLimitIsZero();
}

View File

@@ -54,7 +54,7 @@ contract TokenRateLimiter is AccessControlEnumerable, ITokenRateLimiter {
revert PeriodIsZero();
}
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
periodDuration = _periodDuration;
}
@@ -72,7 +72,7 @@ contract TokenRateLimiter is AccessControlEnumerable, ITokenRateLimiter {
// check total limit, `0` means no limit at all.
uint256 _currentTotalAmount;
TokenAmount memory _currentPeriod = currentPeriod[_token];
if (_currentPeriod.lastUpdateTs < _currentPeriodStart) {
if (uint256(_currentPeriod.lastUpdateTs) < _currentPeriodStart) {
_currentTotalAmount = _amount;
} else {
_currentTotalAmount = _currentPeriod.amount + _amount;

View File

@@ -7,6 +7,8 @@ import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol";
import {ScrollOwner} from "../misc/ScrollOwner.sol";
contract ScrollOwnerTest is DSTestPlus {
event GrantAccess(bytes32 indexed role, address indexed target, bytes4[] selectors);
event RevokeAccess(bytes32 indexed role, address indexed target, bytes4[] selectors);
event Call();
ScrollOwner private owner;
@@ -32,10 +34,18 @@ contract ScrollOwnerTest is DSTestPlus {
assertEq(0, _roles.length);
_selectors = new bytes4[](1);
_selectors[0] = ScrollOwnerTest.revertOnCall.selector;
hevm.expectEmit(true, true, false, true);
emit GrantAccess(bytes32(uint256(1)), address(this), _selectors);
owner.updateAccess(address(this), _selectors, bytes32(uint256(1)), true);
_roles = owner.callableRoles(address(this), ScrollOwnerTest.revertOnCall.selector);
assertEq(1, _roles.length);
assertEq(_roles[0], bytes32(uint256(1)));
hevm.expectEmit(true, true, false, true);
emit RevokeAccess(bytes32(uint256(1)), address(this), _selectors);
owner.updateAccess(address(this), _selectors, bytes32(uint256(1)), false);
_roles = owner.callableRoles(address(this), ScrollOwnerTest.revertOnCall.selector);
assertEq(0, _roles.length);

View File

@@ -7,7 +7,7 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/go-resty/resty/v2 v2.7.0
github.com/mitchellh/mapstructure v1.5.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/shopspring/decimal v1.3.1
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.7

View File

@@ -150,8 +150,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/zktrie v0.6.0 h1:xLrMAO31Yo2BiPg1jtYKzcjpEFnXy8acbB7iIsyshPs=
github.com/scroll-tech/zktrie v0.6.0/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=

View File

@@ -6,7 +6,7 @@ require (
github.com/jmoiron/sqlx v1.3.5
github.com/lib/pq v1.10.9
github.com/pressly/goose/v3 v3.7.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.7
)

View File

@@ -38,8 +38,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=

View File

@@ -1,7 +1,7 @@
go 1.19
use (
./bridge
./rollup
./bridge-history-api
./common
./coordinator

View File

@@ -47,7 +47,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/shopspring/decimal v1.3.1
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0

View File

@@ -118,8 +118,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View File

@@ -5,7 +5,7 @@ go 1.19
require (
github.com/go-resty/resty/v2 v2.7.0
github.com/google/uuid v1.3.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.7
go.etcd.io/bbolt v1.3.7

View File

@@ -89,8 +89,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/zktrie v0.6.0 h1:xLrMAO31Yo2BiPg1jtYKzcjpEFnXy8acbB7iIsyshPs=
github.com/scroll-tech/zktrie v0.6.0/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=

View File

@@ -70,6 +70,8 @@ func NewProver(ctx context.Context, cfg *config.Config) (*Prover, error) {
if err != nil {
return nil, err
}
// Use gzip compression.
l2GethClient.SetHeader("Accept-Encoding", "gzip")
}
// Create prover_core instance

View File

@@ -1,17 +1,15 @@
.PHONY: lint docker clean bridge
.PHONY: mock_abi rollup_bins event_watcher gas_oracle rollup_relayer test lint clean docker
IMAGE_NAME=bridge
IMAGE_VERSION=latest
REPO_ROOT_DIR=./..
mock_abi:
cd .. && go run github.com/scroll-tech/go-ethereum/cmd/abigen --sol ./bridge/mock_bridge/MockBridgeL1.sol --pkg mock_bridge --out ./bridge/mock_bridge/MockBridgeL1.go
cd .. && go run github.com/scroll-tech/go-ethereum/cmd/abigen --sol ./bridge/mock_bridge/MockBridgeL2.sol --pkg mock_bridge --out ./bridge/mock_bridge/MockBridgeL2.go
cd .. && go run github.com/scroll-tech/go-ethereum/cmd/abigen --sol ./rollup/mock_bridge/MockBridgeL1.sol --pkg mock_bridge --out ./rollup/mock_bridge/MockBridgeL1.go
cd .. && go run github.com/scroll-tech/go-ethereum/cmd/abigen --sol ./rollup/mock_bridge/MockBridgeL2.sol --pkg mock_bridge --out ./rollup/mock_bridge/MockBridgeL2.go
bridge_bins: ## Builds the Bridge bins.
rollup_bins: ## Builds the Rollup bins.
go build -o $(PWD)/build/bin/event_watcher ./cmd/event_watcher/
go build -o $(PWD)/build/bin/gas_oracle ./cmd/gas_oracle/
go build -o $(PWD)/build/bin/message_relayer ./cmd/msg_relayer/
go build -o $(PWD)/build/bin/rollup_relayer ./cmd/rollup_relayer/
event_watcher: ## Builds the event_watcher bin
@@ -20,9 +18,6 @@ event_watcher: ## Builds the event_watcher bin
gas_oracle: ## Builds the gas_oracle bin
go build -o $(PWD)/build/bin/gas_oracle ./cmd/gas_oracle/
message_relayer: ## Builds the message_relayer bin
go build -o $(PWD)/build/bin/message_relayer ./cmd/msg_relayer/
rollup_relayer: ## Builds the rollup_relayer bin
go build -o $(PWD)/build/bin/rollup_relayer ./cmd/rollup_relayer/
@@ -39,10 +34,8 @@ docker_push:
docker docker push scrolltech/gas-oracle:${IMAGE_VERSION}
docker docker push scrolltech/event-watcher:${IMAGE_VERSION}
docker docker push scrolltech/rollup-relayer:${IMAGE_VERSION}
docker docker push scrolltech/msg-relayer:${IMAGE_VERSION}
docker:
DOCKER_BUILDKIT=1 docker build -t scrolltech/gas-oracle:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/gas_oracle.Dockerfile
DOCKER_BUILDKIT=1 docker build -t scrolltech/event-watcher:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/event_watcher.Dockerfile
DOCKER_BUILDKIT=1 docker build -t scrolltech/rollup-relayer:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/rollup_relayer.Dockerfile
DOCKER_BUILDKIT=1 docker build -t scrolltech/msg-relayer:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/msg_relayer.Dockerfile

39
rollup/README.md Normal file
View File

@@ -0,0 +1,39 @@
# Rollup
This repo contains the Scroll rollup.
## Dependency
+ install `abigen`
``` bash
go install -v github.com/scroll-tech/go-ethereum/cmd/abigen
```
## Build
```bash
make clean
make mock_abi
make rollup_bins
```
## Start
(Note: make sure you use different private keys for different senders in config.json.)
* use default ports and config.json.
```bash
./build/bin/event_watcher --http
./build/bin/gas_oracle --http
./build/bin/rollup_relayer --http
```
* use specified ports and config.json
```bash
./build/bin/event_watcher --config ./config.json --http --http.addr localhost --http.port 8290
./build/bin/gas_oracle --config ./config.json --http --http.addr localhost --http.port 8290
./build/bin/rollup_relayer --config ./config.json --http --http.addr localhost --http.port 8290
```

View File

@@ -11,8 +11,6 @@ import (
var (
// ScrollChainABI holds information about ScrollChain's context and available invokable methods.
ScrollChainABI *abi.ABI
// L1ScrollMessengerABI holds information about L1ScrollMessenger's context and available invokable methods.
L1ScrollMessengerABI *abi.ABI
// L1MessageQueueABI holds information about L1MessageQueue contract's context and available invokable methods.
L1MessageQueueABI *abi.ABI
// L2GasPriceOracleABI holds information about L2GasPriceOracle's context and available invokable methods.
@@ -20,25 +18,15 @@ var (
// L2ScrollMessengerABI holds information about L2ScrollMessenger's context and available invokable methods.
L2ScrollMessengerABI *abi.ABI
// L1BlockContainerABI holds information about L1BlockContainer contract's context and available invokable methods.
L1BlockContainerABI *abi.ABI
// L1GasPriceOracleABI holds information about L1GasPriceOracle's context and available invokable methods.
L1GasPriceOracleABI *abi.ABI
// L2MessageQueueABI holds information about L2MessageQueue contract's context and available invokable methods.
L2MessageQueueABI *abi.ABI
// L1SentMessageEventSignature = keccak256("SentMessage(address,address,uint256,uint256,uint256,bytes)")
L1SentMessageEventSignature common.Hash
// L1RelayedMessageEventSignature = keccak256("RelayedMessage(bytes32)")
L1RelayedMessageEventSignature common.Hash
// L1FailedRelayedMessageEventSignature = keccak256("FailedRelayedMessage(bytes32)")
L1FailedRelayedMessageEventSignature common.Hash
// L1CommitBatchEventSignature = keccak256("CommitBatch(uint256,bytes32)")
L1CommitBatchEventSignature common.Hash
// L1FinalizeBatchEventSignature = keccak256("FinalizeBatch(uint256,bytes32,bytes32,bytes32)")
L1FinalizeBatchEventSignature common.Hash
// L1QueueTransactionEventSignature = keccak256("QueueTransaction(address,address,uint256,uint64,uint256,bytes)")
L1QueueTransactionEventSignature common.Hash
@@ -49,28 +37,19 @@ var (
// L2FailedRelayedMessageEventSignature = keccak256("FailedRelayedMessage(bytes32)")
L2FailedRelayedMessageEventSignature common.Hash
// L2ImportBlockEventSignature = keccak256("ImportBlock(bytes32,uint256,uint256,uint256,bytes32)")
L2ImportBlockEventSignature common.Hash
// L2AppendMessageEventSignature = keccak256("AppendMessage(uint256,bytes32)")
L2AppendMessageEventSignature common.Hash
)
func init() {
ScrollChainABI, _ = ScrollChainMetaData.GetAbi()
L1ScrollMessengerABI, _ = L1ScrollMessengerMetaData.GetAbi()
L1MessageQueueABI, _ = L1MessageQueueMetaData.GetAbi()
L2GasPriceOracleABI, _ = L2GasPriceOracleMetaData.GetAbi()
L2ScrollMessengerABI, _ = L2ScrollMessengerMetaData.GetAbi()
L1BlockContainerABI, _ = L1BlockContainerMetaData.GetAbi()
L2MessageQueueABI, _ = L2MessageQueueMetaData.GetAbi()
L1GasPriceOracleABI, _ = L1GasPriceOracleMetaData.GetAbi()
L1SentMessageEventSignature = L1ScrollMessengerABI.Events["SentMessage"].ID
L1RelayedMessageEventSignature = L1ScrollMessengerABI.Events["RelayedMessage"].ID
L1FailedRelayedMessageEventSignature = L1ScrollMessengerABI.Events["FailedRelayedMessage"].ID
L1CommitBatchEventSignature = ScrollChainABI.Events["CommitBatch"].ID
L1FinalizeBatchEventSignature = ScrollChainABI.Events["FinalizeBatch"].ID
@@ -80,8 +59,6 @@ func init() {
L2RelayedMessageEventSignature = L2ScrollMessengerABI.Events["RelayedMessage"].ID
L2FailedRelayedMessageEventSignature = L2ScrollMessengerABI.Events["FailedRelayedMessage"].ID
L2ImportBlockEventSignature = L1BlockContainerABI.Events["ImportBlock"].ID
L2AppendMessageEventSignature = L2MessageQueueABI.Events["AppendMessage"].ID
}

View File

@@ -11,21 +11,13 @@ import (
func TestEventSignature(t *testing.T) {
assert := assert.New(t)
assert.Equal(L1SentMessageEventSignature, common.HexToHash("104371f3b442861a2a7b82a070afbbaab748bb13757bf47769e170e37809ec1e"))
assert.Equal(L1RelayedMessageEventSignature, common.HexToHash("4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c"))
assert.Equal(L1FailedRelayedMessageEventSignature, common.HexToHash("99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f"))
assert.Equal(L1CommitBatchEventSignature, common.HexToHash("2c32d4ae151744d0bf0b9464a3e897a1d17ed2f1af71f7c9a75f12ce0d28238f"))
assert.Equal(L1FinalizeBatchEventSignature, common.HexToHash("26ba82f907317eedc97d0cbef23de76a43dd6edb563bdb6e9407645b950a7a2d"))
assert.Equal(L1QueueTransactionEventSignature, common.HexToHash("69cfcb8e6d4192b8aba9902243912587f37e550d75c1fa801491fce26717f37e"))
assert.Equal(L2SentMessageEventSignature, common.HexToHash("104371f3b442861a2a7b82a070afbbaab748bb13757bf47769e170e37809ec1e"))
assert.Equal(L2RelayedMessageEventSignature, common.HexToHash("4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c"))
assert.Equal(L2FailedRelayedMessageEventSignature, common.HexToHash("99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f"))
assert.Equal(L2ImportBlockEventSignature, common.HexToHash("a7823f45e1ee21f9530b77959b57507ad515a14fa9fa24d262ee80e79b2b5745"))
assert.Equal(L2AppendMessageEventSignature, common.HexToHash("faa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693"))
}
@@ -117,12 +109,3 @@ func TestPackSetL2BaseFee(t *testing.T) {
_, err = l2GasOracleABI.Pack("setL2BaseFee", baseFee)
assert.NoError(err)
}
func TestPackImportBlock(t *testing.T) {
assert := assert.New(t)
l1BlockContainerABI := L1BlockContainerABI
_, err := l1BlockContainerABI.Pack("importBlockHeader", common.Hash{}, []byte{}, false)
assert.NoError(err)
}

View File

@@ -17,8 +17,8 @@ import (
"scroll-tech/common/utils"
"scroll-tech/common/version"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/watcher"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/controller/watcher"
)
var app *cli.App
@@ -75,7 +75,7 @@ func action(ctx *cli.Context) error {
}
l1watcher := watcher.NewL1WatcherClient(ctx.Context, l1client, cfg.L1Config.StartHeight, cfg.L1Config.Confirmations,
cfg.L1Config.L1MessengerAddress, cfg.L1Config.L1MessageQueueAddress, cfg.L1Config.ScrollChainContractAddress, db, registry)
cfg.L1Config.L1MessageQueueAddress, cfg.L1Config.ScrollChainContractAddress, db, registry)
l2watcher := watcher.NewL2WatcherClient(ctx.Context, l2client, cfg.L2Config.Confirmations, cfg.L2Config.L2MessengerAddress,
cfg.L2Config.L2MessageQueueAddress, cfg.L2Config.WithdrawTrieRootSlot, db, registry)
@@ -89,6 +89,7 @@ func action(ctx *cli.Context) error {
// Start l2 watcher process
go utils.Loop(subCtx, 2*time.Second, l2watcher.FetchContractEvent)
// Finish start all l2 functions
log.Info("Start event-watcher successfully")
// Catch CTRL-C to ensure a graceful shutdown.

View File

@@ -0,0 +1,7 @@
package main
import "scroll-tech/rollup/cmd/event_watcher/app"
func main() {
app.Run()
}

View File

@@ -17,10 +17,10 @@ import (
"scroll-tech/common/utils"
"scroll-tech/common/version"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/relayer"
"scroll-tech/bridge/internal/controller/watcher"
butils "scroll-tech/bridge/internal/utils"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/controller/relayer"
"scroll-tech/rollup/internal/controller/watcher"
butils "scroll-tech/rollup/internal/utils"
)
var app *cli.App
@@ -78,8 +78,7 @@ func action(ctx *cli.Context) error {
return err
}
l1watcher := watcher.NewL1WatcherClient(ctx.Context, l1client, cfg.L1Config.StartHeight, cfg.L1Config.Confirmations,
cfg.L1Config.L1MessengerAddress, cfg.L1Config.L1MessageQueueAddress, cfg.L1Config.ScrollChainContractAddress, db, registry)
l1watcher := watcher.NewL1WatcherClient(ctx.Context, l1client, cfg.L1Config.StartHeight, cfg.L1Config.Confirmations, cfg.L1Config.L1MessageQueueAddress, cfg.L1Config.ScrollChainContractAddress, db, registry)
l1relayer, err := relayer.NewLayer1Relayer(ctx.Context, db, cfg.L1Config.RelayerConfig, registry)
if err != nil {

View File

@@ -0,0 +1,7 @@
package main
import "scroll-tech/rollup/cmd/gas_oracle/app"
func main() {
app.Run()
}

View File

@@ -11,7 +11,7 @@ import (
"scroll-tech/common/docker"
"scroll-tech/common/utils"
"scroll-tech/bridge/internal/config"
"scroll-tech/rollup/internal/config"
)
// MockApp mockApp-test client manager.
@@ -22,29 +22,29 @@ type MockApp struct {
mockApps map[utils.MockAppName]docker.AppAPI
originFile string
bridgeFile string
rollupFile string
args []string
}
// NewBridgeApp return a new bridgeApp manager, name mush be one them.
func NewBridgeApp(base *docker.App, file string) *MockApp {
// NewRollupApp return a new rollupApp manager, name mush be one them.
func NewRollupApp(base *docker.App, file string) *MockApp {
bridgeFile := fmt.Sprintf("/tmp/%d_bridge-config.json", base.Timestamp)
bridgeApp := &MockApp{
rollupFile := fmt.Sprintf("/tmp/%d_rollup-config.json", base.Timestamp)
rollupApp := &MockApp{
base: base,
mockApps: make(map[utils.MockAppName]docker.AppAPI),
originFile: file,
bridgeFile: bridgeFile,
args: []string{"--log.debug", "--config", bridgeFile},
rollupFile: rollupFile,
args: []string{"--log.debug", "--config", rollupFile},
}
if err := bridgeApp.MockConfig(true); err != nil {
if err := rollupApp.MockConfig(true); err != nil {
panic(err)
}
return bridgeApp
return rollupApp
}
// RunApp run bridge-test child process by multi parameters.
// RunApp run rollup-test child process by multi parameters.
func (b *MockApp) RunApp(t *testing.T, name utils.MockAppName, args ...string) {
if !(name == utils.EventWatcherApp ||
name == utils.GasOracleApp ||
@@ -72,16 +72,16 @@ func (b *MockApp) WaitExit() {
b.mockApps = make(map[utils.MockAppName]docker.AppAPI)
}
// Free stop and release bridge mocked apps.
// Free stop and release rollup mocked apps.
func (b *MockApp) Free() {
b.WaitExit()
_ = os.Remove(b.bridgeFile)
_ = os.Remove(b.rollupFile)
}
// MockConfig creates a new bridge config.
// MockConfig creates a new rollup config.
func (b *MockApp) MockConfig(store bool) error {
base := b.base
// Load origin bridge config file.
// Load origin rollup config file.
cfg, err := config.NewConfig(b.originFile)
if err != nil {
return err
@@ -97,10 +97,10 @@ func (b *MockApp) MockConfig(store bool) error {
if !store {
return nil
}
// Store changed bridge config into a temp file.
// Store changed rollup config into a temp file.
data, err := json.Marshal(b.Config)
if err != nil {
return err
}
return os.WriteFile(b.bridgeFile, data, 0600)
return os.WriteFile(b.rollupFile, data, 0600)
}

View File

@@ -17,10 +17,10 @@ import (
"scroll-tech/common/utils"
"scroll-tech/common/version"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/relayer"
"scroll-tech/bridge/internal/controller/watcher"
butils "scroll-tech/bridge/internal/utils"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/controller/relayer"
"scroll-tech/rollup/internal/controller/watcher"
butils "scroll-tech/rollup/internal/utils"
)
var app *cli.App

View File

@@ -0,0 +1,7 @@
package main
import "scroll-tech/rollup/cmd/rollup_relayer/app"
func main() {
app.Run()
}

View File

@@ -2,12 +2,10 @@
"l1_config": {
"confirmations": "0x6",
"endpoint": "DUMMY_ENDPOINT",
"l1_messenger_address": "0x0000000000000000000000000000000000000000",
"l1_message_queue_address": "0x0000000000000000000000000000000000000000",
"scroll_chain_address": "0x0000000000000000000000000000000000000000",
"start_height": 0,
"relayer_config": {
"messenger_contract_address": "0x0000000000000000000000000000000000000000",
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
"sender_config": {
"endpoint": "/var/lib/jenkins/workspace/SequencerPipeline/MyPrivateNetwork/geth.ipc",
@@ -27,7 +25,6 @@
"gas_price_diff": 50000
},
"finalize_batch_interval_sec": 0,
"message_sender_private_key": "1212121212121212121212121212121212121212121212121212121212121212",
"gas_oracle_sender_private_key": "1313131313131313131313131313131313131313131313131313131313131313"
}
},
@@ -38,7 +35,6 @@
"l2_message_queue_address": "0x0000000000000000000000000000000000000000",
"relayer_config": {
"rollup_contract_address": "0x0000000000000000000000000000000000000000",
"messenger_contract_address": "0x0000000000000000000000000000000000000000",
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
"sender_config": {
"endpoint": "DUMMY_ENDPOINT",
@@ -63,10 +59,10 @@
"base_url": "http://localhost:8750"
},
"finalize_batch_interval_sec": 0,
"message_sender_private_key": "1212121212121212121212121212121212121212121212121212121212121212",
"gas_oracle_sender_private_key": "1313131313131313131313131313131313131313131313131313131313131313",
"commit_sender_private_key": "1414141414141414141414141414141414141414141414141414141414141414",
"finalize_sender_private_key": "1515151515151515151515151515151515151515151515151515151515151515"
"finalize_sender_private_key": "1515151515151515151515151515151515151515151515151515151515151515",
"gas_cost_increase_multiplier": 1.2
},
"chunk_proposer_config": {
"max_tx_num_per_chunk": 1123,

View File

@@ -1,4 +1,4 @@
module scroll-tech/bridge
module scroll-tech/rollup
go 1.19
@@ -8,7 +8,7 @@ require (
github.com/go-resty/resty/v2 v2.7.0
github.com/orcaman/concurrent-map/v2 v2.0.1
github.com/prometheus/client_golang v1.14.0
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc
github.com/smartystreets/goconvey v1.8.0
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.7

View File

@@ -156,8 +156,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28 h1:CECBTWhZ5NGAn8lGFB4ooRAYxZns8PXoX8kTR/14c04=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230812030736-25fe3ba69a28/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc h1:eK3NOpjgm/b2TQ6rYqWx92Zri0kBuxf6gKjjsVxWKr8=
github.com/scroll-tech/go-ethereum v1.10.14-0.20230829000527-f883dcdc21fc/go.mod h1:DiN3p2inoXOxGffxSswDKqWjQ7bU+Mp0c9v0XQXKmaA=
github.com/scroll-tech/zktrie v0.6.0 h1:xLrMAO31Yo2BiPg1jtYKzcjpEFnXy8acbB7iIsyshPs=
github.com/scroll-tech/zktrie v0.6.0/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=

View File

@@ -18,7 +18,7 @@ func TestConfig(t *testing.T) {
data, err := json.Marshal(cfg)
assert.NoError(t, err)
tmpJSON := fmt.Sprintf("/tmp/%d_bridge_config.json", time.Now().Nanosecond())
tmpJSON := fmt.Sprintf("/tmp/%d_rollup_config.json", time.Now().Nanosecond())
defer func() {
if _, err = os.Stat(tmpJSON); err == nil {
assert.NoError(t, os.Remove(tmpJSON))

View File

@@ -13,8 +13,6 @@ type L1Config struct {
Endpoint string `json:"endpoint"`
// The start height to sync event from layer 1
StartHeight uint64 `json:"start_height"`
// The L1ScrollMessenger contract address deployed on layer 1 chain.
L1MessengerAddress common.Address `json:"l1_messenger_address"`
// The L1MessageQueue contract address deployed on layer 1 chain.
L1MessageQueueAddress common.Address `json:"l1_message_queue_address"`
// The ScrollChain contract address deployed on layer 1 chain.

View File

@@ -49,8 +49,6 @@ type ChainMonitor struct {
type RelayerConfig struct {
// RollupContractAddress store the rollup contract address.
RollupContractAddress common.Address `json:"rollup_contract_address,omitempty"`
// MessengerContractAddress store the scroll messenger contract address.
MessengerContractAddress common.Address `json:"messenger_contract_address"`
// GasPriceOracleContractAddress store the scroll messenger contract address.
GasPriceOracleContractAddress common.Address `json:"gas_price_oracle_contract_address"`
// sender config
@@ -63,8 +61,9 @@ type RelayerConfig struct {
MessageRelayMinGasLimit uint64 `json:"message_relay_min_gas_limit,omitempty"`
// ChainMonitor config of monitoring service
ChainMonitor *ChainMonitor `json:"chain_monitor,omitempty"`
// GasCostIncreaseMultiplier multiplier for min gas limit estimation
GasCostIncreaseMultiplier float64 `json:"gas_cost_increase_multiplier,omitempty"`
// The private key of the relayer
MessageSenderPrivateKey *ecdsa.PrivateKey `json:"-"`
GasOracleSenderPrivateKey *ecdsa.PrivateKey `json:"-"`
CommitSenderPrivateKey *ecdsa.PrivateKey `json:"-"`
FinalizeSenderPrivateKey *ecdsa.PrivateKey `json:"-"`
@@ -104,7 +103,6 @@ func convertAndCheck(key string, uniqueAddressesSet map[string]struct{}) (*ecdsa
func (r *RelayerConfig) UnmarshalJSON(input []byte) error {
var privateKeysConfig struct {
relayerConfigAlias
MessageSenderPrivateKey string `json:"message_sender_private_key"`
GasOracleSenderPrivateKey string `json:"gas_oracle_sender_private_key"`
CommitSenderPrivateKey string `json:"commit_sender_private_key"`
FinalizeSenderPrivateKey string `json:"finalize_sender_private_key"`
@@ -118,11 +116,6 @@ func (r *RelayerConfig) UnmarshalJSON(input []byte) error {
uniqueAddressesSet := make(map[string]struct{})
r.MessageSenderPrivateKey, err = convertAndCheck(privateKeysConfig.MessageSenderPrivateKey, uniqueAddressesSet)
if err != nil {
return fmt.Errorf("error converting and checking message sender private key: %w", err)
}
r.GasOracleSenderPrivateKey, err = convertAndCheck(privateKeysConfig.GasOracleSenderPrivateKey, uniqueAddressesSet)
if err != nil {
return fmt.Errorf("error converting and checking gas oracle sender private key: %w", err)
@@ -146,14 +139,12 @@ func (r *RelayerConfig) MarshalJSON() ([]byte, error) {
privateKeysConfig := struct {
relayerConfigAlias
// The private key of the relayer
MessageSenderPrivateKey string `json:"message_sender_private_key"`
GasOracleSenderPrivateKey string `json:"gas_oracle_sender_private_key"`
CommitSenderPrivateKey string `json:"commit_sender_private_key"`
FinalizeSenderPrivateKey string `json:"finalize_sender_private_key"`
}{}
privateKeysConfig.relayerConfigAlias = relayerConfigAlias(*r)
privateKeysConfig.MessageSenderPrivateKey = common.Bytes2Hex(crypto.FromECDSA(r.MessageSenderPrivateKey))
privateKeysConfig.GasOracleSenderPrivateKey = common.Bytes2Hex(crypto.FromECDSA(r.GasOracleSenderPrivateKey))
privateKeysConfig.CommitSenderPrivateKey = common.Bytes2Hex(crypto.FromECDSA(r.CommitSenderPrivateKey))
privateKeysConfig.FinalizeSenderPrivateKey = common.Bytes2Hex(crypto.FromECDSA(r.FinalizeSenderPrivateKey))

View File

@@ -6,10 +6,6 @@ const (
gasPriceDiffPrecision = 1000000
defaultGasPriceDiff = 50000 // 5%
defaultL1MessageRelayMinGasLimit = 130000 // should be enough for both ERC20 and ETH relay
defaultL2MessageRelayMinGasLimit = 200000
)
var (

View File

@@ -8,17 +8,16 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/scroll-tech/go-ethereum/accounts/abi"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/log"
"gorm.io/gorm"
"scroll-tech/common/types"
bridgeAbi "scroll-tech/bridge/abi"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/sender"
"scroll-tech/bridge/internal/orm"
bridgeAbi "scroll-tech/rollup/abi"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/controller/sender"
"scroll-tech/rollup/internal/orm"
)
// Layer1Relayer is responsible for
@@ -32,32 +31,19 @@ type Layer1Relayer struct {
cfg *config.RelayerConfig
// channel used to communicate with transaction sender
messageSender *sender.Sender
l2MessengerABI *abi.ABI
gasOracleSender *sender.Sender
l1GasOracleABI *abi.ABI
minGasLimitForMessageRelay uint64
lastGasPrice uint64
minGasPrice uint64
gasPriceDiff uint64
l1MessageOrm *orm.L1Message
l1BlockOrm *orm.L1Block
metrics *l1RelayerMetrics
l1BlockOrm *orm.L1Block
metrics *l1RelayerMetrics
}
// NewLayer1Relayer will return a new instance of Layer1RelayerClient
func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfig, reg prometheus.Registerer) (*Layer1Relayer, error) {
messageSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.MessageSenderPrivateKey, "l1_relayer", "message_sender", reg)
if err != nil {
addr := crypto.PubkeyToAddress(cfg.MessageSenderPrivateKey.PublicKey)
return nil, fmt.Errorf("new message sender failed for address %s, err: %v", addr.Hex(), err)
}
gasOracleSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.GasOracleSenderPrivateKey, "l1_relayer", "gas_oracle_sender", reg)
if err != nil {
addr := crypto.PubkeyToAddress(cfg.GasOracleSenderPrivateKey.PublicKey)
@@ -74,25 +60,14 @@ func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfi
gasPriceDiff = defaultGasPriceDiff
}
minGasLimitForMessageRelay := uint64(defaultL1MessageRelayMinGasLimit)
if cfg.MessageRelayMinGasLimit != 0 {
minGasLimitForMessageRelay = cfg.MessageRelayMinGasLimit
}
l1Relayer := &Layer1Relayer{
cfg: cfg,
ctx: ctx,
l1MessageOrm: orm.NewL1Message(db),
l1BlockOrm: orm.NewL1Block(db),
messageSender: messageSender,
l2MessengerABI: bridgeAbi.L2ScrollMessengerABI,
cfg: cfg,
ctx: ctx,
l1BlockOrm: orm.NewL1Block(db),
gasOracleSender: gasOracleSender,
l1GasOracleABI: bridgeAbi.L1GasPriceOracleABI,
minGasLimitForMessageRelay: minGasLimitForMessageRelay,
minGasPrice: minGasPrice,
gasPriceDiff: gasPriceDiff,
}
@@ -103,57 +78,9 @@ func NewLayer1Relayer(ctx context.Context, db *gorm.DB, cfg *config.RelayerConfi
return l1Relayer, nil
}
// ProcessSavedEvents relays saved un-processed cross-domain transactions to desired blockchain
func (r *Layer1Relayer) ProcessSavedEvents() {
// msgs are sorted by nonce in increasing order
msgs, err := r.l1MessageOrm.GetL1MessagesByStatus(types.MsgPending, 100)
if err != nil {
log.Error("Failed to fetch unprocessed L1 messages", "err", err)
return
}
if len(msgs) > 0 {
log.Info("Processing L1 messages", "count", len(msgs))
}
for _, msg := range msgs {
tmpMsg := msg
r.metrics.bridgeL1RelayedMsgsTotal.Inc()
if err = r.processSavedEvent(&tmpMsg); err != nil {
r.metrics.bridgeL1RelayedMsgsFailureTotal.Inc()
if !errors.Is(err, sender.ErrNoAvailableAccount) && !errors.Is(err, sender.ErrFullPending) {
log.Error("failed to process event", "msg.msgHash", msg.MsgHash, "err", err)
}
return
}
}
}
func (r *Layer1Relayer) processSavedEvent(msg *orm.L1Message) error {
calldata := common.Hex2Bytes(msg.Calldata)
hash, err := r.messageSender.SendTransaction(msg.MsgHash, &r.cfg.MessengerContractAddress, big.NewInt(0), calldata, r.minGasLimitForMessageRelay)
if err != nil && errors.Is(err, ErrExecutionRevertedMessageExpired) {
return r.l1MessageOrm.UpdateLayer1Status(r.ctx, msg.MsgHash, types.MsgExpired)
}
if err != nil && errors.Is(err, ErrExecutionRevertedAlreadySuccessExecuted) {
return r.l1MessageOrm.UpdateLayer1Status(r.ctx, msg.MsgHash, types.MsgConfirmed)
}
if err != nil {
return err
}
log.Info("relayMessage to layer2", "msg hash", msg.MsgHash, "tx hash", hash)
err = r.l1MessageOrm.UpdateLayer1StatusAndLayer2Hash(r.ctx, msg.MsgHash, types.MsgSubmitted, hash.String())
if err != nil {
log.Error("UpdateLayer1StatusAndLayer2Hash failed", "msg.msgHash", msg.MsgHash, "msg.height", msg.Height, "err", err)
}
return err
}
// ProcessGasPriceOracle imports gas price to layer2
func (r *Layer1Relayer) ProcessGasPriceOracle() {
r.metrics.bridgeL1RelayerGasPriceOraclerRunTotal.Inc()
r.metrics.rollupL1RelayerGasPriceOraclerRunTotal.Inc()
latestBlockHeight, err := r.l1BlockOrm.GetLatestL1BlockHeight(r.ctx)
if err != nil {
log.Warn("Failed to fetch latest L1 block height from db", "err", err)
@@ -198,7 +125,7 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() {
return
}
r.lastGasPrice = block.BaseFee
r.metrics.bridgeL1RelayerLastGasPrice.Set(float64(r.lastGasPrice))
r.metrics.rollupL1RelayerLastGasPrice.Set(float64(r.lastGasPrice))
log.Info("Update l1 base fee", "txHash", hash.String(), "baseFee", baseFee)
}
}
@@ -209,24 +136,8 @@ func (r *Layer1Relayer) handleConfirmLoop(ctx context.Context) {
select {
case <-ctx.Done():
return
case cfm := <-r.messageSender.ConfirmChan():
r.metrics.bridgeL1MsgsRelayedConfirmedTotal.Inc()
if !cfm.IsSuccessful {
err := r.l1MessageOrm.UpdateLayer1StatusAndLayer2Hash(r.ctx, cfm.ID, types.MsgRelayFailed, cfm.TxHash.String())
if err != nil {
log.Warn("UpdateLayer1StatusAndLayer2Hash failed", "err", err)
}
log.Warn("transaction confirmed but failed in layer2", "confirmation", cfm)
} else {
// @todo handle db error
err := r.l1MessageOrm.UpdateLayer1StatusAndLayer2Hash(r.ctx, cfm.ID, types.MsgConfirmed, cfm.TxHash.String())
if err != nil {
log.Warn("UpdateLayer1StatusAndLayer2Hash failed", "err", err)
}
log.Info("transaction confirmed in layer2", "confirmation", cfm)
}
case cfm := <-r.gasOracleSender.ConfirmChan():
r.metrics.bridgeL1GasOraclerConfirmedTotal.Inc()
r.metrics.rollupL1GasOraclerConfirmedTotal.Inc()
if !cfm.IsSuccessful {
// @discuss: maybe make it pending again?
err := r.l1BlockOrm.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleFailed, cfm.TxHash.String())

View File

@@ -0,0 +1,54 @@
package relayer
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type l1RelayerMetrics struct {
rollupL1RelayedMsgsTotal prometheus.Counter
rollupL1RelayedMsgsFailureTotal prometheus.Counter
rollupL1RelayerGasPriceOraclerRunTotal prometheus.Counter
rollupL1RelayerLastGasPrice prometheus.Gauge
rollupL1MsgsRelayedConfirmedTotal prometheus.Counter
rollupL1GasOraclerConfirmedTotal prometheus.Counter
}
var (
initL1RelayerMetricOnce sync.Once
l1RelayerMetric *l1RelayerMetrics
)
func initL1RelayerMetrics(reg prometheus.Registerer) *l1RelayerMetrics {
initL1RelayerMetricOnce.Do(func() {
l1RelayerMetric = &l1RelayerMetrics{
rollupL1RelayedMsgsTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer1_msg_relayed_total",
Help: "The total number of the l1 relayed message.",
}),
rollupL1RelayedMsgsFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer1_msg_relayed_failure_total",
Help: "The total number of the l1 relayed failure message.",
}),
rollupL1MsgsRelayedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer1_relayed_confirmed_total",
Help: "The total number of layer1 relayed confirmed",
}),
rollupL1RelayerGasPriceOraclerRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer1_gas_price_oracler_total",
Help: "The total number of layer1 gas price oracler run total",
}),
rollupL1RelayerLastGasPrice: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "rollup_layer1_gas_price_latest_gas_price",
Help: "The latest gas price of rollup relayer l1",
}),
rollupL1GasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer1_gas_oracler_confirmed_total",
Help: "The total number of layer1 relayed confirmed",
}),
}
})
return l1RelayerMetric
}

View File

@@ -18,35 +18,8 @@ import (
"scroll-tech/database/migrate"
"scroll-tech/bridge/internal/controller/sender"
"scroll-tech/bridge/internal/orm"
)
var (
templateL1Message = []*orm.L1Message{
{
QueueIndex: 1,
MsgHash: "msg_hash1",
Height: 1,
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
Value: "0x19ece",
GasLimit: 11529940,
Target: "0x2c73620b223808297ea734d946813f0dd78eb8f7",
Calldata: "testdata",
Layer1Hash: "hash0",
},
{
QueueIndex: 2,
MsgHash: "msg_hash2",
Height: 2,
Sender: "0x596a746661dbed76a84556111c2872249b070e15",
Value: "0x19ece",
GasLimit: 11529940,
Target: "0x2c73620b223808297ea734d946813f0dd78eb8f7",
Calldata: "testdata",
Layer1Hash: "hash1",
},
}
"scroll-tech/rollup/internal/controller/sender"
"scroll-tech/rollup/internal/orm"
)
func setupL1RelayerDB(t *testing.T) *gorm.DB {
@@ -67,61 +40,6 @@ func testCreateNewL1Relayer(t *testing.T) {
assert.NotNil(t, relayer)
}
func testL1RelayerProcessSaveEvents(t *testing.T) {
db := setupL1RelayerDB(t)
defer database.CloseDB(db)
l1MessageOrm := orm.NewL1Message(db)
l1Cfg := cfg.L1Config
relayer, err := NewLayer1Relayer(context.Background(), db, l1Cfg.RelayerConfig, nil)
assert.NoError(t, err)
assert.NotNil(t, relayer)
assert.NoError(t, l1MessageOrm.SaveL1Messages(context.Background(), templateL1Message))
relayer.ProcessSavedEvents()
msg1, err := l1MessageOrm.GetL1MessageByQueueIndex(1)
assert.NoError(t, err)
assert.Equal(t, types.MsgStatus(msg1.Status), types.MsgSubmitted)
msg2, err := l1MessageOrm.GetL1MessageByQueueIndex(2)
assert.NoError(t, err)
assert.Equal(t, types.MsgStatus(msg2.Status), types.MsgSubmitted)
}
func testL1RelayerMsgConfirm(t *testing.T) {
db := setupL1RelayerDB(t)
defer database.CloseDB(db)
l1MessageOrm := orm.NewL1Message(db)
l1Messages := []*orm.L1Message{
{MsgHash: "msg-1", QueueIndex: 0},
{MsgHash: "msg-2", QueueIndex: 1},
}
err := l1MessageOrm.SaveL1Messages(context.Background(), l1Messages)
assert.NoError(t, err)
// Create and set up the Layer1 Relayer.
l1Cfg := cfg.L1Config
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
l1Relayer, err := NewLayer1Relayer(ctx, db, l1Cfg.RelayerConfig, nil)
assert.NoError(t, err)
// Simulate message confirmations.
l1Relayer.messageSender.SendConfirmation(&sender.Confirmation{
ID: "msg-1",
IsSuccessful: true,
})
l1Relayer.messageSender.SendConfirmation(&sender.Confirmation{
ID: "msg-2",
IsSuccessful: false,
})
// Check the database for the updated status using TryTimes.
ok := utils.TryTimes(5, func() bool {
msg1, err1 := l1MessageOrm.GetL1MessageByMsgHash("msg-1")
msg2, err2 := l1MessageOrm.GetL1MessageByMsgHash("msg-2")
return err1 == nil && types.MsgStatus(msg1.Status) == types.MsgConfirmed &&
err2 == nil && types.MsgStatus(msg2.Status) == types.MsgRelayFailed
})
assert.True(t, ok)
}
func testL1RelayerGasOracleConfirm(t *testing.T) {
db := setupL1RelayerDB(t)
defer database.CloseDB(db)

View File

@@ -20,10 +20,10 @@ import (
"scroll-tech/common/types"
bridgeAbi "scroll-tech/bridge/abi"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/controller/sender"
"scroll-tech/bridge/internal/orm"
bridgeAbi "scroll-tech/rollup/abi"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/controller/sender"
"scroll-tech/rollup/internal/orm"
)
// Layer2Relayer is responsible for
@@ -44,9 +44,6 @@ type Layer2Relayer struct {
cfg *config.RelayerConfig
messageSender *sender.Sender
l1MessengerABI *abi.ABI
commitSender *sender.Sender
finalizeSender *sender.Sender
l1RollupABI *abi.ABI
@@ -54,8 +51,6 @@ type Layer2Relayer struct {
gasOracleSender *sender.Sender
l2GasOracleABI *abi.ABI
minGasLimitForMessageRelay uint64
lastGasPrice uint64
minGasPrice uint64
gasPriceDiff uint64
@@ -80,12 +75,6 @@ type Layer2Relayer struct {
// NewLayer2Relayer will return a new instance of Layer2RelayerClient
func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.DB, cfg *config.RelayerConfig, initGenesis bool, reg prometheus.Registerer) (*Layer2Relayer, error) {
messageSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.MessageSenderPrivateKey, "l2_relayer", "message_sender", reg)
if err != nil {
addr := crypto.PubkeyToAddress(cfg.MessageSenderPrivateKey.PublicKey)
return nil, fmt.Errorf("new message sender failed for address %s, err: %w", addr.Hex(), err)
}
commitSender, err := sender.NewSender(ctx, cfg.SenderConfig, cfg.CommitSenderPrivateKey, "l2_relayer", "commit_sender", reg)
if err != nil {
addr := crypto.PubkeyToAddress(cfg.CommitSenderPrivateKey.PublicKey)
@@ -113,11 +102,6 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.
gasPriceDiff = defaultGasPriceDiff
}
minGasLimitForMessageRelay := uint64(defaultL2MessageRelayMinGasLimit)
if cfg.MessageRelayMinGasLimit != 0 {
minGasLimitForMessageRelay = cfg.MessageRelayMinGasLimit
}
// chain_monitor client
chainMonitorClient := resty.New()
chainMonitorClient.SetRetryCount(cfg.ChainMonitor.TryTimes)
@@ -133,9 +117,6 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.
l2Client: l2Client,
messageSender: messageSender,
l1MessengerABI: bridgeAbi.L1ScrollMessengerABI,
commitSender: commitSender,
finalizeSender: finalizeSender,
l1RollupABI: bridgeAbi.ScrollChainABI,
@@ -143,8 +124,6 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db *gorm.
gasOracleSender: gasOracleSender,
l2GasOracleABI: bridgeAbi.L2GasPriceOracleABI,
minGasLimitForMessageRelay: minGasLimitForMessageRelay,
minGasPrice: minGasPrice,
gasPriceDiff: gasPriceDiff,
@@ -285,7 +264,7 @@ func (r *Layer2Relayer) commitGenesisBatch(batchHash string, batchHeader []byte,
// ProcessGasPriceOracle imports gas price to layer1
func (r *Layer2Relayer) ProcessGasPriceOracle() {
r.metrics.bridgeL2RelayerGasPriceOraclerRunTotal.Inc()
r.metrics.rollupL2RelayerGasPriceOraclerRunTotal.Inc()
batch, err := r.batchOrm.GetLatestBatch(r.ctx)
if batch == nil || err != nil {
log.Error("Failed to GetLatestBatch", "batch", batch, "err", err)
@@ -323,7 +302,7 @@ func (r *Layer2Relayer) ProcessGasPriceOracle() {
return
}
r.lastGasPrice = suggestGasPriceUint64
r.metrics.bridgeL2RelayerLastGasPrice.Set(float64(r.lastGasPrice))
r.metrics.rollupL2RelayerLastGasPrice.Set(float64(r.lastGasPrice))
log.Info("Update l2 gas price", "txHash", hash.String(), "GasPrice", suggestGasPrice)
}
}
@@ -332,13 +311,13 @@ 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.
pendingBatches, err := r.batchOrm.GetPendingBatches(r.ctx, 1)
pendingBatches, err := r.batchOrm.GetPendingBatches(r.ctx, 5)
if err != nil {
log.Error("Failed to fetch pending L2 batches", "err", err)
return
}
for _, batch := range pendingBatches {
r.metrics.bridgeL2RelayerProcessPendingBatchTotal.Inc()
r.metrics.rollupL2RelayerProcessPendingBatchTotal.Inc()
// get current header and parent header.
currentBatchHeader, err := types.DecodeBatchHeader(batch.BatchHeader)
if err != nil {
@@ -395,7 +374,8 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
// send transaction
txID := batch.Hash + "-commit"
txHash, err := r.commitSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, 0)
minGasLimit := uint64(float64(batch.TotalL1CommitGas) * r.cfg.GasCostIncreaseMultiplier)
txHash, err := r.commitSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, minGasLimit)
if err != nil {
log.Error(
"Failed to send commitBatch tx to layer1",
@@ -420,7 +400,7 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
log.Error("UpdateCommitTxHashAndRollupStatus failed", "hash", batch.Hash, "index", batch.Index, "err", err)
return
}
r.metrics.bridgeL2RelayerProcessPendingBatchSuccessTotal.Inc()
r.metrics.rollupL2RelayerProcessPendingBatchSuccessTotal.Inc()
r.processingCommitment.Store(txID, batch.Hash)
log.Info("Sent the commitBatch tx to layer1", "batch index", batch.Index, "batch hash", batch.Hash, "tx hash", txHash.Hex())
}
@@ -444,7 +424,7 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
return
}
r.metrics.bridgeL2RelayerProcessCommittedBatchesTotal.Inc()
r.metrics.rollupL2RelayerProcessCommittedBatchesTotal.Inc()
batch := batches[0]
hash := batch.Hash
@@ -455,17 +435,17 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
return
case types.ProvingTaskVerified:
log.Info("Start to roll up zk proof", "hash", hash)
r.metrics.bridgeL2RelayerProcessCommittedBatchesFinalizedTotal.Inc()
r.metrics.rollupL2RelayerProcessCommittedBatchesFinalizedTotal.Inc()
// Check batch status before send `finalizeBatchWithProof` tx.
//batchStatus, err := r.getBatchStatusByIndex(batch.Index)
//if err != nil {
// r.metrics.bridgeL2ChainMonitorLatestFailedCall.Inc()
// r.metrics.rollupL2ChainMonitorLatestFailedCall.Inc()
// log.Warn("failed to get batch status, please check chain_monitor api server", "batch_index", batch.Index, "err", err)
// return
//}
//if !batchStatus {
// r.metrics.bridgeL2ChainMonitorLatestFailedBatchStatus.Inc()
// r.metrics.rollupL2ChainMonitorLatestFailedBatchStatus.Inc()
// log.Error("the batch status is not right, stop finalize batch and check the reason", "batch_index", batch.Index)
// return
//}
@@ -523,7 +503,6 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
"RollupContractAddress", r.cfg.RollupContractAddress,
"err", err,
)
log.Debug(
"finalizeBatchWithProof in layer1 failed",
"index", batch.Index,
@@ -545,7 +524,7 @@ func (r *Layer2Relayer) ProcessCommittedBatches() {
"tx hash", finalizeTxHash.String(), "err", err)
}
r.processingFinalization.Store(txID, hash)
r.metrics.bridgeL2RelayerProcessCommittedBatchesFinalizedSuccessTotal.Inc()
r.metrics.rollupL2RelayerProcessCommittedBatchesFinalizedSuccessTotal.Inc()
case types.ProvingTaskFailed:
// We were unable to prove this batch. There are two possibilities:
@@ -613,7 +592,7 @@ func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
"batch hash", batchHash.(string),
"tx hash", confirmation.TxHash.String(), "err", err)
}
r.metrics.bridgeL2BatchesCommittedConfirmedTotal.Inc()
r.metrics.rollupL2BatchesCommittedConfirmedTotal.Inc()
r.processingCommitment.Delete(confirmation.ID)
}
@@ -635,7 +614,7 @@ func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
"batch hash", batchHash.(string),
"tx hash", confirmation.TxHash.String(), "err", err)
}
r.metrics.bridgeL2BatchesFinalizedConfirmedTotal.Inc()
r.metrics.rollupL2BatchesFinalizedConfirmedTotal.Inc()
r.processingFinalization.Delete(confirmation.ID)
}
log.Info("transaction confirmed in layer1", "type", transactionType, "confirmation", confirmation)
@@ -646,14 +625,12 @@ func (r *Layer2Relayer) handleConfirmLoop(ctx context.Context) {
select {
case <-ctx.Done():
return
case confirmation := <-r.messageSender.ConfirmChan():
r.handleConfirmation(confirmation)
case confirmation := <-r.commitSender.ConfirmChan():
r.handleConfirmation(confirmation)
case confirmation := <-r.finalizeSender.ConfirmChan():
r.handleConfirmation(confirmation)
case cfm := <-r.gasOracleSender.ConfirmChan():
r.metrics.bridgeL2BatchesGasOraclerConfirmedTotal.Inc()
r.metrics.rollupL2BatchesGasOraclerConfirmedTotal.Inc()
if !cfm.IsSuccessful {
// @discuss: maybe make it pending again?
err := r.batchOrm.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, cfm.ID, types.GasOracleFailed, cfm.TxHash.String())

View File

@@ -0,0 +1,84 @@
package relayer
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type l2RelayerMetrics struct {
rollupL2RelayerProcessPendingBatchTotal prometheus.Counter
rollupL2RelayerProcessPendingBatchSuccessTotal prometheus.Counter
rollupL2RelayerGasPriceOraclerRunTotal prometheus.Counter
rollupL2RelayerLastGasPrice prometheus.Gauge
rollupL2RelayerProcessCommittedBatchesTotal prometheus.Counter
rollupL2RelayerProcessCommittedBatchesFinalizedTotal prometheus.Counter
rollupL2RelayerProcessCommittedBatchesFinalizedSuccessTotal prometheus.Counter
rollupL2BatchesCommittedConfirmedTotal prometheus.Counter
rollupL2BatchesFinalizedConfirmedTotal prometheus.Counter
rollupL2BatchesGasOraclerConfirmedTotal prometheus.Counter
rollupL2ChainMonitorLatestFailedCall prometheus.Counter
rollupL2ChainMonitorLatestFailedBatchStatus prometheus.Counter
}
var (
initL2RelayerMetricOnce sync.Once
l2RelayerMetric *l2RelayerMetrics
)
func initL2RelayerMetrics(reg prometheus.Registerer) *l2RelayerMetrics {
initL2RelayerMetricOnce.Do(func() {
l2RelayerMetric = &l2RelayerMetrics{
rollupL2RelayerProcessPendingBatchTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_pending_batch_total",
Help: "The total number of layer2 process pending batch",
}),
rollupL2RelayerProcessPendingBatchSuccessTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_pending_batch_success_total",
Help: "The total number of layer2 process pending success batch",
}),
rollupL2RelayerGasPriceOraclerRunTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_gas_price_oracler_total",
Help: "The total number of layer2 gas price oracler run total",
}),
rollupL2RelayerLastGasPrice: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "rollup_layer2_gas_price_latest_gas_price",
Help: "The latest gas price of rollup relayer l2",
}),
rollupL2RelayerProcessCommittedBatchesTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_committed_batches_total",
Help: "The total number of layer2 process committed batches run total",
}),
rollupL2RelayerProcessCommittedBatchesFinalizedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_committed_batches_finalized_total",
Help: "The total number of layer2 process committed batches finalized total",
}),
rollupL2RelayerProcessCommittedBatchesFinalizedSuccessTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_committed_batches_finalized_success_total",
Help: "The total number of layer2 process committed batches finalized success total",
}),
rollupL2BatchesCommittedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_committed_batches_confirmed_total",
Help: "The total number of layer2 process committed batches confirmed total",
}),
rollupL2BatchesFinalizedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_finalized_batches_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",
}),
rollupL2BatchesGasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_gras_oracler_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",
}),
rollupL2ChainMonitorLatestFailedCall: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_chain_monitor_latest_failed_batch_call",
Help: "The total number of failed call chain_monitor api",
}),
rollupL2ChainMonitorLatestFailedBatchStatus: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_chain_monitor_latest_failed_batch_status",
Help: "The total number of failed batch status get from chain_monitor",
}),
}
})
return l2RelayerMetric
}

View File

@@ -22,8 +22,8 @@ import (
"scroll-tech/database/migrate"
"scroll-tech/bridge/internal/controller/sender"
"scroll-tech/bridge/internal/orm"
"scroll-tech/rollup/internal/controller/sender"
"scroll-tech/rollup/internal/orm"
)
func setupL2RelayerDB(t *testing.T) *gorm.DB {

View File

@@ -13,7 +13,7 @@ import (
"scroll-tech/common/docker"
"scroll-tech/common/types"
"scroll-tech/bridge/internal/config"
"scroll-tech/rollup/internal/config"
)
var (
@@ -92,8 +92,6 @@ func TestFunctions(t *testing.T) {
// Run l1 relayer test cases.
t.Run("TestCreateNewL1Relayer", testCreateNewL1Relayer)
t.Run("TestL1RelayerProcessSaveEvents", testL1RelayerProcessSaveEvents)
t.Run("TestL1RelayerMsgConfirm", testL1RelayerMsgConfirm)
t.Run("TestL1RelayerGasOracleConfirm", testL1RelayerGasOracleConfirm)
t.Run("TestL1RelayerProcessGasPriceOracle", testL1RelayerProcessGasPriceOracle)

View File

@@ -16,7 +16,6 @@ func (s *Sender) estimateLegacyGas(auth *bind.TransactOpts, contract *common.Add
log.Error("estimateLegacyGas SuggestGasPrice failure", "error", err)
return nil, err
}
gasLimit, err := s.estimateGasLimit(auth, contract, input, gasPrice, nil, nil, value, minGasLimit)
if err != nil {
log.Error("estimateLegacyGas estimateGasLimit failure", "gasPrice", gasPrice, "error", err)
@@ -46,7 +45,10 @@ func (s *Sender) estimateDynamicGas(auth *bind.TransactOpts, contract *common.Ad
gasLimit, err := s.estimateGasLimit(auth, contract, input, nil, gasTipCap, gasFeeCap, value, minGasLimit)
if err != nil {
log.Error("estimateDynamicGas estimateGasLimit failure", "error", err)
return nil, err
if minGasLimit == 0 {
return nil, err
}
gasLimit = minGasLimit
}
return &FeeData{
gasLimit: gasLimit,
@@ -67,7 +69,7 @@ func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Addr
}
gasLimit, err := s.client.EstimateGas(s.ctx, msg)
if err != nil {
log.Error("estimateGasLimit EstimateGas failure", "msg", msg, "error", err)
log.Error("estimateGasLimit EstimateGas failure", "error", err)
return 0, err
}
if minGasLimit > gasLimit {

View File

@@ -33,59 +33,59 @@ func initSenderMetrics(reg prometheus.Registerer) *senderMetrics {
initSenderMetricOnce.Do(func() {
sm = &senderMetrics{
sendTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_send_transaction_total",
Name: "rollup_sender_send_transaction_total",
Help: "The total number of sending transaction.",
}, []string{"service", "name"}),
sendTransactionFailureFullTx: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_send_transaction_full_tx_failure_total",
Name: "rollup_sender_send_transaction_full_tx_failure_total",
Help: "The total number of sending transaction failure for full size tx.",
}, []string{"service", "name"}),
sendTransactionFailureRepeatTransaction: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_send_transaction_repeat_transaction_failure_total",
Name: "rollup_sender_send_transaction_repeat_transaction_failure_total",
Help: "The total number of sending transaction failure for repeat transaction.",
}, []string{"service", "name"}),
sendTransactionFailureGetFee: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_send_transaction_get_fee_failure_total",
Name: "rollup_sender_send_transaction_get_fee_failure_total",
Help: "The total number of sending transaction failure for getting fee.",
}, []string{"service", "name"}),
sendTransactionFailureSendTx: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_send_transaction_send_tx_failure_total",
Name: "rollup_sender_send_transaction_send_tx_failure_total",
Help: "The total number of sending transaction failure for sending tx.",
}, []string{"service", "name"}),
resubmitTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_send_transaction_resubmit_send_transaction_total",
Name: "rollup_sender_send_transaction_resubmit_send_transaction_total",
Help: "The total number of resubmit transaction.",
}, []string{"service", "name"}),
currentPendingTxsNum: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_pending_tx_count",
Name: "rollup_sender_pending_tx_count",
Help: "The pending tx count in the sender.",
}, []string{"service", "name"}),
currentGasFeeCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_gas_fee_cap",
Name: "rollup_sender_gas_fee_cap",
Help: "The gas fee of current transaction.",
}, []string{"service", "name"}),
currentGasTipCap: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_gas_tip_cap",
Name: "rollup_sender_gas_tip_cap",
Help: "The gas tip of current transaction.",
}, []string{"service", "name"}),
currentGasPrice: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_gas_price_cap",
Name: "rollup_sender_gas_price_cap",
Help: "The gas price of current transaction.",
}, []string{"service", "name"}),
currentGasLimit: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_gas_limit",
Name: "rollup_sender_gas_limit",
Help: "The gas limit of current transaction.",
}, []string{"service", "name"}),
currentNonce: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{
Name: "bridge_sender_nonce",
Name: "rollup_sender_nonce",
Help: "The nonce of current transaction.",
}, []string{"service", "name"}),
senderCheckPendingTransactionTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_check_pending_transaction_total",
Name: "rollup_sender_check_pending_transaction_total",
Help: "The total number of check pending transaction.",
}, []string{"service", "name"}),
senderCheckBalancerTotal: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
Name: "bridge_sender_check_balancer_total",
Name: "rollup_sender_check_balancer_total",
Help: "The total number of check balancer.",
}, []string{"service", "name"}),
}

View File

@@ -18,8 +18,8 @@ import (
"github.com/scroll-tech/go-ethereum/ethclient"
"github.com/scroll-tech/go-ethereum/log"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/utils"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/utils"
)
const (
@@ -56,15 +56,6 @@ type FeeData struct {
gasLimit uint64
}
func newEmptyFeeData() *FeeData {
return &FeeData{
gasFeeCap: big.NewInt(0),
gasTipCap: big.NewInt(0),
gasPrice: big.NewInt(0),
gasLimit: 0,
}
}
// PendingTransaction submitted but pending transactions
type PendingTransaction struct {
submitAt uint64
@@ -94,8 +85,6 @@ type Sender struct {
stopCh chan struct{}
metrics *senderMetrics
cachedMaxFeeData *FeeData // hacky way to avoid getFeeData error
}
// NewSender returns a new instance of transaction sender
@@ -140,20 +129,19 @@ func NewSender(ctx context.Context, config *config.SenderConfig, priv *ecdsa.Pri
}
sender := &Sender{
ctx: ctx,
config: config,
client: client,
chainID: chainID,
auth: auth,
minBalance: config.MinBalance,
confirmCh: make(chan *Confirmation, 128),
blockNumber: header.Number.Uint64(),
baseFeePerGas: baseFeePerGas,
pendingTxs: cmapV2.New[*PendingTransaction](),
stopCh: make(chan struct{}),
name: name,
service: service,
cachedMaxFeeData: newEmptyFeeData(),
ctx: ctx,
config: config,
client: client,
chainID: chainID,
auth: auth,
minBalance: config.MinBalance,
confirmCh: make(chan *Confirmation, 128),
blockNumber: header.Number.Uint64(),
baseFeePerGas: baseFeePerGas,
pendingTxs: cmapV2.New[*PendingTransaction](),
stopCh: make(chan struct{}),
name: name,
service: service,
}
sender.metrics = initSenderMetrics(reg)
@@ -201,26 +189,6 @@ func (s *Sender) getFeeData(auth *bind.TransactOpts, target *common.Address, val
return s.estimateLegacyGas(auth, target, value, data, minGasLimit)
}
func (s *Sender) cacheMaxFeeData(feeData *FeeData) {
if feeData == nil {
log.Error("cacheMaxFeeData", "err", "feeData must not be nil")
return
}
if feeData.gasFeeCap != nil && feeData.gasFeeCap.Cmp(s.cachedMaxFeeData.gasFeeCap) > 0 {
s.cachedMaxFeeData.gasFeeCap = feeData.gasFeeCap
}
if feeData.gasTipCap != nil && feeData.gasTipCap.Cmp(s.cachedMaxFeeData.gasTipCap) > 0 {
s.cachedMaxFeeData.gasTipCap = feeData.gasTipCap
}
if feeData.gasPrice != nil && feeData.gasPrice.Cmp(s.cachedMaxFeeData.gasPrice) > 0 {
s.cachedMaxFeeData.gasPrice = feeData.gasPrice
}
if feeData.gasLimit > s.cachedMaxFeeData.gasLimit {
s.cachedMaxFeeData.gasLimit = feeData.gasLimit
}
}
// SendTransaction send a signed L2tL1 transaction.
func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.Int, data []byte, minGasLimit uint64) (common.Hash, error) {
s.metrics.sendTransactionTotal.WithLabelValues(s.service, s.name).Inc()
@@ -250,12 +218,7 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I
if feeData, err = s.getFeeData(s.auth, target, value, data, minGasLimit); err != nil {
s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc()
log.Error("failed to get fee data", "err", err)
if s.cachedMaxFeeData.gasLimit == 0 { // if no MaxFeeData cached, and getFeeData fails
return common.Hash{}, fmt.Errorf("failed to get fee data for the first time, err: %w", err)
}
feeData = s.cachedMaxFeeData
} else {
s.cacheMaxFeeData(feeData)
return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err)
}
if tx, err = s.createAndSendTx(s.auth, feeData, target, value, data, nil); err != nil {
@@ -448,7 +411,6 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts,
}
log.Debug("Transaction gas adjustment details", txInfo)
s.cacheMaxFeeData(feeData)
nonce := tx.Nonce()
s.metrics.resubmitTransactionTotal.WithLabelValues(s.service, s.name).Inc()

View File

@@ -19,7 +19,7 @@ import (
"scroll-tech/common/docker"
"scroll-tech/bridge/internal/config"
"scroll-tech/rollup/internal/config"
)
const TXBatch = 50

View File

@@ -12,8 +12,8 @@ import (
"scroll-tech/common/types"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/orm"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/orm"
)
// BatchProposer proposes batches based on available unbatched chunks.
@@ -63,39 +63,39 @@ func NewBatchProposer(ctx context.Context, cfg *config.BatchProposerConfig, db *
gasCostIncreaseMultiplier: cfg.GasCostIncreaseMultiplier,
batchProposerCircleTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_circle_total",
Name: "rollup_propose_batch_circle_total",
Help: "Total number of propose batch total.",
}),
proposeBatchFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_failure_circle_total",
Name: "rollup_propose_batch_failure_circle_total",
Help: "Total number of propose batch total.",
}),
proposeBatchUpdateInfoTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_update_info_total",
Name: "rollup_propose_batch_update_info_total",
Help: "Total number of propose batch update info total.",
}),
proposeBatchUpdateInfoFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_update_info_failure_total",
Name: "rollup_propose_batch_update_info_failure_total",
Help: "Total number of propose batch update info failure total.",
}),
totalL1CommitGas: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_batch_total_l1_commit_gas",
Name: "rollup_propose_batch_total_l1_commit_gas",
Help: "The total l1 commit gas",
}),
totalL1CommitCalldataSize: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_batch_total_l1_call_data_size",
Name: "rollup_propose_batch_total_l1_call_data_size",
Help: "The total l1 call data size",
}),
batchChunksNum: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_batch_chunks_number",
Name: "rollup_propose_batch_chunks_number",
Help: "The number of chunks in the batch",
}),
batchFirstBlockTimeoutReached: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_first_block_timeout_reached_total",
Name: "rollup_propose_batch_first_block_timeout_reached_total",
Help: "Total times of batch's first block timeout reached",
}),
batchChunksProposeNotEnoughTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_batch_chunks_propose_not_enough_total",
Name: "rollup_propose_batch_chunks_propose_not_enough_total",
Help: "Total number of batch chunk propose not enough",
}),
}
@@ -122,7 +122,7 @@ func (p *BatchProposer) updateBatchInfoInDB(dbChunks []*orm.Chunk, batchMeta *ty
if numChunks <= 0 {
return nil
}
chunks, err := p.dbChunksToBridgeChunks(dbChunks)
chunks, err := p.dbChunksToRollupChunks(dbChunks)
if err != nil {
return err
}
@@ -269,7 +269,7 @@ func (p *BatchProposer) proposeBatchChunks() ([]*orm.Chunk, *types.BatchMeta, er
return nil, nil, nil
}
func (p *BatchProposer) dbChunksToBridgeChunks(dbChunks []*orm.Chunk) ([]*types.Chunk, error) {
func (p *BatchProposer) dbChunksToRollupChunks(dbChunks []*orm.Chunk) ([]*types.Chunk, error) {
chunks := make([]*types.Chunk, len(dbChunks))
for i, c := range dbChunks {
wrappedBlocks, err := p.l2BlockOrm.GetL2BlocksInRange(p.ctx, c.StartBlockNumber, c.EndBlockNumber)

View File

@@ -9,8 +9,8 @@ import (
"scroll-tech/common/database"
"scroll-tech/common/types"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/orm"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/orm"
)
// TODO: Add unit tests that the limits are enforced correctly.

View File

@@ -14,8 +14,8 @@ import (
"scroll-tech/common/types"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/orm"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/orm"
)
// maxNumBlockPerChunk is the maximum number of blocks we allow per chunk.
@@ -98,51 +98,51 @@ func NewChunkProposer(ctx context.Context, cfg *config.ChunkProposerConfig, db *
gasCostIncreaseMultiplier: cfg.GasCostIncreaseMultiplier,
chunkProposerCircleTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_circle_total",
Name: "rollup_propose_chunk_circle_total",
Help: "Total number of propose chunk total.",
}),
proposeChunkFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_failure_circle_total",
Name: "rollup_propose_chunk_failure_circle_total",
Help: "Total number of propose chunk failure total.",
}),
proposeChunkUpdateInfoTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_update_info_total",
Name: "rollup_propose_chunk_update_info_total",
Help: "Total number of propose chunk update info total.",
}),
proposeChunkUpdateInfoFailureTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_update_info_failure_total",
Name: "rollup_propose_chunk_update_info_failure_total",
Help: "Total number of propose chunk update info failure total.",
}),
chunkTxNum: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_tx_num",
Name: "rollup_propose_chunk_tx_num",
Help: "The chunk tx num",
}),
chunkEstimateL1CommitGas: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_estimate_l1_commit_gas",
Name: "rollup_propose_chunk_estimate_l1_commit_gas",
Help: "The chunk estimate l1 commit gas",
}),
totalL1CommitCalldataSize: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_total_l1_commit_call_data_size",
Name: "rollup_propose_chunk_total_l1_commit_call_data_size",
Help: "The total l1 commit call data size",
}),
totalTxGasUsed: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_total_tx_gas_used",
Name: "rollup_propose_chunk_total_tx_gas_used",
Help: "The total tx gas used",
}),
maxTxConsumption: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_max_tx_consumption",
Name: "rollup_propose_chunk_max_tx_consumption",
Help: "The max tx consumption",
}),
chunkBlocksNum: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_propose_chunk_chunk_block_number",
Name: "rollup_propose_chunk_chunk_block_number",
Help: "The number of blocks in the chunk",
}),
chunkFirstBlockTimeoutReached: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_first_block_timeout_reached_total",
Name: "rollup_propose_chunk_first_block_timeout_reached_total",
Help: "Total times of chunk's first block timeout reached",
}),
chunkBlocksProposeNotEnoughTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_propose_chunk_blocks_propose_not_enough_total",
Name: "rollup_propose_chunk_blocks_propose_not_enough_total",
Help: "Total number of chunk block propose not enough",
}),
}

View File

@@ -9,8 +9,8 @@ import (
"scroll-tech/common/database"
"scroll-tech/common/types"
"scroll-tech/bridge/internal/config"
"scroll-tech/bridge/internal/orm"
"scroll-tech/rollup/internal/config"
"scroll-tech/rollup/internal/orm"
)
// TODO: Add unit tests that the limits are enforced correctly.

View File

@@ -17,9 +17,9 @@ import (
"scroll-tech/common/types"
bridgeAbi "scroll-tech/bridge/abi"
"scroll-tech/bridge/internal/orm"
"scroll-tech/bridge/internal/utils"
bridgeAbi "scroll-tech/rollup/abi"
"scroll-tech/rollup/internal/orm"
"scroll-tech/rollup/internal/utils"
)
type rollupEvent struct {
@@ -39,9 +39,6 @@ type L1WatcherClient struct {
// The number of new blocks to wait for a block to be confirmed
confirmations rpc.BlockNumber
messengerAddress common.Address
messengerABI *abi.ABI
messageQueueAddress common.Address
messageQueueABI *abi.ABI
@@ -57,7 +54,7 @@ type L1WatcherClient struct {
}
// NewL1WatcherClient returns a new instance of L1WatcherClient.
func NewL1WatcherClient(ctx context.Context, client *ethclient.Client, startHeight uint64, confirmations rpc.BlockNumber, messengerAddress, messageQueueAddress, scrollChainAddress common.Address, db *gorm.DB, reg prometheus.Registerer) *L1WatcherClient {
func NewL1WatcherClient(ctx context.Context, client *ethclient.Client, startHeight uint64, confirmations rpc.BlockNumber, messageQueueAddress, scrollChainAddress common.Address, db *gorm.DB, reg prometheus.Registerer) *L1WatcherClient {
l1MessageOrm := orm.NewL1Message(db)
savedHeight, err := l1MessageOrm.GetLayer1LatestWatchedHeight()
if err != nil {
@@ -86,9 +83,6 @@ func NewL1WatcherClient(ctx context.Context, client *ethclient.Client, startHeig
batchOrm: orm.NewBatch(db),
confirmations: confirmations,
messengerAddress: messengerAddress,
messengerABI: bridgeAbi.L1ScrollMessengerABI,
messageQueueAddress: messageQueueAddress,
messageQueueABI: bridgeAbi.L1MessageQueueABI,
@@ -199,18 +193,15 @@ func (w *L1WatcherClient) FetchContractEvent() error {
FromBlock: big.NewInt(from), // inclusive
ToBlock: big.NewInt(to), // inclusive
Addresses: []common.Address{
w.messengerAddress,
w.scrollChainAddress,
w.messageQueueAddress,
},
Topics: make([][]common.Hash, 1),
}
query.Topics[0] = make([]common.Hash, 5)
query.Topics[0] = make([]common.Hash, 3)
query.Topics[0][0] = bridgeAbi.L1QueueTransactionEventSignature
query.Topics[0][1] = bridgeAbi.L1RelayedMessageEventSignature
query.Topics[0][2] = bridgeAbi.L1FailedRelayedMessageEventSignature
query.Topics[0][3] = bridgeAbi.L1CommitBatchEventSignature
query.Topics[0][4] = bridgeAbi.L1FinalizeBatchEventSignature
query.Topics[0][1] = bridgeAbi.L1CommitBatchEventSignature
query.Topics[0][2] = bridgeAbi.L1FinalizeBatchEventSignature
logs, err := w.client.FilterLogs(w.ctx, query)
if err != nil {

View File

@@ -26,31 +26,31 @@ func initL1WatcherMetrics(reg prometheus.Registerer) *l1WatcherMetrics {
initL1WatcherMetricOnce.Do(func() {
l1WatcherMetric = &l1WatcherMetrics{
l1WatcherFetchBlockHeaderTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_l1_watcher_fetch_block_header_total",
Name: "rollup_l1_watcher_fetch_block_header_total",
Help: "The total number of l1 watcher fetch block header total",
}),
l1WatcherFetchBlockHeaderProcessedBlockHeight: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_l1_watcher_fetch_block_header_processed_block_height",
Name: "rollup_l1_watcher_fetch_block_header_processed_block_height",
Help: "The current processed block height of l1 watcher fetch block header",
}),
l1WatcherFetchContractEventTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_l1_watcher_fetch_block_contract_event_total",
Name: "rollup_l1_watcher_fetch_block_contract_event_total",
Help: "The total number of l1 watcher fetch contract event total",
}),
l1WatcherFetchContractEventSuccessTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_l1_watcher_fetch_block_contract_event_success_total",
Name: "rollup_l1_watcher_fetch_block_contract_event_success_total",
Help: "The total number of l1 watcher fetch contract event success total",
}),
l1WatcherFetchContractEventProcessedBlockHeight: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "bridge_l1_watcher_fetch_block_contract_event_processed_block_height",
Name: "rollup_l1_watcher_fetch_block_contract_event_processed_block_height",
Help: "The current processed block height of l1 watcher fetch contract event",
}),
l1WatcherFetchContractEventSentEventsTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_l1_watcher_fetch_block_contract_event_sent_event_total",
Name: "rollup_l1_watcher_fetch_block_contract_event_sent_event_total",
Help: "The current processed block height of l1 watcher fetch contract sent event",
}),
l1WatcherFetchContractEventRollupEventsTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "bridge_l1_watcher_fetch_block_contract_event_rollup_event_total",
Name: "rollup_l1_watcher_fetch_block_contract_event_rollup_event_total",
Help: "The current processed block height of l1 watcher fetch contract rollup event",
}),
}

View File

@@ -20,9 +20,9 @@ import (
"scroll-tech/common/database"
commonTypes "scroll-tech/common/types"
bridgeAbi "scroll-tech/bridge/abi"
"scroll-tech/bridge/internal/orm"
"scroll-tech/bridge/internal/utils"
bridgeAbi "scroll-tech/rollup/abi"
"scroll-tech/rollup/internal/orm"
"scroll-tech/rollup/internal/utils"
)
func setupL1Watcher(t *testing.T) (*L1WatcherClient, *gorm.DB) {
@@ -30,8 +30,7 @@ func setupL1Watcher(t *testing.T) (*L1WatcherClient, *gorm.DB) {
client, err := ethclient.Dial(base.L1gethImg.Endpoint())
assert.NoError(t, err)
l1Cfg := cfg.L1Config
watcher := NewL1WatcherClient(context.Background(), client, l1Cfg.StartHeight, l1Cfg.Confirmations, l1Cfg.L1MessengerAddress,
l1Cfg.L1MessageQueueAddress, l1Cfg.RelayerConfig.RollupContractAddress, db, nil)
watcher := NewL1WatcherClient(context.Background(), client, l1Cfg.StartHeight, l1Cfg.Confirmations, l1Cfg.L1MessageQueueAddress, l1Cfg.RelayerConfig.RollupContractAddress, db, nil)
assert.NoError(t, watcher.FetchContractEvent())
return watcher, db
}

View File

@@ -19,9 +19,9 @@ import (
"scroll-tech/common/types"
bridgeAbi "scroll-tech/bridge/abi"
"scroll-tech/bridge/internal/orm"
"scroll-tech/bridge/internal/utils"
bridgeAbi "scroll-tech/rollup/abi"
"scroll-tech/rollup/internal/orm"
"scroll-tech/rollup/internal/utils"
)
// L2WatcherClient provide APIs which support others to subscribe to various event from l2geth
@@ -116,7 +116,7 @@ func (w *L2WatcherClient) TryFetchRunningMissingBlocks(blockHeight uint64) {
return
}
w.metrics.fetchRunningMissingBlocksHeight.Set(float64(to))
w.metrics.bridgeL2BlocksFetchedGap.Set(float64(blockHeight - to))
w.metrics.rollupL2BlocksFetchedGap.Set(float64(blockHeight - to))
}
}
@@ -246,7 +246,7 @@ func (w *L2WatcherClient) FetchContractEvent() {
}
relayedMessageCount := int64(len(relayedMessageEvents))
w.metrics.bridgeL2MsgsRelayedEventsTotal.Add(float64(relayedMessageCount))
w.metrics.rollupL2MsgsRelayedEventsTotal.Add(float64(relayedMessageCount))
log.Info("L2 events types", "RelayedMessageCount", relayedMessageCount)
// Update relayed message first to make sure we don't forget to update submited message.

Some files were not shown because too many files have changed in this diff Show More