mirror of
https://github.com/status-im/status-go.git
synced 2025-02-21 19:28:29 +00:00
feat(wallet)_: calculating tx estimated time
This commit is contained in:
parent
1bfb0cef02
commit
0bf6048801
@ -97,7 +97,7 @@ func (c *SendTransactionCommand) Execute(ctx context.Context, request RPCRequest
|
|||||||
if !fetchedFees.EIP1559Enabled {
|
if !fetchedFees.EIP1559Enabled {
|
||||||
params.GasPrice = (*hexutil.Big)(fetchedFees.GasPrice)
|
params.GasPrice = (*hexutil.Big)(fetchedFees.GasPrice)
|
||||||
} else {
|
} else {
|
||||||
maxFees, priorityFee, err := fetchedFees.FeeFor(fees.GasFeeMedium)
|
maxFees, priorityFee, _, err := fetchedFees.FeeFor(fees.GasFeeMedium)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -481,6 +481,11 @@ func (api *API) GetTransactionEstimatedTime(ctx context.Context, chainID uint64,
|
|||||||
return api.s.router.GetFeesManager().TransactionEstimatedTime(ctx, chainID, gweiToWei(maxFeePerGas)), nil
|
return api.s.router.GetFeesManager().TransactionEstimatedTime(ctx, chainID, gweiToWei(maxFeePerGas)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) GetTransactionEstimatedTimeV2(ctx context.Context, chainID uint64, maxFeePerGas *hexutil.Big, maxPriorityFeePerGas *hexutil.Big) (uint, error) {
|
||||||
|
logutils.ZapLogger().Debug("call to getTransactionEstimatedTimeV2")
|
||||||
|
return api.s.router.GetFeesManager().TransactionEstimatedTimeV2(ctx, chainID, maxFeePerGas.ToInt(), maxPriorityFeePerGas.ToInt()), nil
|
||||||
|
}
|
||||||
|
|
||||||
func gweiToWei(val *big.Float) *big.Int {
|
func gweiToWei(val *big.Float) *big.Int {
|
||||||
res, _ := new(big.Float).Mul(val, big.NewFloat(1000000000)).Int(nil)
|
res, _ := new(big.Float).Mul(val, big.NewFloat(1000000000)).Int(nil)
|
||||||
return res
|
return res
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
gethParams "github.com/ethereum/go-ethereum/params"
|
gethParams "github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
@ -75,3 +76,11 @@ func WeiToGwei(val *big.Int) *big.Float {
|
|||||||
|
|
||||||
return result.Quo(result, new(big.Float).SetInt(unit))
|
return result.Quo(result, new(big.Float).SetInt(unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetBlockCreationTimeForChain(chainID uint64) time.Duration {
|
||||||
|
blockDuration, found := AverageBlockDurationForChain[ChainID(chainID)]
|
||||||
|
if !found {
|
||||||
|
blockDuration = AverageBlockDurationForChain[ChainID(UnknownChainID)]
|
||||||
|
}
|
||||||
|
return blockDuration
|
||||||
|
}
|
||||||
|
@ -5,10 +5,24 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
|
"github.com/status-im/status-go/services/wallet/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const inclusionThreshold = 0.95
|
const (
|
||||||
|
inclusionThreshold = 0.95
|
||||||
|
|
||||||
|
priorityFeePercentileHigh = 0.6
|
||||||
|
priorityFeePercentileMedium = 0.5
|
||||||
|
priorityFeePercentileLow = 0.4
|
||||||
|
|
||||||
|
baseFeePercentileFirstBlock = 0.8
|
||||||
|
baseFeePercentileSecondBlock = 0.7
|
||||||
|
baseFeePercentileThirdBlock = 0.6
|
||||||
|
baseFeePercentileFourthBlock = 0.5
|
||||||
|
baseFeePercentileFifthBlock = 0.4
|
||||||
|
baseFeePercentileSixthBlock = 0.3
|
||||||
|
)
|
||||||
|
|
||||||
type TransactionEstimation int
|
type TransactionEstimation int
|
||||||
|
|
||||||
@ -30,8 +44,8 @@ func (f *FeeManager) TransactionEstimatedTime(ctx context.Context, chainID uint6
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeeManager) estimatedTime(feeHistory *FeeHistory, maxFeePerGas *big.Int) TransactionEstimation {
|
func (f *FeeManager) estimatedTime(feeHistory *FeeHistory, maxFeePerGas *big.Int) TransactionEstimation {
|
||||||
fees, err := f.getFeeHistorySorted(feeHistory)
|
fees := f.convertToBigIntAndSort(feeHistory.BaseFeePerGas)
|
||||||
if err != nil || len(fees) == 0 {
|
if len(fees) == 0 {
|
||||||
return Unknown
|
return Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,14 +116,110 @@ func (f *FeeManager) estimatedTime(feeHistory *FeeHistory, maxFeePerGas *big.Int
|
|||||||
return MoreThanFiveMinutes
|
return MoreThanFiveMinutes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeeManager) getFeeHistorySorted(feeHistory *FeeHistory) ([]*big.Int, error) {
|
func (f *FeeManager) convertToBigIntAndSort(hexArray []string) []*big.Int {
|
||||||
fees := []*big.Int{}
|
values := []*big.Int{}
|
||||||
for _, fee := range feeHistory.BaseFeePerGas {
|
for _, sValue := range hexArray {
|
||||||
i := new(big.Int)
|
iValue := new(big.Int)
|
||||||
i.SetString(strings.Replace(fee, "0x", "", 1), 16)
|
_, ok := iValue.SetString(sValue, 0)
|
||||||
fees = append(fees, i)
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
values = append(values, iValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(fees, func(i, j int) bool { return fees[i].Cmp(fees[j]) < 0 })
|
sort.Slice(values, func(i, j int) bool { return values[i].Cmp(values[j]) < 0 })
|
||||||
return fees, nil
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FeeManager) getFeeHistoryForTimeEstimation(ctx context.Context, chainID uint64) (*FeeHistory, error) {
|
||||||
|
blockCount := uint64(10) // use the last 10 blocks for L1 chains
|
||||||
|
if chainID != common.EthereumMainnet &&
|
||||||
|
chainID != common.EthereumSepolia &&
|
||||||
|
chainID != common.AnvilMainnet {
|
||||||
|
blockCount = 50 // use the last 50 blocks for L2 chains
|
||||||
|
}
|
||||||
|
return f.getFeeHistory(ctx, chainID, blockCount, "latest", []int{RewardPercentiles2})
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateTimeForInclusion(chainID uint64, expectedInclusionInBlock int) uint {
|
||||||
|
blockCreationTime := common.GetBlockCreationTimeForChain(chainID)
|
||||||
|
blockCreationTimeInSeconds := uint(blockCreationTime.Seconds())
|
||||||
|
|
||||||
|
// the client will decide how to display estimated times, status-go sends it in the steps of 5 (for example the client
|
||||||
|
// should display "more than 1 minute" if the expected inclusion time is 60 seconds or more.
|
||||||
|
expectedInclusionTime := uint(expectedInclusionInBlock) * blockCreationTimeInSeconds
|
||||||
|
return (expectedInclusionTime/5 + 1) * 5
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBaseFeePercentileIndex(sortedBaseFees []*big.Int, percentile float64, networkCongestion float64) int {
|
||||||
|
// calculate the index of the base fee for the given percentile corrected by the network congestion
|
||||||
|
index := int(float64(len(sortedBaseFees)) * percentile * networkCongestion)
|
||||||
|
if index >= len(sortedBaseFees) {
|
||||||
|
return len(sortedBaseFees) - 1
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransactionEstimatedTimeV2 returns the estimated time in seconds for a transaction to be included in a block
|
||||||
|
func (f *FeeManager) TransactionEstimatedTimeV2(ctx context.Context, chainID uint64, maxFeePerGas *big.Int, priorityFee *big.Int) uint {
|
||||||
|
feeHistory, err := f.getFeeHistoryForTimeEstimation(ctx, chainID)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.estimatedTimeV2(feeHistory, maxFeePerGas, priorityFee, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FeeManager) estimatedTimeV2(feeHistory *FeeHistory, txMaxFeePerGas *big.Int, txPriorityFee *big.Int, chainID uint64) uint {
|
||||||
|
sortedBaseFees := f.convertToBigIntAndSort(feeHistory.BaseFeePerGas)
|
||||||
|
if len(sortedBaseFees) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var mediumPriorityFees []string // based on 50th percentile in the last 100 blocks
|
||||||
|
for _, fee := range feeHistory.Reward {
|
||||||
|
mediumPriorityFees = append(mediumPriorityFees, fee[0])
|
||||||
|
}
|
||||||
|
mediumPriorityFeesSorted := f.convertToBigIntAndSort(mediumPriorityFees)
|
||||||
|
if len(mediumPriorityFeesSorted) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
txBaseFee := new(big.Int).Sub(txMaxFeePerGas, txPriorityFee)
|
||||||
|
|
||||||
|
networkCongestion := calculateNetworkCongestion(feeHistory)
|
||||||
|
|
||||||
|
// Priority fee for the first two blocks has to be higher than 60th percentile of the mediumPriorityFeesSorted
|
||||||
|
priorityFeePercentileIndex := int(float64(len(mediumPriorityFeesSorted)) * priorityFeePercentileHigh)
|
||||||
|
priorityFeeForFirstTwoBlock := mediumPriorityFeesSorted[priorityFeePercentileIndex]
|
||||||
|
// Priority fee for the second two blocks has to be higher than 50th percentile of the mediumPriorityFeesSorted
|
||||||
|
priorityFeePercentileIndex = int(float64(len(mediumPriorityFeesSorted)) * priorityFeePercentileMedium)
|
||||||
|
priorityFeeForSecondTwoBlocks := mediumPriorityFeesSorted[priorityFeePercentileIndex]
|
||||||
|
// Priority fee for the third two blocks has to be higher than 40th percentile of the mediumPriorityFeesSorted
|
||||||
|
priorityFeePercentileIndex = int(float64(len(mediumPriorityFeesSorted)) * priorityFeePercentileLow)
|
||||||
|
priorityFeeForThirdTwoBlocks := mediumPriorityFeesSorted[priorityFeePercentileIndex]
|
||||||
|
|
||||||
|
// To include the transaction in the block `inclusionInBlock` its base fee has to be in a higher than `baseFeePercentile`
|
||||||
|
// and its priority fee has to be higher than the `priorityFee`
|
||||||
|
inclusions := []struct {
|
||||||
|
inclusionInBlock int
|
||||||
|
baseFeePercentile float64
|
||||||
|
priorityFee *big.Int
|
||||||
|
}{
|
||||||
|
{1, baseFeePercentileFirstBlock, priorityFeeForFirstTwoBlock},
|
||||||
|
{2, baseFeePercentileSecondBlock, priorityFeeForFirstTwoBlock},
|
||||||
|
{3, baseFeePercentileThirdBlock, priorityFeeForSecondTwoBlocks},
|
||||||
|
{4, baseFeePercentileFourthBlock, priorityFeeForSecondTwoBlocks},
|
||||||
|
{5, baseFeePercentileFifthBlock, priorityFeeForThirdTwoBlocks},
|
||||||
|
{6, baseFeePercentileSixthBlock, priorityFeeForThirdTwoBlocks},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range inclusions {
|
||||||
|
baseFeePercentileIndex := getBaseFeePercentileIndex(sortedBaseFees, p.baseFeePercentile, networkCongestion)
|
||||||
|
if txBaseFee.Cmp(sortedBaseFees[baseFeePercentileIndex]) >= 0 && txPriorityFee.Cmp(p.priorityFee) >= 0 {
|
||||||
|
return calculateTimeForInclusion(chainID, p.inclusionInBlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -32,28 +32,31 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MaxFeesLevels struct {
|
type MaxFeesLevels struct {
|
||||||
Low *hexutil.Big `json:"low"`
|
Low *hexutil.Big `json:"low"` // Low max fee per gas in WEI
|
||||||
LowPriority *hexutil.Big `json:"lowPriority"`
|
LowPriority *hexutil.Big `json:"lowPriority"` // Low priority fee in WEI
|
||||||
Medium *hexutil.Big `json:"medium"`
|
LowEstimatedTime uint `json:"lowEstimatedTime"` // Estimated time for low fees in seconds
|
||||||
MediumPriority *hexutil.Big `json:"mediumPriority"`
|
Medium *hexutil.Big `json:"medium"` // Medium max fee per gas in WEI
|
||||||
High *hexutil.Big `json:"high"`
|
MediumPriority *hexutil.Big `json:"mediumPriority"` // Medium priority fee in WEI
|
||||||
HighPriority *hexutil.Big `json:"highPriority"`
|
MediumEstimatedTime uint `json:"mediumEstimatedTime"` // Estimated time for medium fees in seconds
|
||||||
|
High *hexutil.Big `json:"high"` // High max fee per gas in WEI
|
||||||
|
HighPriority *hexutil.Big `json:"highPriority"` // High priority fee in WEI
|
||||||
|
HighEstimatedTime uint `json:"highEstimatedTime"` // Estimated time for high fees in seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
type MaxPriorityFeesSuggestedBounds struct {
|
type MaxPriorityFeesSuggestedBounds struct {
|
||||||
Lower *big.Int
|
Lower *big.Int // Lower bound for priority fee per gas in WEI
|
||||||
Upper *big.Int
|
Upper *big.Int // Upper bound for priority fee per gas in WEI
|
||||||
}
|
}
|
||||||
|
|
||||||
type SuggestedFees struct {
|
type SuggestedFees struct {
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int // TODO: remove once clients stop using this field, used for EIP-1559 incompatible chains, not in use anymore
|
||||||
BaseFee *big.Int
|
BaseFee *big.Int // TODO: remove once clients stop using this field, current network base fee (in ETH WEI), kept for backward compatibility
|
||||||
CurrentBaseFee *big.Int // Current network base fee (in ETH WEI)
|
CurrentBaseFee *big.Int // Current network base fee (in ETH WEI)
|
||||||
MaxFeesLevels *MaxFeesLevels
|
MaxFeesLevels *MaxFeesLevels // Max fees levels for low, medium and high fee modes
|
||||||
MaxPriorityFeePerGas *big.Int // TODO: remove once clients stop using this field
|
MaxPriorityFeePerGas *big.Int // TODO: remove once clients stop using this field, kept for backward compatibility
|
||||||
MaxPriorityFeeSuggestedBounds *MaxPriorityFeesSuggestedBounds
|
MaxPriorityFeeSuggestedBounds *MaxPriorityFeesSuggestedBounds // Lower and upper bounds for priority fee per gas in WEI
|
||||||
L1GasFee *big.Float
|
L1GasFee *big.Float // TODO: remove once clients stop using this field, not in use anymore
|
||||||
EIP1559Enabled bool
|
EIP1559Enabled bool // TODO: remove it since all chains we have support EIP-1559
|
||||||
}
|
}
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
@ -71,23 +74,23 @@ type SuggestedFeesGwei struct {
|
|||||||
EIP1559Enabled bool `json:"eip1559Enabled"`
|
EIP1559Enabled bool `json:"eip1559Enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MaxFeesLevels) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, error) {
|
func (m *MaxFeesLevels) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, uint, error) {
|
||||||
if mode == GasFeeCustom {
|
if mode == GasFeeCustom {
|
||||||
return nil, nil, ErrCustomFeeModeNotAvailableInSuggestedFees
|
return nil, nil, 0, ErrCustomFeeModeNotAvailableInSuggestedFees
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == GasFeeLow {
|
if mode == GasFeeLow {
|
||||||
return m.Low.ToInt(), m.LowPriority.ToInt(), nil
|
return m.Low.ToInt(), m.LowPriority.ToInt(), m.LowEstimatedTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == GasFeeHigh {
|
if mode == GasFeeHigh {
|
||||||
return m.High.ToInt(), m.HighPriority.ToInt(), nil
|
return m.High.ToInt(), m.HighPriority.ToInt(), m.MediumEstimatedTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.Medium.ToInt(), m.MediumPriority.ToInt(), nil
|
return m.Medium.ToInt(), m.MediumPriority.ToInt(), m.HighEstimatedTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SuggestedFees) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, error) {
|
func (s *SuggestedFees) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, uint, error) {
|
||||||
return s.MaxFeesLevels.FeeFor(mode)
|
return s.MaxFeesLevels.FeeFor(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +153,14 @@ func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*Sugges
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
feeHistory, err = f.getFeeHistoryForTimeEstimation(ctx, chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
suggestedFees.MaxFeesLevels.LowEstimatedTime = f.estimatedTimeV2(feeHistory, suggestedFees.MaxFeesLevels.Low.ToInt(), suggestedFees.MaxFeesLevels.LowPriority.ToInt(), chainID)
|
||||||
|
suggestedFees.MaxFeesLevels.MediumEstimatedTime = f.estimatedTimeV2(feeHistory, suggestedFees.MaxFeesLevels.Medium.ToInt(), suggestedFees.MaxFeesLevels.MediumPriority.ToInt(), chainID)
|
||||||
|
suggestedFees.MaxFeesLevels.HighEstimatedTime = f.estimatedTimeV2(feeHistory, suggestedFees.MaxFeesLevels.High.ToInt(), suggestedFees.MaxFeesLevels.HighPriority.ToInt(), chainID)
|
||||||
|
|
||||||
return suggestedFees, nil
|
return suggestedFees, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,32 +64,43 @@ func TestEstimatedTime(t *testing.T) {
|
|||||||
assert.Equal(t, LessThanOneMinute, estimation)
|
assert.Equal(t, LessThanOneMinute, estimation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSuggestedFeesForNotEIP1559CompatibleChains(t *testing.T) {
|
func TestEstimatedTimeV2(t *testing.T) {
|
||||||
state := setupTest(t)
|
state := setupTest(t)
|
||||||
|
// no fee history
|
||||||
chainID := uint64(1)
|
|
||||||
gasPrice := big.NewInt(1)
|
|
||||||
feeHistory := &FeeHistory{}
|
feeHistory := &FeeHistory{}
|
||||||
percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3}
|
state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(10), "latest", []int{RewardPercentiles2}).Times(1).Return(nil)
|
||||||
state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil)
|
|
||||||
mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl)
|
|
||||||
state.rpcClient.EXPECT().EthClient(chainID).Times(1).Return(mockedChainClient, nil)
|
|
||||||
mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(gasPrice, nil)
|
|
||||||
|
|
||||||
suggestedFees, err := state.feeManager.SuggestedFees(context.Background(), chainID)
|
maxFeesPerGas := big.NewInt(2e9)
|
||||||
assert.NoError(t, err)
|
priorityFeesPerGas := big.NewInt(2e8)
|
||||||
assert.NotNil(t, suggestedFees)
|
estimation := state.feeManager.TransactionEstimatedTimeV2(context.Background(), uint64(1), maxFeesPerGas, priorityFeesPerGas)
|
||||||
assert.Equal(t, gasPrice, suggestedFees.GasPrice)
|
|
||||||
assert.False(t, suggestedFees.EIP1559Enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) {
|
assert.Equal(t, uint(0), estimation)
|
||||||
state := setupTest(t)
|
|
||||||
|
|
||||||
chainID := uint64(1)
|
// there is fee history
|
||||||
feeHistory := &FeeHistory{}
|
state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(10), "latest", []int{RewardPercentiles2}).Times(1).Return(nil).
|
||||||
percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3}
|
Do(func(feeHistory, chainID, method any, args ...any) {
|
||||||
state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil).
|
feeHistoryResponse := &FeeHistory{
|
||||||
|
BaseFeePerGas: []string{
|
||||||
|
"0x12f0e070b",
|
||||||
|
"0x13f10da8b",
|
||||||
|
"0x126c30d5e",
|
||||||
|
"0x136e4fe51",
|
||||||
|
"0x134180d5a",
|
||||||
|
"0x134e32c33",
|
||||||
|
"0x137da8d22",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*feeHistory.(*FeeHistory) = *feeHistoryResponse
|
||||||
|
})
|
||||||
|
|
||||||
|
maxFeesPerGas = big.NewInt(100e9)
|
||||||
|
priorityFeesPerGas = big.NewInt(10e9)
|
||||||
|
estimation = state.feeManager.TransactionEstimatedTimeV2(context.Background(), uint64(1), maxFeesPerGas, priorityFeesPerGas)
|
||||||
|
|
||||||
|
assert.Equal(t, uint(0), estimation)
|
||||||
|
|
||||||
|
// there is fee history and rewards
|
||||||
|
state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(10), "latest", []int{RewardPercentiles2}).Times(1).Return(nil).
|
||||||
Do(func(feeHistory, chainID, method any, args ...any) {
|
Do(func(feeHistory, chainID, method any, args ...any) {
|
||||||
feeHistoryResponse := &FeeHistory{
|
feeHistoryResponse := &FeeHistory{
|
||||||
BaseFeePerGas: []string{
|
BaseFeePerGas: []string{
|
||||||
@ -152,6 +163,107 @@ func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) {
|
|||||||
*feeHistory.(*FeeHistory) = *feeHistoryResponse
|
*feeHistory.(*FeeHistory) = *feeHistoryResponse
|
||||||
})
|
})
|
||||||
|
|
||||||
|
estimation = state.feeManager.TransactionEstimatedTimeV2(context.Background(), uint64(1), maxFeesPerGas, priorityFeesPerGas)
|
||||||
|
|
||||||
|
assert.Equal(t, uint(15), estimation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSuggestedFeesForNotEIP1559CompatibleChains(t *testing.T) {
|
||||||
|
state := setupTest(t)
|
||||||
|
|
||||||
|
chainID := uint64(1)
|
||||||
|
gasPrice := big.NewInt(1)
|
||||||
|
feeHistory := &FeeHistory{}
|
||||||
|
percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3}
|
||||||
|
state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil)
|
||||||
|
mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl)
|
||||||
|
state.rpcClient.EXPECT().EthClient(chainID).Times(1).Return(mockedChainClient, nil)
|
||||||
|
mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(gasPrice, nil)
|
||||||
|
|
||||||
|
suggestedFees, err := state.feeManager.SuggestedFees(context.Background(), chainID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, suggestedFees)
|
||||||
|
assert.Equal(t, gasPrice, suggestedFees.GasPrice)
|
||||||
|
assert.False(t, suggestedFees.EIP1559Enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) {
|
||||||
|
state := setupTest(t)
|
||||||
|
|
||||||
|
feeHistoryResponse := &FeeHistory{
|
||||||
|
BaseFeePerGas: []string{
|
||||||
|
"0x12f0e070b",
|
||||||
|
"0x13f10da8b",
|
||||||
|
"0x126c30d5e",
|
||||||
|
"0x136e4fe51",
|
||||||
|
"0x134180d5a",
|
||||||
|
"0x134e32c33",
|
||||||
|
"0x137da8d22",
|
||||||
|
},
|
||||||
|
GasUsedRatio: []float64{
|
||||||
|
0.7113286209349903,
|
||||||
|
0.19531163333333335,
|
||||||
|
0.7189235666666667,
|
||||||
|
0.4639678021079083,
|
||||||
|
0.5103012666666666,
|
||||||
|
0.538413,
|
||||||
|
0.16543626666666666,
|
||||||
|
},
|
||||||
|
OldestBlock: "0x1497d4b",
|
||||||
|
Reward: [][]string{
|
||||||
|
{
|
||||||
|
"0x2faf080",
|
||||||
|
"0x39d10680",
|
||||||
|
"0x722d7ef5",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x5f5e100",
|
||||||
|
"0x3b9aca00",
|
||||||
|
"0x59682f00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x342e4a2",
|
||||||
|
"0x39d10680",
|
||||||
|
"0x77359400",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x14a22237",
|
||||||
|
"0x40170350",
|
||||||
|
"0x77359400",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x9134860",
|
||||||
|
"0x39d10680",
|
||||||
|
"0x618400ad",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x2faf080",
|
||||||
|
"0x39d10680",
|
||||||
|
"0x77359400",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"0x1ed69035",
|
||||||
|
"0x39d10680",
|
||||||
|
"0x41d0a8d6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
chainID := uint64(1)
|
||||||
|
feeHistory := &FeeHistory{}
|
||||||
|
percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3}
|
||||||
|
state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil).
|
||||||
|
Do(func(feeHistory, chainID, method any, args ...any) {
|
||||||
|
*feeHistory.(*FeeHistory) = *feeHistoryResponse
|
||||||
|
})
|
||||||
|
|
||||||
|
feeHistory = &FeeHistory{}
|
||||||
|
percentiles = []int{RewardPercentiles2}
|
||||||
|
state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(10), "latest", percentiles).Times(1).Return(nil).
|
||||||
|
Do(func(feeHistory, chainID, method any, args ...any) {
|
||||||
|
*feeHistory.(*FeeHistory) = *feeHistoryResponse
|
||||||
|
})
|
||||||
|
|
||||||
suggestedFees, err := state.feeManager.SuggestedFees(context.Background(), chainID)
|
suggestedFees, err := state.feeManager.SuggestedFees(context.Background(), chainID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, suggestedFees)
|
assert.NotNil(t, suggestedFees)
|
||||||
@ -177,4 +289,7 @@ func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) {
|
|||||||
assert.Equal(t, big.NewInt(100000000), suggestedFees.MaxPriorityFeeSuggestedBounds.Lower)
|
assert.Equal(t, big.NewInt(100000000), suggestedFees.MaxPriorityFeeSuggestedBounds.Lower)
|
||||||
assert.Equal(t, big.NewInt(1915584245), suggestedFees.MaxPriorityFeeSuggestedBounds.Upper)
|
assert.Equal(t, big.NewInt(1915584245), suggestedFees.MaxPriorityFeeSuggestedBounds.Upper)
|
||||||
assert.True(t, suggestedFees.EIP1559Enabled)
|
assert.True(t, suggestedFees.EIP1559Enabled)
|
||||||
|
assert.Equal(t, uint(40), suggestedFees.MaxFeesLevels.LowEstimatedTime)
|
||||||
|
assert.Equal(t, uint(15), suggestedFees.MaxFeesLevels.MediumEstimatedTime)
|
||||||
|
assert.Equal(t, uint(15), suggestedFees.MaxFeesLevels.HighEstimatedTime)
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func (r *Router) SetTestBalanceMap(balanceMap map[string]*big.Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) setCustomTxDetails(pathTxIdentity *requests.PathTxIdentity, pathTxCustomParams *requests.PathTxCustomParams) error {
|
func (r *Router) setCustomTxDetails(ctx context.Context, pathTxIdentity *requests.PathTxIdentity, pathTxCustomParams *requests.PathTxCustomParams) error {
|
||||||
if pathTxIdentity == nil {
|
if pathTxIdentity == nil {
|
||||||
return ErrTxIdentityNotProvided
|
return ErrTxIdentityNotProvided
|
||||||
}
|
}
|
||||||
@ -164,31 +164,17 @@ func (r *Router) setCustomTxDetails(pathTxIdentity *requests.PathTxIdentity, pat
|
|||||||
return ErrCannotCustomizeIfNoRoute
|
return ErrCannotCustomizeIfNoRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchedFees, err := r.feesManager.SuggestedFees(ctx, pathTxIdentity.ChainID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, path := range r.activeRoutes.Best {
|
for _, path := range r.activeRoutes.Best {
|
||||||
if path.PathIdentity() != pathTxIdentity.PathIdentity() {
|
if path.PathIdentity() != pathTxIdentity.PathIdentity() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if pathTxIdentity.IsApprovalTx {
|
// update the custom params
|
||||||
path.ApprovalGasFeeMode = pathTxCustomParams.GasFeeMode
|
|
||||||
if pathTxCustomParams.GasFeeMode == fees.GasFeeCustom {
|
|
||||||
path.ApprovalTxNonce = (*hexutil.Uint64)(&pathTxCustomParams.Nonce)
|
|
||||||
path.ApprovalGasAmount = pathTxCustomParams.GasAmount
|
|
||||||
path.ApprovalMaxFeesPerGas = pathTxCustomParams.MaxFeesPerGas
|
|
||||||
path.ApprovalBaseFee = (*hexutil.Big)(new(big.Int).Sub(pathTxCustomParams.MaxFeesPerGas.ToInt(), pathTxCustomParams.PriorityFee.ToInt()))
|
|
||||||
path.ApprovalPriorityFee = pathTxCustomParams.PriorityFee
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
path.TxGasFeeMode = pathTxCustomParams.GasFeeMode
|
|
||||||
if pathTxCustomParams.GasFeeMode == fees.GasFeeCustom {
|
|
||||||
path.TxNonce = (*hexutil.Uint64)(&pathTxCustomParams.Nonce)
|
|
||||||
path.TxGasAmount = pathTxCustomParams.GasAmount
|
|
||||||
path.TxMaxFeesPerGas = pathTxCustomParams.MaxFeesPerGas
|
|
||||||
path.TxBaseFee = (*hexutil.Big)(new(big.Int).Sub(pathTxCustomParams.MaxFeesPerGas.ToInt(), pathTxCustomParams.PriorityFee.ToInt()))
|
|
||||||
path.TxPriorityFee = pathTxCustomParams.PriorityFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.lastInputParamsMutex.Lock()
|
r.lastInputParamsMutex.Lock()
|
||||||
if r.lastInputParams.PathTxCustomParams == nil {
|
if r.lastInputParams.PathTxCustomParams == nil {
|
||||||
r.lastInputParams.PathTxCustomParams = make(map[string]*requests.PathTxCustomParams)
|
r.lastInputParams.PathTxCustomParams = make(map[string]*requests.PathTxCustomParams)
|
||||||
@ -196,6 +182,15 @@ func (r *Router) setCustomTxDetails(pathTxIdentity *requests.PathTxIdentity, pat
|
|||||||
r.lastInputParams.PathTxCustomParams[pathTxIdentity.TxIdentityKey()] = pathTxCustomParams
|
r.lastInputParams.PathTxCustomParams[pathTxIdentity.TxIdentityKey()] = pathTxCustomParams
|
||||||
r.lastInputParamsMutex.Unlock()
|
r.lastInputParamsMutex.Unlock()
|
||||||
|
|
||||||
|
// update the path details
|
||||||
|
usedNonces := make(map[uint64]uint64)
|
||||||
|
err = r.evaluateAndUpdatePathDetails(ctx, path, fetchedFees, usedNonces, false, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// inform the client about the changes
|
||||||
|
sendRouterResult(pathTxIdentity.RouterInputParamsUuid, r.activeRoutes, nil)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,14 +202,14 @@ func (r *Router) SetFeeMode(ctx context.Context, pathTxIdentity *requests.PathTx
|
|||||||
return ErrCustomFeeModeCannotBeSetThisWay
|
return ErrCustomFeeModeCannotBeSetThisWay
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.setCustomTxDetails(pathTxIdentity, &requests.PathTxCustomParams{GasFeeMode: feeMode})
|
return r.setCustomTxDetails(ctx, pathTxIdentity, &requests.PathTxCustomParams{GasFeeMode: feeMode})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) SetCustomTxDetails(ctx context.Context, pathTxIdentity *requests.PathTxIdentity, pathTxCustomParams *requests.PathTxCustomParams) error {
|
func (r *Router) SetCustomTxDetails(ctx context.Context, pathTxIdentity *requests.PathTxIdentity, pathTxCustomParams *requests.PathTxCustomParams) error {
|
||||||
if pathTxCustomParams != nil && pathTxCustomParams.GasFeeMode != fees.GasFeeCustom {
|
if pathTxCustomParams != nil && pathTxCustomParams.GasFeeMode != fees.GasFeeCustom {
|
||||||
return ErrOnlyCustomFeeModeCanBeSetThisWay
|
return ErrOnlyCustomFeeModeCanBeSetThisWay
|
||||||
}
|
}
|
||||||
return r.setCustomTxDetails(pathTxIdentity, pathTxCustomParams)
|
return r.setCustomTxDetails(ctx, pathTxIdentity, pathTxCustomParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSuggestedRoutes(
|
func newSuggestedRoutes(
|
||||||
|
@ -195,7 +195,7 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch
|
|||||||
|
|
||||||
if r.lastInputParams.PathTxCustomParams == nil || len(r.lastInputParams.PathTxCustomParams) == 0 {
|
if r.lastInputParams.PathTxCustomParams == nil || len(r.lastInputParams.PathTxCustomParams) == 0 {
|
||||||
// if no custom params are provided, use the initial fee mode
|
// if no custom params are provided, use the initial fee mode
|
||||||
maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(r.lastInputParams.GasFeeMode)
|
maxFeesPerGas, priorityFee, estimatedTime, err := fetchedFees.FeeFor(r.lastInputParams.GasFeeMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -204,31 +204,35 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch
|
|||||||
path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
||||||
path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
||||||
path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee)
|
path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee)
|
||||||
|
path.ApprovalEstimatedTime = estimatedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
path.TxGasFeeMode = r.lastInputParams.GasFeeMode
|
path.TxGasFeeMode = r.lastInputParams.GasFeeMode
|
||||||
path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
||||||
path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
||||||
path.TxPriorityFee = (*hexutil.Big)(priorityFee)
|
path.TxPriorityFee = (*hexutil.Big)(priorityFee)
|
||||||
|
path.TxEstimatedTime = estimatedTime
|
||||||
} else {
|
} else {
|
||||||
if path.ApprovalRequired {
|
if path.ApprovalRequired {
|
||||||
approvalTxIdentityKey := path.TxIdentityKey(true)
|
approvalTxIdentityKey := path.TxIdentityKey(true)
|
||||||
if approvalTxCustomParams, ok := r.lastInputParams.PathTxCustomParams[approvalTxIdentityKey]; ok {
|
if approvalTxCustomParams, ok := r.lastInputParams.PathTxCustomParams[approvalTxIdentityKey]; ok {
|
||||||
path.ApprovalGasFeeMode = approvalTxCustomParams.GasFeeMode
|
path.ApprovalGasFeeMode = approvalTxCustomParams.GasFeeMode
|
||||||
if approvalTxCustomParams.GasFeeMode != fees.GasFeeCustom {
|
if approvalTxCustomParams.GasFeeMode != fees.GasFeeCustom {
|
||||||
maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(approvalTxCustomParams.GasFeeMode)
|
maxFeesPerGas, priorityFee, estimatedTime, err := fetchedFees.FeeFor(approvalTxCustomParams.GasFeeMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
||||||
path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
||||||
path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee)
|
path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee)
|
||||||
|
path.ApprovalEstimatedTime = estimatedTime
|
||||||
} else {
|
} else {
|
||||||
path.ApprovalTxNonce = (*hexutil.Uint64)(&approvalTxCustomParams.Nonce)
|
path.ApprovalTxNonce = (*hexutil.Uint64)(&approvalTxCustomParams.Nonce)
|
||||||
path.ApprovalGasAmount = approvalTxCustomParams.GasAmount
|
path.ApprovalGasAmount = approvalTxCustomParams.GasAmount
|
||||||
path.ApprovalMaxFeesPerGas = approvalTxCustomParams.MaxFeesPerGas
|
path.ApprovalMaxFeesPerGas = approvalTxCustomParams.MaxFeesPerGas
|
||||||
path.ApprovalBaseFee = (*hexutil.Big)(new(big.Int).Sub(approvalTxCustomParams.MaxFeesPerGas.ToInt(), approvalTxCustomParams.PriorityFee.ToInt()))
|
path.ApprovalBaseFee = (*hexutil.Big)(new(big.Int).Sub(approvalTxCustomParams.MaxFeesPerGas.ToInt(), approvalTxCustomParams.PriorityFee.ToInt()))
|
||||||
path.ApprovalPriorityFee = approvalTxCustomParams.PriorityFee
|
path.ApprovalPriorityFee = approvalTxCustomParams.PriorityFee
|
||||||
|
path.ApprovalEstimatedTime = r.feesManager.TransactionEstimatedTimeV2(ctx, path.FromChain.ChainID, path.ApprovalMaxFeesPerGas.ToInt(), path.ApprovalPriorityFee.ToInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,19 +241,21 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch
|
|||||||
if txCustomParams, ok := r.lastInputParams.PathTxCustomParams[txIdentityKey]; ok {
|
if txCustomParams, ok := r.lastInputParams.PathTxCustomParams[txIdentityKey]; ok {
|
||||||
path.TxGasFeeMode = txCustomParams.GasFeeMode
|
path.TxGasFeeMode = txCustomParams.GasFeeMode
|
||||||
if txCustomParams.GasFeeMode != fees.GasFeeCustom {
|
if txCustomParams.GasFeeMode != fees.GasFeeCustom {
|
||||||
maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(txCustomParams.GasFeeMode)
|
maxFeesPerGas, priorityFee, estimatedTime, err := fetchedFees.FeeFor(txCustomParams.GasFeeMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas)
|
||||||
path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee)
|
||||||
path.TxPriorityFee = (*hexutil.Big)(priorityFee)
|
path.TxPriorityFee = (*hexutil.Big)(priorityFee)
|
||||||
|
path.TxEstimatedTime = estimatedTime
|
||||||
} else {
|
} else {
|
||||||
path.TxNonce = (*hexutil.Uint64)(&txCustomParams.Nonce)
|
path.TxNonce = (*hexutil.Uint64)(&txCustomParams.Nonce)
|
||||||
path.TxGasAmount = txCustomParams.GasAmount
|
path.TxGasAmount = txCustomParams.GasAmount
|
||||||
path.TxMaxFeesPerGas = txCustomParams.MaxFeesPerGas
|
path.TxMaxFeesPerGas = txCustomParams.MaxFeesPerGas
|
||||||
path.TxBaseFee = (*hexutil.Big)(new(big.Int).Sub(txCustomParams.MaxFeesPerGas.ToInt(), txCustomParams.PriorityFee.ToInt()))
|
path.TxBaseFee = (*hexutil.Big)(new(big.Int).Sub(txCustomParams.MaxFeesPerGas.ToInt(), txCustomParams.PriorityFee.ToInt()))
|
||||||
path.TxPriorityFee = txCustomParams.PriorityFee
|
path.TxPriorityFee = txCustomParams.PriorityFee
|
||||||
|
path.TxEstimatedTime = r.feesManager.TransactionEstimatedTimeV2(ctx, path.FromChain.ChainID, path.TxMaxFeesPerGas.ToInt(), path.TxPriorityFee.ToInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,15 +342,6 @@ func (r *Router) evaluateAndUpdatePathDetails(ctx context.Context, path *routes.
|
|||||||
path.RequiredTokenBalance = requiredTokenBalance
|
path.RequiredTokenBalance = requiredTokenBalance
|
||||||
path.RequiredNativeBalance = requiredNativeBalance
|
path.RequiredNativeBalance = requiredNativeBalance
|
||||||
|
|
||||||
path.TxEstimatedTime = r.feesManager.TransactionEstimatedTime(ctx, path.FromChain.ChainID, path.TxMaxFeesPerGas.ToInt())
|
|
||||||
if path.ApprovalRequired {
|
|
||||||
if path.TxMaxFeesPerGas.ToInt().Cmp(path.ApprovalMaxFeesPerGas.ToInt()) == 0 {
|
|
||||||
path.ApprovalEstimatedTime = path.TxEstimatedTime
|
|
||||||
} else {
|
|
||||||
path.ApprovalEstimatedTime = r.feesManager.TransactionEstimatedTime(ctx, path.FromChain.ChainID, path.ApprovalMaxFeesPerGas.ToInt())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ type Path struct {
|
|||||||
TxGasAmount uint64 // Gas used for the transaction
|
TxGasAmount uint64 // Gas used for the transaction
|
||||||
TxBonderFees *hexutil.Big // Bonder fees for the transaction - used for Hop bridge (in selected token)
|
TxBonderFees *hexutil.Big // Bonder fees for the transaction - used for Hop bridge (in selected token)
|
||||||
TxTokenFees *hexutil.Big // Token fees for the transaction - used for bridges (represent the difference between the amount in and the amount out, in selected token)
|
TxTokenFees *hexutil.Big // Token fees for the transaction - used for bridges (represent the difference between the amount in and the amount out, in selected token)
|
||||||
TxEstimatedTime fees.TransactionEstimation
|
TxEstimatedTime uint // Estimated time for the transaction in seconds
|
||||||
|
|
||||||
TxFee *hexutil.Big // fee for the transaction (includes tx fee only, doesn't include approval fees, l1 fees, l1 approval fees, token fees or bonders fees, in ETH WEI)
|
TxFee *hexutil.Big // fee for the transaction (includes tx fee only, doesn't include approval fees, l1 fees, l1 approval fees, token fees or bonders fees, in ETH WEI)
|
||||||
TxL1Fee *hexutil.Big // L1 fee for the transaction - used for for transactions placed on L2 chains (in ETH WEI)
|
TxL1Fee *hexutil.Big // L1 fee for the transaction - used for for transactions placed on L2 chains (in ETH WEI)
|
||||||
@ -57,7 +57,7 @@ type Path struct {
|
|||||||
ApprovalBaseFee *hexutil.Big // Base fee for the approval transaction (in ETH WEI)
|
ApprovalBaseFee *hexutil.Big // Base fee for the approval transaction (in ETH WEI)
|
||||||
ApprovalPriorityFee *hexutil.Big // Priority fee for the approval transaction (in ETH WEI)
|
ApprovalPriorityFee *hexutil.Big // Priority fee for the approval transaction (in ETH WEI)
|
||||||
ApprovalGasAmount uint64 // Gas used for the approval transaction
|
ApprovalGasAmount uint64 // Gas used for the approval transaction
|
||||||
ApprovalEstimatedTime fees.TransactionEstimation
|
ApprovalEstimatedTime uint // Estimated time for the approval transaction in seconds
|
||||||
|
|
||||||
ApprovalFee *hexutil.Big // Total fee for the approval transaction (includes approval tx fees only, doesn't include approval l1 fees, in ETH WEI)
|
ApprovalFee *hexutil.Big // Total fee for the approval transaction (includes approval tx fees only, doesn't include approval l1 fees, in ETH WEI)
|
||||||
ApprovalL1Fee *hexutil.Big // L1 fee for the approval transaction - used for for transactions placed on L2 chains (in ETH WEI)
|
ApprovalL1Fee *hexutil.Big // L1 fee for the approval transaction - used for for transactions placed on L2 chains (in ETH WEI)
|
||||||
|
@ -36,7 +36,7 @@ func TestCopyPath(t *testing.T) {
|
|||||||
TxGasAmount: 100,
|
TxGasAmount: 100,
|
||||||
TxBonderFees: (*hexutil.Big)(big.NewInt(100)),
|
TxBonderFees: (*hexutil.Big)(big.NewInt(100)),
|
||||||
TxTokenFees: (*hexutil.Big)(big.NewInt(100)),
|
TxTokenFees: (*hexutil.Big)(big.NewInt(100)),
|
||||||
TxEstimatedTime: fees.TransactionEstimation(100),
|
TxEstimatedTime: 100,
|
||||||
TxFee: (*hexutil.Big)(big.NewInt(100)),
|
TxFee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
TxL1Fee: (*hexutil.Big)(big.NewInt(100)),
|
TxL1Fee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
ApprovalRequired: true,
|
ApprovalRequired: true,
|
||||||
@ -46,7 +46,7 @@ func TestCopyPath(t *testing.T) {
|
|||||||
ApprovalBaseFee: (*hexutil.Big)(big.NewInt(100)),
|
ApprovalBaseFee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
ApprovalPriorityFee: (*hexutil.Big)(big.NewInt(100)),
|
ApprovalPriorityFee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
ApprovalGasAmount: 100,
|
ApprovalGasAmount: 100,
|
||||||
ApprovalEstimatedTime: fees.TransactionEstimation(100),
|
ApprovalEstimatedTime: 100,
|
||||||
ApprovalFee: (*hexutil.Big)(big.NewInt(100)),
|
ApprovalFee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
ApprovalL1Fee: (*hexutil.Big)(big.NewInt(100)),
|
ApprovalL1Fee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
TxTotalFee: (*hexutil.Big)(big.NewInt(100)),
|
TxTotalFee: (*hexutil.Big)(big.NewInt(100)),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user