Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into requeue-sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
rach-id authored Dec 5, 2023
2 parents fa8bd8d + b1c2b89 commit 33aa69d
Showing 1 changed file with 103 additions and 11 deletions.
114 changes: 103 additions & 11 deletions relayer/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"strconv"
"time"

"github.com/ethereum/go-ethereum/params"

"github.com/ethereum/go-ethereum/ethclient"

"github.com/ipfs/go-datastore"
Expand Down Expand Up @@ -408,19 +410,52 @@ func (r *Relayer) waitForTransactionAndRetryIfNeeded(ctx context.Context, ethCli
_, err := r.EVMClient.WaitForTransaction(ctx, ethClient, newTx, r.RetryTimeout)
if err != nil {
if stderrors.Is(err, context.DeadlineExceeded) {
newGasPrice, err := ethClient.SuggestGasPrice(ctx)
if err != nil {
return err
}
if newGasPrice.Uint64() <= newTx.GasPrice().Uint64() {
// no need to resend the transaction if the suggested gas price is lower than the original one
continue
var rawTx *coregethtypes.Transaction
if tx.GasPrice() != nil {
rawTx, err = createSpeededUpLegacyTransaction(ctx, ethClient, newTx)
if err != nil {
return err
}
if rawTx.GasPrice().Cmp(newTx.GasPrice()) <= 0 {
// no need to resend the transaction if the suggested gas price is lower than the original one
continue
}
} else if tx.GasTipCap() != nil && tx.GasFeeCap() != nil {
rawTx, err = createSpeededUpDynamicTransaction(ctx, ethClient, newTx)
if err != nil {
return err
}
if rawTx.GasFeeCap().Cmp(newTx.GasFeeCap()) <= 0 {
// no need to resend the transaction if the suggested gas price is lower than the original one
continue
}
} else {
// Only query for basefee if gasPrice not specified
if head, errHead := ethClient.HeaderByNumber(ctx, nil); errHead != nil {
return errHead
} else if head.BaseFee != nil {
rawTx, err = createSpeededUpDynamicTransaction(ctx, ethClient, newTx)
if err != nil {
return err
}
if rawTx.GasFeeCap().Cmp(newTx.GasFeeCap()) <= 0 {
// no need to resend the transaction if the suggested gas price is lower than the original one
continue
}
} else {
// Chain is not London ready -> use legacy transaction
rawTx, err = createSpeededUpLegacyTransaction(ctx, ethClient, newTx)
if err != nil {
return err
}
if rawTx.GasPrice().Cmp(newTx.GasPrice()) <= 0 {
// no need to resend the transaction if the suggested gas price is lower than the original one
continue
}
}
}
legacyTx := toLegacyTransaction(newTx)
legacyTx.GasPrice = newGasPrice
newTx = coregethtypes.NewTx(legacyTx)
r.logger.Debug("transaction still not included. updating the gas price", "retry_number", i)
err = ethClient.SendTransaction(ctx, newTx)
err = ethClient.SendTransaction(ctx, rawTx)
r.logger.Info("submitted speed up transaction", "hash", newTx.Hash().Hex(), "new_gas_price", newTx.GasPrice().Uint64())
if err != nil {
r.logger.Debug("response of sending speed up transaction", "resp", err.Error())
Expand All @@ -435,6 +470,45 @@ func (r *Relayer) waitForTransactionAndRetryIfNeeded(ctx context.Context, ethCli
return ErrTransactionStillPending
}

// createSpeededUpDynamicTransaction update the EIP1559 dynamic transaction with the current gas price.
func createSpeededUpDynamicTransaction(ctx context.Context, ethClient *ethclient.Client, newTx *coregethtypes.Transaction) (*coregethtypes.Transaction, error) {
// Estimate TipCap
gasTipCap, err := ethClient.SuggestGasTipCap(ctx)
if err != nil {
return nil, err
}
lastKnownHeader, err := ethClient.HeaderByNumber(ctx, nil)
if err != nil {
return nil, err
}
// Estimate FeeCap
gasFeeCap := new(big.Int).Add(
gasTipCap,
// the DefaultElasticityMultiplier is used to define the wiggle room for the gas
// in EIP1559
new(big.Int).Mul(lastKnownHeader.BaseFee, big.NewInt(params.DefaultElasticityMultiplier)),
)
if gasFeeCap.Cmp(gasTipCap) < 0 {
return nil, fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", gasFeeCap, gasTipCap)
}

dynamicTransaction := toDynamicTransaction(newTx)
dynamicTransaction.GasTipCap = gasTipCap
dynamicTransaction.GasFeeCap = gasFeeCap
return coregethtypes.NewTx(dynamicTransaction), nil
}

// createSpeededUpLegacyTransaction update the legacy transaction with the new gas price.
func createSpeededUpLegacyTransaction(ctx context.Context, ethClient *ethclient.Client, newTx *coregethtypes.Transaction) (tx *coregethtypes.Transaction, err error) {
newGasPrice, err := ethClient.SuggestGasPrice(ctx)
if err != nil {
return nil, err
}
legacyTx := toLegacyTransaction(newTx)
legacyTx.GasPrice = newGasPrice
return coregethtypes.NewTx(legacyTx), nil
}

func toLegacyTransaction(tx *coregethtypes.Transaction) *coregethtypes.LegacyTx {
v, r, s := tx.RawSignatureValues()
return &coregethtypes.LegacyTx{
Expand All @@ -450,6 +524,24 @@ func toLegacyTransaction(tx *coregethtypes.Transaction) *coregethtypes.LegacyTx
}
}

func toDynamicTransaction(tx *coregethtypes.Transaction) *coregethtypes.DynamicFeeTx {
v, r, s := tx.RawSignatureValues()
return &coregethtypes.DynamicFeeTx{
ChainID: tx.ChainId(),
Nonce: tx.Nonce(),
GasTipCap: tx.GasTipCap(),
GasFeeCap: tx.GasFeeCap(),
Gas: tx.Gas(),
To: tx.To(),
Value: tx.Value(),
Data: tx.Data(),
AccessList: tx.AccessList(),
V: v,
R: r,
S: s,
}
}

// matchAttestationConfirmSigs matches and sorts the confirm signatures with the valset
// members as expected by the Blobstream contract.
// Also, it leaves the non provided signatures as nil in the `sigs` slice:
Expand Down

0 comments on commit 33aa69d

Please sign in to comment.