mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-12 15:38:18 -05:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ed3d68fc3 | ||
|
|
2847d02498 | ||
|
|
a7d9bf3488 | ||
|
|
255eb5f307 | ||
|
|
0955382aec | ||
|
|
07961f751e | ||
|
|
bbd5a5a9c2 | ||
|
|
2e1f42fcb6 | ||
|
|
bcdbe1f119 | ||
|
|
6034c43bb1 |
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -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 or have you added `bump-version` tag to this PR?
|
||||
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
|
||||
|
||||
9
.github/workflows/bump_version.yml
vendored
9
.github/workflows/bump_version.yml
vendored
@@ -3,11 +3,16 @@ name: Bump Version
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ develop ]
|
||||
types: [ labeled ]
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
try-to-bump:
|
||||
if: ${{ github.event.label.name == 'bump-version' }}
|
||||
if: contains(github.event.pull_request.labels.*.name, 'bump-version')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
21
.github/workflows/docker.yaml
vendored
21
.github/workflows/docker.yaml
vendored
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ mock_abi:
|
||||
bridge_bins: ## Builds the Bridge 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 +19,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 +35,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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package main
|
||||
|
||||
import "scroll-tech/bridge/cmd/msg_relayer/app"
|
||||
|
||||
func main() {
|
||||
app.Run()
|
||||
}
|
||||
@@ -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,7 +59,6 @@
|
||||
"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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -66,7 +64,6 @@ type RelayerConfig struct {
|
||||
// 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:"-"`
|
||||
@@ -106,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"`
|
||||
@@ -120,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)
|
||||
@@ -148,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))
|
||||
|
||||
@@ -6,10 +6,6 @@ const (
|
||||
gasPriceDiffPrecision = 1000000
|
||||
|
||||
defaultGasPriceDiff = 50000 // 5%
|
||||
|
||||
defaultL1MessageRelayMinGasLimit = 130000 // should be enough for both ERC20 and ETH relay
|
||||
|
||||
defaultL2MessageRelayMinGasLimit = 200000
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -8,7 +8,6 @@ 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"
|
||||
@@ -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,54 +78,6 @@ 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()
|
||||
@@ -209,22 +136,6 @@ 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()
|
||||
if !cfm.IsSuccessful {
|
||||
|
||||
@@ -22,33 +22,6 @@ import (
|
||||
"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",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func setupL1RelayerDB(t *testing.T) *gorm.DB {
|
||||
db, err := database.InitDB(cfg.DBConfig)
|
||||
assert.NoError(t, err)
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -646,8 +625,6 @@ 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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func testCreateNewWatcherAndStop(t *testing.T) {
|
||||
|
||||
l1cfg := cfg.L1Config
|
||||
l1cfg.RelayerConfig.SenderConfig.Confirmations = rpc.LatestBlockNumber
|
||||
newSender, err := sender.NewSender(context.Background(), l1cfg.RelayerConfig.SenderConfig, l1cfg.RelayerConfig.MessageSenderPrivateKey, "test", "test", nil)
|
||||
newSender, err := sender.NewSender(context.Background(), l1cfg.RelayerConfig.SenderConfig, l1cfg.RelayerConfig.GasOracleSenderPrivateKey, "test", "test", nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create several transactions and commit to block
|
||||
@@ -72,7 +72,7 @@ func testFetchRunningMissingBlocks(t *testing.T) {
|
||||
_, db := setupL2Watcher(t)
|
||||
defer database.CloseDB(db)
|
||||
|
||||
auth := prepareAuth(t, l2Cli, cfg.L2Config.RelayerConfig.MessageSenderPrivateKey)
|
||||
auth := prepareAuth(t, l2Cli, cfg.L2Config.RelayerConfig.GasOracleSenderPrivateKey)
|
||||
|
||||
// deploy mock bridge
|
||||
_, tx, _, err := mock_bridge.DeployMockBridgeL2(auth, l2Cli)
|
||||
|
||||
@@ -36,17 +36,9 @@ var (
|
||||
l1Auth *bind.TransactOpts
|
||||
l2Auth *bind.TransactOpts
|
||||
|
||||
// l1 messenger contract
|
||||
l1MessengerInstance *mock_bridge.MockBridgeL1
|
||||
l1MessengerAddress common.Address
|
||||
|
||||
// l1 rollup contract
|
||||
scrollChainInstance *mock_bridge.MockBridgeL1
|
||||
scrollChainAddress common.Address
|
||||
|
||||
// l2 messenger contract
|
||||
l2MessengerInstance *mock_bridge.MockBridgeL2
|
||||
l2MessengerAddress common.Address
|
||||
)
|
||||
|
||||
func setupDB(t *testing.T) *gorm.DB {
|
||||
@@ -87,10 +79,10 @@ func setupEnv(t *testing.T) {
|
||||
l2Cfg.Confirmations = 0
|
||||
l2Cfg.RelayerConfig.SenderConfig.Confirmations = 0
|
||||
|
||||
l1Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.MessageSenderPrivateKey, base.L1gethImg.ChainID())
|
||||
l1Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.CommitSenderPrivateKey, base.L1gethImg.ChainID())
|
||||
assert.NoError(t, err)
|
||||
|
||||
l2Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L1Config.RelayerConfig.MessageSenderPrivateKey, base.L2gethImg.ChainID())
|
||||
l2Auth, err = bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L1Config.RelayerConfig.GasOracleSenderPrivateKey, base.L2gethImg.ChainID())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -115,36 +107,16 @@ func prepareContracts(t *testing.T) {
|
||||
var err error
|
||||
var tx *types.Transaction
|
||||
|
||||
// L1 messenger contract
|
||||
_, tx, l1MessengerInstance, err = mock_bridge.DeployMockBridgeL1(l1Auth, l1Client)
|
||||
assert.NoError(t, err)
|
||||
l1MessengerAddress, err = bind.WaitDeployed(context.Background(), l1Client, tx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// L1 ScrolChain contract
|
||||
_, tx, scrollChainInstance, err = mock_bridge.DeployMockBridgeL1(l1Auth, l1Client)
|
||||
assert.NoError(t, err)
|
||||
scrollChainAddress, err = bind.WaitDeployed(context.Background(), l1Client, tx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// L2 messenger contract
|
||||
_, tx, l2MessengerInstance, err = mock_bridge.DeployMockBridgeL2(l2Auth, l2Client)
|
||||
assert.NoError(t, err)
|
||||
l2MessengerAddress, err = bind.WaitDeployed(context.Background(), l2Client, tx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
l1Config, l2Config := bridgeApp.Config.L1Config, bridgeApp.Config.L2Config
|
||||
l1Config.L1MessengerAddress = l1MessengerAddress
|
||||
l1Config.L1MessageQueueAddress = l1MessengerAddress
|
||||
l1Config.ScrollChainContractAddress = scrollChainAddress
|
||||
l1Config.RelayerConfig.MessengerContractAddress = l2MessengerAddress
|
||||
l1Config.RelayerConfig.GasPriceOracleContractAddress = l1MessengerAddress
|
||||
|
||||
l2Config.L2MessengerAddress = l2MessengerAddress
|
||||
l2Config.L2MessageQueueAddress = l2MessengerAddress
|
||||
l2Config.RelayerConfig.MessengerContractAddress = l1MessengerAddress
|
||||
l2Config.RelayerConfig.RollupContractAddress = scrollChainAddress
|
||||
l2Config.RelayerConfig.GasPriceOracleContractAddress = l2MessengerAddress
|
||||
}
|
||||
|
||||
func TestFunction(t *testing.T) {
|
||||
@@ -161,7 +133,6 @@ func TestFunction(t *testing.T) {
|
||||
t.Run("TestCommitBatchAndFinalizeBatch", testCommitBatchAndFinalizeBatch)
|
||||
|
||||
// l1 message
|
||||
t.Run("TestRelayL1MessageSucceed", testRelayL1MessageSucceed)
|
||||
|
||||
// l2 message
|
||||
// TODO: add a "user relay l2msg Succeed" test
|
||||
|
||||
@@ -32,8 +32,7 @@ func testImportL1GasPrice(t *testing.T) {
|
||||
// Create L1Watcher
|
||||
startHeight, err := l1Client.BlockNumber(context.Background())
|
||||
assert.NoError(t, err)
|
||||
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, startHeight-1, 0,
|
||||
l1Cfg.L1MessengerAddress, l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db, nil)
|
||||
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, startHeight-1, 0, l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db, nil)
|
||||
|
||||
// fetch new blocks
|
||||
number, err := l1Client.BlockNumber(context.Background())
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
|
||||
_ "scroll-tech/bridge/cmd/event_watcher/app"
|
||||
_ "scroll-tech/bridge/cmd/gas_oracle/app"
|
||||
_ "scroll-tech/bridge/cmd/msg_relayer/app"
|
||||
_ "scroll-tech/bridge/cmd/rollup_relayer/app"
|
||||
|
||||
"scroll-tech/common/database"
|
||||
@@ -23,7 +22,6 @@ func testProcessStart(t *testing.T) {
|
||||
|
||||
bridgeApp.RunApp(t, cutils.EventWatcherApp)
|
||||
bridgeApp.RunApp(t, cutils.GasOracleApp)
|
||||
bridgeApp.RunApp(t, cutils.MessageRelayerApp)
|
||||
bridgeApp.RunApp(t, cutils.RollupRelayerApp)
|
||||
|
||||
bridgeApp.WaitExit()
|
||||
@@ -43,11 +41,6 @@ func testProcessStartEnableMetrics(t *testing.T) {
|
||||
svrPort = strconv.FormatInt(port.Int64()+50000, 10)
|
||||
bridgeApp.RunApp(t, cutils.GasOracleApp, "--metrics", "--metrics.addr", "localhost", "--metrics.port", svrPort)
|
||||
|
||||
port, err = rand.Int(rand.Reader, big.NewInt(2000))
|
||||
assert.NoError(t, err)
|
||||
svrPort = strconv.FormatInt(port.Int64()+50000, 10)
|
||||
bridgeApp.RunApp(t, cutils.MessageRelayerApp, "--metrics", "--metrics.addr", "localhost", "--metrics.port", svrPort)
|
||||
|
||||
port, err = rand.Int(rand.Reader, big.NewInt(2000))
|
||||
assert.NoError(t, err)
|
||||
svrPort = strconv.FormatInt(port.Int64()+50000, 10)
|
||||
|
||||
@@ -33,8 +33,7 @@ func testCommitBatchAndFinalizeBatch(t *testing.T) {
|
||||
|
||||
// Create L1Watcher
|
||||
l1Cfg := bridgeApp.Config.L1Config
|
||||
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, 0, l1Cfg.Confirmations, l1Cfg.L1MessengerAddress,
|
||||
l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db, nil)
|
||||
l1Watcher := watcher.NewL1WatcherClient(context.Background(), l1Client, 0, l1Cfg.Confirmations, l1Cfg.L1MessageQueueAddress, l1Cfg.ScrollChainContractAddress, db, nil)
|
||||
|
||||
// add some blocks to db
|
||||
var wrappedBlocks []*types.WrappedBlock
|
||||
|
||||
@@ -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"]
|
||||
@@ -1,5 +0,0 @@
|
||||
assets/
|
||||
docs/
|
||||
l2geth/
|
||||
rpc-gateway/
|
||||
*target/*
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var tag = "v4.2.14"
|
||||
var tag = "v4.2.15"
|
||||
|
||||
var commit = func() string {
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"scroll-tech/common/bytecode/erc20"
|
||||
@@ -28,8 +29,10 @@ func TestERC20(t *testing.T) {
|
||||
|
||||
token, err := erc20.NewERC20Mock(erc20Address, l2Cli)
|
||||
assert.NoError(t, err)
|
||||
privKey, err := crypto.ToECDSA(common.FromHex("1212121212121212121212121212121212121212121212121212121212121212"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.MessageSenderPrivateKey, base.L2gethImg.ChainID())
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(privKey, base.L2gethImg.ChainID())
|
||||
assert.NoError(t, err)
|
||||
|
||||
authBls0, err := token.BalanceOf(nil, auth.From)
|
||||
@@ -60,7 +63,7 @@ func TestGreeter(t *testing.T) {
|
||||
l2Cli, err := base.L2Client()
|
||||
assert.Nil(t, err)
|
||||
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.MessageSenderPrivateKey, base.L2gethImg.ChainID())
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(bridgeApp.Config.L2Config.RelayerConfig.CommitSenderPrivateKey, base.L2gethImg.ChainID())
|
||||
assert.NoError(t, err)
|
||||
|
||||
token, err := greeter.NewGreeter(greeterAddress, l2Cli)
|
||||
|
||||
Reference in New Issue
Block a user