-
Notifications
You must be signed in to change notification settings - Fork 14
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
Lo6165 price bump cap #62
base: main
Are you sure you want to change the base?
Changes from 7 commits
d412a80
c5db28a
6621802
3213c9c
a845932
557c2b0
4901d10
19e9c1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,12 @@ import ( | |
"context" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/accounts/abi/bind" | ||
|
||
"github.com/datachainlab/ethereum-ibc-relay-chain/pkg/client" | ||
"github.com/datachainlab/ethereum-ibc-relay-chain/pkg/client/txpool" | ||
) | ||
|
||
func (chain *Chain) CallOpts(ctx context.Context, height int64) *bind.CallOpts { | ||
|
@@ -26,10 +31,6 @@ func (chain *Chain) TxOpts(ctx context.Context, useLatestNonce bool) (*bind.Tran | |
Signer: chain.ethereumSigner.Sign, | ||
} | ||
|
||
if err := NewGasFeeCalculator(chain.client, &chain.config).Apply(ctx, txOpts); err != nil { | ||
return nil, err | ||
} | ||
|
||
if useLatestNonce { | ||
if nonce, err := chain.client.NonceAt(ctx, addr, nil); err != nil { | ||
return nil, err | ||
|
@@ -38,5 +39,26 @@ func (chain *Chain) TxOpts(ctx context.Context, useLatestNonce bool) (*bind.Tran | |
} | ||
} | ||
|
||
if err := NewGasFeeCalculator(chain.client, &chain.config).Apply(ctx, txOpts); err != nil { | ||
return nil, err | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. statement move to fix bug |
||
return txOpts, nil | ||
} | ||
|
||
// wrapping interface of client.ETHClient struct | ||
type IChainClient interface { | ||
ethereum.ChainReader | ||
ethereum.GasPricer | ||
ethereum.FeeHistoryReader | ||
|
||
GetMinimumRequiredFee(ctx context.Context, address common.Address, nonce uint64, priceBump uint64) (*txpool.RPCTransaction, *big.Int, *big.Int, error); | ||
} | ||
|
||
type ChainClient struct { | ||
*client.ETHClient | ||
} | ||
|
||
func (cl *ChainClient) GetMinimumRequiredFee(ctx context.Context, address common.Address, nonce uint64, priceBump uint64) (*txpool.RPCTransaction, *big.Int, *big.Int, error) { | ||
return txpool.GetMinimumRequiredFee(ctx, cl.ETHClient.Client, address, nonce, priceBump); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,19 +5,18 @@ import ( | |
"fmt" | ||
"math/big" | ||
|
||
"github.com/datachainlab/ethereum-ibc-relay-chain/pkg/client" | ||
"github.com/datachainlab/ethereum-ibc-relay-chain/pkg/client/txpool" | ||
"github.com/ethereum/go-ethereum" | ||
"github.com/ethereum/go-ethereum/accounts/abi/bind" | ||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
type GasFeeCalculator struct { | ||
client *client.ETHClient | ||
client IChainClient | ||
config *ChainConfig | ||
} | ||
|
||
func NewGasFeeCalculator(client *client.ETHClient, config *ChainConfig) *GasFeeCalculator { | ||
func NewGasFeeCalculator(client IChainClient, config *ChainConfig) *GasFeeCalculator { | ||
return &GasFeeCalculator{ | ||
client: client, | ||
config: config, | ||
|
@@ -27,19 +26,22 @@ func NewGasFeeCalculator(client *client.ETHClient, config *ChainConfig) *GasFeeC | |
func (m *GasFeeCalculator) Apply(ctx context.Context, txOpts *bind.TransactOpts) error { | ||
minFeeCap := common.Big0 | ||
minTipCap := common.Big0 | ||
var oldTx *txpool.RPCTransaction | ||
if m.config.PriceBump > 0 && txOpts.Nonce != nil { | ||
var err error | ||
if minFeeCap, minTipCap, err = txpool.GetMinimumRequiredFee(ctx, m.client.Client, txOpts.From, txOpts.Nonce.Uint64(), m.config.PriceBump); err != nil { | ||
if oldTx, minFeeCap, minTipCap, err = m.client.GetMinimumRequiredFee(ctx, txOpts.From, txOpts.Nonce.Uint64(), m.config.PriceBump); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
switch m.config.TxType { | ||
case TxTypeLegacy: | ||
gasPrice, err := m.client.SuggestGasPrice(ctx) | ||
if err != nil { | ||
return fmt.Errorf("failed to suggest gas price: %v", err) | ||
} | ||
if oldTx != nil && oldTx.GasPrice != nil && oldTx.GasPrice.ToInt().Cmp(gasPrice) > 0 { | ||
return fmt.Errorf("old tx's gasPrice(%v) is higher than suggestion(%v)", oldTx.GasPrice.ToInt(), gasPrice) | ||
} | ||
if gasPrice.Cmp(minFeeCap) < 0 { | ||
gasPrice = minFeeCap | ||
} | ||
|
@@ -52,6 +54,9 @@ func (m *GasFeeCalculator) Apply(ctx context.Context, txOpts *bind.TransactOpts) | |
} | ||
// GasTipCap = min(LimitPriorityFeePerGas, simulated_eth_maxPriorityFeePerGas * PriorityFeeRate) | ||
m.config.DynamicTxGasConfig.PriorityFeeRate.Mul(gasTipCap) | ||
if oldTx != nil && oldTx.GasTipCap != nil && oldTx.GasTipCap.ToInt().Cmp(gasTipCap) > 0 { | ||
return fmt.Errorf("old tx's gasTipCap(%v) is higher than suggestion(%v)", oldTx.GasTipCap.ToInt(), gasTipCap) | ||
} | ||
if gasTipCap.Cmp(minTipCap) < 0 { | ||
gasTipCap = minTipCap | ||
} | ||
|
@@ -61,6 +66,9 @@ func (m *GasFeeCalculator) Apply(ctx context.Context, txOpts *bind.TransactOpts) | |
// GasFeeCap = min(LimitFeePerGas, GasTipCap + BaseFee * BaseFeeRate) | ||
m.config.DynamicTxGasConfig.BaseFeeRate.Mul(gasFeeCap) | ||
gasFeeCap.Add(gasFeeCap, gasTipCap) | ||
if oldTx != nil && oldTx.GasFeeCap != nil && oldTx.GasFeeCap.ToInt().Cmp(gasFeeCap) > 0 { | ||
return fmt.Errorf("old tx's gasFeeCap(%v) is higher than suggestion(%v)", oldTx.GasFeeCap.ToInt(), gasFeeCap) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dai1975 I think that we should give up tx replacement only if both the tip and fee caps of the pending tx are higher than the new tx. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surely. fixed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add error case when new caps are equals to old caps(Cmp returns zero) |
||
if gasFeeCap.Cmp(minFeeCap) < 0 { | ||
gasFeeCap = minFeeCap | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hexuti.Big.ToInt() returns same pointer of receiver instance and following inclByPercent() overwrite it. This make problems when targetTx object is stored and reused such as testing mock.