Skip to content

Commit

Permalink
Merge branch 'develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmountaintop authored Jan 22, 2024
2 parents 1bdf46c + 44c5f1c commit 7c37655
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 58 deletions.
2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v4.3.54"
var tag = "v4.3.55"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down
4 changes: 2 additions & 2 deletions rollup/cmd/mock_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ func (b *MockApp) MockConfig(store bool) error {
}

cfg.L1Config.Endpoint = base.L1gethImg.Endpoint()
cfg.L2Config.RelayerConfig.SenderConfig.Endpoint = base.L1gethImg.Endpoint()
cfg.L2Config.Endpoint = base.L2gethImg.Endpoint()
cfg.L1Config.RelayerConfig.SenderConfig.Endpoint = base.L2gethImg.Endpoint()
cfg.L2Config.Endpoint = base.L2gethImg.Endpoint()
cfg.L2Config.RelayerConfig.SenderConfig.Endpoint = base.L1gethImg.Endpoint()
cfg.DBConfig.DSN = base.DBImg.Endpoint()
b.Config = cfg

Expand Down
10 changes: 5 additions & 5 deletions rollup/conf/config.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"l1_config": {
"confirmations": "0x6",
"endpoint": "DUMMY_ENDPOINT",
"endpoint": "https://rpc.ankr.com/eth",
"l1_message_queue_address": "0x0000000000000000000000000000000000000000",
"scroll_chain_address": "0x0000000000000000000000000000000000000000",
"start_height": 0,
"relayer_config": {
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
"sender_config": {
"endpoint": "https://sepolia-rpc.scroll.io",
"endpoint": "https://rpc.scroll.io",
"check_pending_time": 2,
"check_balance_time": 100,
"escalate_blocks": 100,
Expand All @@ -29,22 +29,22 @@
},
"l2_config": {
"confirmations": "0x1",
"endpoint": "https://sepolia-rpc.scroll.io",
"endpoint": "https://rpc.scroll.io",
"l2_messenger_address": "0x0000000000000000000000000000000000000000",
"l2_message_queue_address": "0x0000000000000000000000000000000000000000",
"relayer_config": {
"rollup_contract_address": "0x0000000000000000000000000000000000000000",
"gas_price_oracle_address": "0x0000000000000000000000000000000000000000",
"sender_config": {
"endpoint": "https://sepolia-rpc.scroll.io",
"endpoint": "https://rpc.ankr.com/eth",
"check_pending_time": 10,
"check_balance_time": 100,
"escalate_blocks": 100,
"confirmations": "0x6",
"escalate_multiple_num": 11,
"escalate_multiple_den": 10,
"max_gas_price": 10000000000,
"tx_type": "LegacyTx",
"tx_type": "DynamicFeeTx",
"min_balance": 100000000000000000000,
"pending_limit": 10
},
Expand Down
5 changes: 5 additions & 0 deletions rollup/internal/controller/relayer/relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/ethclient"
"github.com/scroll-tech/go-ethereum/log"
"github.com/stretchr/testify/assert"

"scroll-tech/common/database"
Expand Down Expand Up @@ -40,6 +41,10 @@ var (
)

func setupEnv(t *testing.T) {
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.LogfmtFormat()))
glogger.Verbosity(log.LvlInfo)
log.Root().SetHandler(glogger)

// Load config.
var err error
cfg, err = config.NewConfig("../../../conf/config.json")
Expand Down
57 changes: 37 additions & 20 deletions rollup/internal/controller/sender/estimategas.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,21 @@ import (
"sync/atomic"

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

func (s *Sender) estimateLegacyGas(auth *bind.TransactOpts, contract *common.Address, value *big.Int, input []byte, fallbackGasLimit uint64) (*FeeData, error) {
func (s *Sender) estimateLegacyGas(contract *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
gasPrice, err := s.client.SuggestGasPrice(s.ctx)
if err != nil {
log.Error("estimateLegacyGas SuggestGasPrice failure", "error", err)
return nil, err
}
gasLimit, _, err := s.estimateGasLimit(auth, contract, input, gasPrice, nil, nil, value, false)
gasLimit, _, err := s.estimateGasLimit(contract, data, gasPrice, nil, nil, value, false)
if err != nil {
log.Error("estimateLegacyGas estimateGasLimit failure", "gas price", gasPrice, "from", auth.From.Hex(),
"nonce", auth.Nonce.Uint64(), "contract address", contract.Hex(), "fallback gas limit", fallbackGasLimit, "error", err)
log.Error("estimateLegacyGas estimateGasLimit failure", "gas price", gasPrice, "from", s.auth.From.Hex(),
"nonce", s.auth.Nonce.Uint64(), "contract address", contract.Hex(), "fallback gas limit", fallbackGasLimit, "error", err)
if fallbackGasLimit == 0 {
return nil, err
}
Expand All @@ -35,7 +34,7 @@ func (s *Sender) estimateLegacyGas(auth *bind.TransactOpts, contract *common.Add
}, nil
}

func (s *Sender) estimateDynamicGas(auth *bind.TransactOpts, contract *common.Address, value *big.Int, input []byte, fallbackGasLimit uint64) (*FeeData, error) {
func (s *Sender) estimateDynamicGas(contract *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
gasTipCap, err := s.client.SuggestGasTipCap(s.ctx)
if err != nil {
log.Error("estimateDynamicGas SuggestGasTipCap failure", "error", err)
Expand All @@ -50,10 +49,10 @@ func (s *Sender) estimateDynamicGas(auth *bind.TransactOpts, contract *common.Ad
gasTipCap,
new(big.Int).Mul(baseFee, big.NewInt(2)),
)
gasLimit, accessList, err := s.estimateGasLimit(auth, contract, input, nil, gasTipCap, gasFeeCap, value, true)
gasLimit, accessList, err := s.estimateGasLimit(contract, data, nil, gasTipCap, gasFeeCap, value, true)
if err != nil {
log.Error("estimateDynamicGas estimateGasLimit failure",
"from", auth.From.Hex(), "nonce", auth.Nonce.Uint64(), "contract address", contract.Hex(),
"from", s.auth.From.Hex(), "nonce", s.auth.Nonce.Uint64(), "contract address", contract.Hex(),
"fallback gas limit", fallbackGasLimit, "error", err)
if fallbackGasLimit == 0 {
return nil, err
Expand All @@ -73,15 +72,15 @@ func (s *Sender) estimateDynamicGas(auth *bind.TransactOpts, contract *common.Ad
return feeData, nil
}

func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Address, input []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int, useAccessList bool) (uint64, *types.AccessList, error) {
func (s *Sender) estimateGasLimit(contract *common.Address, data []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int, useAccessList bool) (uint64, *types.AccessList, error) {
msg := ethereum.CallMsg{
From: opts.From,
From: s.auth.From,
To: contract,
GasPrice: gasPrice,
GasTipCap: gasTipCap,
GasFeeCap: gasFeeCap,
Value: value,
Data: input,
Data: data,
}
gasLimitWithoutAccessList, err := s.client.EstimateGas(s.ctx, msg)
if err != nil {
Expand All @@ -93,8 +92,7 @@ func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Addr
return gasLimitWithoutAccessList, nil, nil
}

var gasLimitWithAccessList uint64
accessList, _, errStr, rpcErr := s.gethClient.CreateAccessList(s.ctx, msg)
accessList, gasLimitWithAccessList, errStr, rpcErr := s.gethClient.CreateAccessList(s.ctx, msg)
if rpcErr != nil {
log.Error("CreateAccessList RPC error", "error", rpcErr)
return gasLimitWithoutAccessList, nil, rpcErr
Expand All @@ -104,17 +102,36 @@ func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Addr
return gasLimitWithoutAccessList, nil, fmt.Errorf(errStr)
}

msg.AccessList = *accessList
gasLimitWithAccessList, err = s.client.EstimateGas(s.ctx, msg)
if err != nil {
log.Error("estimateGasLimit EstimateGas failure with access list", "error", err)
return gasLimitWithoutAccessList, nil, err
}
// Fine-tune accessList because 'to' address is automatically included in the access list by the Ethereum protocol: https://github.com/ethereum/go-ethereum/blob/v1.13.10/core/state/statedb.go#L1322
// This function returns a gas estimation because GO SDK does not support access list: https://github.com/ethereum/go-ethereum/blob/v1.13.10/ethclient/ethclient.go#L642
accessList, gasLimitWithAccessList = finetuneAccessList(accessList, gasLimitWithAccessList, msg.To)

log.Info("gas", "gasLimitWithAccessList", gasLimitWithAccessList, "gasLimitWithoutAccessList", gasLimitWithoutAccessList)
log.Info("gas", "senderName", s.name, "senderService", s.service, "gasLimitWithAccessList", gasLimitWithAccessList, "gasLimitWithoutAccessList", gasLimitWithoutAccessList, "accessList", accessList)

if gasLimitWithAccessList < gasLimitWithoutAccessList {
return gasLimitWithAccessList, accessList, nil
}
return gasLimitWithoutAccessList, nil, nil
}

func finetuneAccessList(accessList *types.AccessList, gasLimitWithAccessList uint64, to *common.Address) (*types.AccessList, uint64) {
if accessList == nil || to == nil {
return accessList, gasLimitWithAccessList
}

var newAccessList types.AccessList
for _, entry := range *accessList {
if entry.Address == *to && len(entry.StorageKeys) < 24 {
// Based on: https://arxiv.org/pdf/2312.06574.pdf
// We remove the address and respective storage keys as long as the number of storage keys < 24.
// This removal helps in preventing double-counting of the 'to' address in access list calculations.
gasLimitWithAccessList -= 2400
// Each storage key saves 100 gas units.
gasLimitWithAccessList += uint64(100 * len(entry.StorageKeys))
} else {
// Otherwise, keep the entry in the new access list.
newAccessList = append(newAccessList, entry)
}
}
return &newAccessList, gasLimitWithAccessList
}
24 changes: 12 additions & 12 deletions rollup/internal/controller/sender/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ func (s *Sender) SendConfirmation(cfm *Confirmation) {
s.confirmCh <- cfm
}

func (s *Sender) getFeeData(auth *bind.TransactOpts, target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
func (s *Sender) getFeeData(target *common.Address, value *big.Int, data []byte, fallbackGasLimit uint64) (*FeeData, error) {
if s.config.TxType == DynamicFeeTxType {
return s.estimateDynamicGas(auth, target, value, data, fallbackGasLimit)
return s.estimateDynamicGas(target, value, data, fallbackGasLimit)
}
return s.estimateLegacyGas(auth, target, value, data, fallbackGasLimit)
return s.estimateLegacyGas(target, value, data, fallbackGasLimit)
}

// SendTransaction send a signed L2tL1 transaction.
Expand Down Expand Up @@ -226,13 +226,13 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I
}
}()

if feeData, err = s.getFeeData(s.auth, target, value, data, fallbackGasLimit); err != nil {
if feeData, err = s.getFeeData(target, value, data, fallbackGasLimit); err != nil {
s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc()
log.Error("failed to get fee data", "from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "fallback gas limit", fallbackGasLimit, "err", err)
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 {
if tx, err = s.createAndSendTx(feeData, target, value, data, nil); err != nil {
s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc()
log.Error("failed to create and send tx (non-resubmit case)", "from", s.auth.From.String(), "nonce", s.auth.Nonce.Uint64(), "err", err)
return common.Hash{}, fmt.Errorf("failed to create and send transaction, err: %w", err)
Expand All @@ -250,9 +250,9 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I
return tx.Hash(), nil
}

func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, target *common.Address, value *big.Int, data []byte, overrideNonce *uint64) (*types.Transaction, error) {
func (s *Sender) createAndSendTx(feeData *FeeData, target *common.Address, value *big.Int, data []byte, overrideNonce *uint64) (*types.Transaction, error) {
var (
nonce = auth.Nonce.Uint64()
nonce = s.auth.Nonce.Uint64()
txData types.TxData
)

Expand Down Expand Up @@ -308,13 +308,13 @@ func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, targ
}

// sign and send
tx, err := auth.Signer(auth.From, types.NewTx(txData))
tx, err := s.auth.Signer(s.auth.From, types.NewTx(txData))
if err != nil {
log.Error("failed to sign tx", "address", auth.From.String(), "err", err)
log.Error("failed to sign tx", "address", s.auth.From.String(), "err", err)
return nil, err
}
if err = s.client.SendTransaction(s.ctx, tx); err != nil {
log.Error("failed to send tx", "tx hash", tx.Hash().String(), "from", auth.From.String(), "nonce", tx.Nonce(), "err", err)
log.Error("failed to send tx", "tx hash", tx.Hash().String(), "from", s.auth.From.String(), "nonce", tx.Nonce(), "err", err)
// Check if contain nonce, and reset nonce
// only reset nonce when it is not from resubmit
if strings.Contains(err.Error(), "nonce") && overrideNonce == nil {
Expand All @@ -339,7 +339,7 @@ func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, targ

// update nonce when it is not from resubmit
if overrideNonce == nil {
auth.Nonce = big.NewInt(int64(nonce + 1))
s.auth.Nonce = big.NewInt(int64(nonce + 1))
}
return tx, nil
}
Expand Down Expand Up @@ -442,7 +442,7 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts,

nonce := tx.Nonce()
s.metrics.resubmitTransactionTotal.WithLabelValues(s.service, s.name).Inc()
tx, err := s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data(), &nonce)
tx, err := s.createAndSendTx(feeData, tx.To(), tx.Value(), tx.Data(), &nonce)
if err != nil {
log.Error("failed to create and send tx (resubmit case)", "from", s.auth.From.String(), "nonce", nonce, "err", err)
return nil, err
Expand Down
Loading

0 comments on commit 7c37655

Please sign in to comment.