Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(relayer): cache maxFeeData #897

Merged
merged 12 commits into from
Sep 1, 2023
2 changes: 1 addition & 1 deletion bridge/internal/controller/sender/estimategas.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (s *Sender) estimateGasLimit(opts *bind.TransactOpts, contract *common.Addr
gasLimit = minGasLimit
}

gasLimit = gasLimit * 15 / 10 // 50% extra gas to void out of gas error
gasLimit = gasLimit * 15 / 10 // 50% extra gas to avoid out of gas error

return gasLimit, nil
}
67 changes: 53 additions & 14 deletions bridge/internal/controller/sender/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ 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
Expand Down Expand Up @@ -85,6 +94,8 @@ type Sender struct {
stopCh chan struct{}

metrics *senderMetrics

cachedMaxFeeData *FeeData // hacky way to avoid getFeeData error
}

// NewSender returns a new instance of transaction sender
Expand Down Expand Up @@ -129,19 +140,20 @@ 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,
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(),
}
sender.metrics = initSenderMetrics(reg)

Expand Down Expand Up @@ -189,6 +201,26 @@ 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()
Expand Down Expand Up @@ -217,7 +249,13 @@ 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()
return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err)
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)
}

if tx, err = s.createAndSendTx(s.auth, feeData, target, value, data, nil); err != nil {
Expand Down Expand Up @@ -410,6 +448,7 @@ 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()
Expand Down
2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
)

var tag = "v4.2.11"
var tag = "v4.2.12"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down
Loading