Compare commits

..

2 Commits

Author SHA1 Message Date
Xi Lin
92e70432e4 feat(bridge): only update gas price oracle for exceeding diff threshold (#319) 2023-02-23 19:14:29 +08:00
HAOYUatHZ
6f3eddf773 fix(config): fix typos (#315) 2023-02-23 12:50:09 +08:00
6 changed files with 113 additions and 39 deletions

View File

@@ -20,6 +20,10 @@
"tx_type": "LegacyTx",
"min_balance": 100000000000000000000
},
"gas_oracle_config": {
"min_gas_price": 0,
"gas_price_diff": 50000
},
"message_sender_private_keys": [
"1212121212121212121212121212121212121212121212121212121212121212"
],
@@ -48,6 +52,10 @@
"tx_type": "LegacyTx",
"min_balance": 100000000000000000000
},
"gas_oracle_config": {
"min_gas_price": 0,
"gas_price_diff": 50000
},
"message_sender_private_keys": [
"1212121212121212121212121212121212121212121212121212121212121212"
],

View File

@@ -42,15 +42,25 @@ type RelayerConfig struct {
// 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_proce_oracle_contract_address"`
GasPriceOracleContractAddress common.Address `json:"gas_price_oracle_contract_address"`
// sender config
SenderConfig *SenderConfig `json:"sender_config"`
// gas oracle config
GasOracleConfig *GasOracleConfig `json:"gas_oracle_config"`
// The private key of the relayer
MessageSenderPrivateKeys []*ecdsa.PrivateKey `json:"-"`
GasOracleSenderPrivateKeys []*ecdsa.PrivateKey `json:"-"`
RollupSenderPrivateKeys []*ecdsa.PrivateKey `json:"-"`
}
// GasOracleConfig The config for updating gas price oracle.
type GasOracleConfig struct {
// MinGasPrice store the minimum gas price to set.
MinGasPrice uint64 `json:"min_gas_price"`
// GasPriceDiff store the percentage of gas price difference.
GasPriceDiff uint64 `json:"gas_price_diff"`
}
// relayerConfigAlias RelayerConfig alias name
type relayerConfigAlias RelayerConfig

View File

@@ -22,6 +22,12 @@ import (
"scroll-tech/bridge/sender"
)
const (
gasPriceDiffPrecision = 1000000
defaultGasPriceDiff = 50000 // 5%
)
// Layer1Relayer is responsible for
// 1. fetch pending L1Message from db
// 2. relay pending message to layer 2 node
@@ -43,6 +49,10 @@ type Layer1Relayer struct {
gasOracleCh <-chan *sender.Confirmation
l1GasOracleABI *abi.ABI
lastGasPrice uint64
minGasPrice uint64
gasPriceDiff uint64
stopCh chan struct{}
}
@@ -63,6 +73,16 @@ func NewLayer1Relayer(ctx context.Context, db database.OrmFactory, cfg *config.R
return nil, err
}
var minGasPrice uint64
var gasPriceDiff uint64
if cfg.GasOracleConfig != nil {
minGasPrice = cfg.GasOracleConfig.MinGasPrice
gasPriceDiff = cfg.GasOracleConfig.GasPriceDiff
} else {
minGasPrice = 0
gasPriceDiff = defaultGasPriceDiff
}
return &Layer1Relayer{
ctx: ctx,
db: db,
@@ -75,6 +95,9 @@ func NewLayer1Relayer(ctx context.Context, db database.OrmFactory, cfg *config.R
gasOracleCh: gasOracleSender.ConfirmChan(),
l1GasOracleABI: bridge_abi.L1GasPriceOracleABI,
minGasPrice: minGasPrice,
gasPriceDiff: gasPriceDiff,
cfg: cfg,
stopCh: make(chan struct{}),
}, nil
@@ -147,25 +170,31 @@ func (r *Layer1Relayer) ProcessGasPriceOracle() {
block := blocks[0]
if block.GasOracleStatus == types.GasOraclePending {
baseFee := big.NewInt(int64(block.BaseFee))
data, err := r.l1GasOracleABI.Pack("setL1BaseFee", baseFee)
if err != nil {
log.Error("Failed to pack setL1BaseFee", "block.Hash", block.Hash, "block.Height", block.Number, "block.BaseFee", block.BaseFee, "err", err)
return
}
hash, err := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data)
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) {
log.Error("Failed to send setL1BaseFee tx to layer2 ", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
expectedDelta := r.lastGasPrice * r.gasPriceDiff / gasPriceDiffPrecision
// last is undefine or (block.BaseFee >= minGasPrice && exceed diff)
if r.lastGasPrice == 0 || (block.BaseFee >= r.minGasPrice && (block.BaseFee >= r.lastGasPrice+expectedDelta || block.BaseFee <= r.lastGasPrice-expectedDelta)) {
baseFee := big.NewInt(int64(block.BaseFee))
data, err := r.l1GasOracleABI.Pack("setL1BaseFee", baseFee)
if err != nil {
log.Error("Failed to pack setL1BaseFee", "block.Hash", block.Hash, "block.Height", block.Number, "block.BaseFee", block.BaseFee, "err", err)
return
}
return
}
err = r.db.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, block.Hash, types.GasOracleImporting, hash.String())
if err != nil {
log.Error("UpdateGasOracleStatusAndOracleTxHash failed", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
return
hash, err := r.gasOracleSender.SendTransaction(block.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data)
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) {
log.Error("Failed to send setL1BaseFee tx to layer2 ", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
}
return
}
err = r.db.UpdateL1GasOracleStatusAndOracleTxHash(r.ctx, block.Hash, types.GasOracleImporting, hash.String())
if err != nil {
log.Error("UpdateGasOracleStatusAndOracleTxHash failed", "block.Hash", block.Hash, "block.Height", block.Number, "err", err)
return
}
r.lastGasPrice = block.BaseFee
log.Info("Update l1 base fee", "txHash", hash.String(), "baseFee", baseFee)
}
}
}

View File

@@ -157,7 +157,7 @@ func (p *BatchProposer) recoverBatchDataBuffer() {
}
blockBatches, err := p.orm.GetBlockBatches(map[string]interface{}{"hash": batchHash})
if err != nil || len(blockBatches) == 0 {
return nil, err //
return nil, err
}
blockBatchCache[batchHash] = blockBatches[0]
return blockBatches[0], nil
@@ -249,7 +249,6 @@ func (p *BatchProposer) tryCommitBatches() {
break
}
}
log.Info("tryCommitBatches", "calldataByteLen", calldataByteLen, "p.commitCalldataSizeLimit", p.commitCalldataSizeLimit)
if !commit {
return
}

View File

@@ -29,6 +29,12 @@ import (
"scroll-tech/bridge/utils"
)
const (
gasPriceDiffPrecision = 1000000
defaultGasPriceDiff = 50000 // 5%
)
// Layer2Relayer is responsible for
// 1. Committing and finalizing L2 blocks on L1
// 2. Relaying messages from L2 to L1
@@ -55,6 +61,10 @@ type Layer2Relayer struct {
gasOracleCh <-chan *sender.Confirmation
l2GasOracleABI *abi.ABI
lastGasPrice uint64
minGasPrice uint64
gasPriceDiff uint64
// A list of processing message.
// key(string): confirmation ID, value(string): layer2 hash.
processingMessage sync.Map
@@ -91,6 +101,16 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db databa
return nil, err
}
var minGasPrice uint64
var gasPriceDiff uint64
if cfg.GasOracleConfig != nil {
minGasPrice = cfg.GasOracleConfig.MinGasPrice
gasPriceDiff = cfg.GasOracleConfig.GasPriceDiff
} else {
minGasPrice = 0
gasPriceDiff = defaultGasPriceDiff
}
return &Layer2Relayer{
ctx: ctx,
db: db,
@@ -109,6 +129,9 @@ func NewLayer2Relayer(ctx context.Context, l2Client *ethclient.Client, db databa
gasOracleCh: gasOracleSender.ConfirmChan(),
l2GasOracleABI: bridge_abi.L2GasPriceOracleABI,
minGasPrice: minGasPrice,
gasPriceDiff: gasPriceDiff,
cfg: cfg,
processingMessage: sync.Map{},
processingBatchesCommitment: sync.Map{},
@@ -238,25 +261,32 @@ func (r *Layer2Relayer) ProcessGasPriceOracle() {
log.Error("Failed to fetch SuggestGasPrice from l2geth", "err", err)
return
}
suggestGasPriceUint64 := uint64(suggestGasPrice.Int64())
expectedDelta := r.lastGasPrice * r.gasPriceDiff / gasPriceDiffPrecision
data, err := r.l2GasOracleABI.Pack("setL2BaseFee", suggestGasPrice)
if err != nil {
log.Error("Failed to pack setL2BaseFee", "batch.Hash", batch.Hash, "block.BaseFee", suggestGasPrice.Uint64(), "err", err)
return
}
hash, err := r.gasOracleSender.SendTransaction(batch.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data)
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) {
log.Error("Failed to send setL2BaseFee tx to layer2 ", "batch.Hash", batch.Hash, "err", err)
// last is undefine or (suggestGasPriceUint64 >= minGasPrice && exceed diff)
if r.lastGasPrice == 0 || (suggestGasPriceUint64 >= r.minGasPrice && (suggestGasPriceUint64 >= r.lastGasPrice+expectedDelta || suggestGasPriceUint64 <= r.lastGasPrice-expectedDelta)) {
data, err := r.l2GasOracleABI.Pack("setL2BaseFee", suggestGasPrice)
if err != nil {
log.Error("Failed to pack setL2BaseFee", "batch.Hash", batch.Hash, "GasPrice", suggestGasPrice.Uint64(), "err", err)
return
}
return
}
err = r.db.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, batch.Hash, types.GasOracleImporting, hash.String())
if err != nil {
log.Error("UpdateGasOracleStatusAndOracleTxHash failed", "batch.Hash", batch.Hash, "err", err)
return
hash, err := r.gasOracleSender.SendTransaction(batch.Hash, &r.cfg.GasPriceOracleContractAddress, big.NewInt(0), data)
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) {
log.Error("Failed to send setL2BaseFee tx to layer2 ", "batch.Hash", batch.Hash, "err", err)
}
return
}
err = r.db.UpdateL2GasOracleStatusAndOracleTxHash(r.ctx, batch.Hash, types.GasOracleImporting, hash.String())
if err != nil {
log.Error("UpdateGasOracleStatusAndOracleTxHash failed", "batch.Hash", batch.Hash, "err", err)
return
}
r.lastGasPrice = suggestGasPriceUint64
log.Info("Update l2 gas price", "txHash", hash.String(), "GasPrice", suggestGasPrice)
}
}
}
@@ -285,7 +315,6 @@ func (r *Layer2Relayer) SendCommitTx(batchData []*types.BatchData) error {
// generate a unique txID and send transaction
var bytes []byte
for _, batch := range batchData {
log.Info("!!!!!", "BatchIndex", batch.Batch.BatchIndex, "BatchHash", batch.Hash().String(), "ParentBatchHash", batch.Batch.ParentBatchHash.String(), "PrevStateRoot", batch.Batch.PrevStateRoot.String(), "NewStateRoot", batch.Batch.NewStateRoot.String())
bytes = append(bytes, batch.Hash().Bytes()...)
}
txID := crypto.Keccak256Hash(bytes).String()
@@ -293,7 +322,6 @@ func (r *Layer2Relayer) SendCommitTx(batchData []*types.BatchData) error {
if err != nil {
if !errors.Is(err, sender.ErrNoAvailableAccount) {
log.Error("Failed to send commitBatches tx to layer1 ", "err", err)
fmt.Printf("Calldata = %v\n", common.Bytes2Hex(calldata))
}
return err
}

View File

@@ -5,7 +5,7 @@ import (
"runtime/debug"
)
var tag = "alpha-v1.6"
var tag = "alpha-v1.8"
var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {