Skip to content

Commit

Permalink
Use gasFeeCap formula
Browse files Browse the repository at this point in the history
  • Loading branch information
swift1337 committed Aug 6, 2024
1 parent 4d6ed2c commit 2260925
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 62 deletions.
51 changes: 38 additions & 13 deletions zetaclient/chains/evm/signer/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/big"

"cosmossdk.io/math"
"github.com/pkg/errors"
"github.com/rs/zerolog"

Expand All @@ -24,34 +25,58 @@ const (
//
// However, this doesn't affect tx creation nor broadcasting
type Gas struct {
Limit uint64
limit uint64

// This is a "total" gasPrice per 1 unit of gas.
Price *big.Int
price *big.Int

// PriorityFee a fee paid directly to validators.
PriorityFee *big.Int
priorityFee *big.Int
}

func (g Gas) validate() error {
switch {
case g.Limit == 0:
case g.limit == 0:
return errors.New("gas limit is zero")
case g.Price == nil:
return errors.New("max fee per unit is nil")
case g.PriorityFee == nil:
case g.price == nil:
return errors.New("gas price per unit is nil")
case g.priorityFee == nil:
return errors.New("priority fee per unit is nil")

Check warning on line 44 in zetaclient/chains/evm/signer/gas.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/gas.go#L39-L44

Added lines #L39 - L44 were not covered by tests
default:
return nil
}
}

// isLegacy determines whether the gas is meant for LegacyTx{} (pre EIP-1559)
// IsLegacy determines whether the gas is meant for LegacyTx{} (pre EIP-1559)
// or DynamicFeeTx{} (post EIP-1559).
//
// Returns true if priority fee is <= 0.
func (g Gas) isLegacy() bool {
return g.PriorityFee.Sign() < 1
func (g Gas) IsLegacy() bool {
return g.priorityFee.Sign() < 1
}

func (g Gas) Limit() uint64 {
return g.limit
}

// GasPrice returns the gas price for legacy transactions.
func (g Gas) GasPrice() *big.Int {
return g.price
}

// PriorityFee returns the priority fee for EIP-1559 transactions.
func (g Gas) PriorityFee() *big.Int {
return g.priorityFee
}

// GasFeeCap returns the gas fee cap for EIP-1559 transactions.
// heuristic of `2*baseFee + gasTipCap` is used. And because baseFee = `gasPrice - priorityFee`,
// it's `2*(gasPrice - priorityFee) + priorityFee` => `2*gasPrice - priorityFee`
func (g Gas) GasFeeCap() *big.Int {
return math.NewUintFromBigInt(g.price).
MulUint64(2).
Sub(math.NewUintFromBigInt(g.priorityFee)).
BigInt()
}

func gasFromCCTX(cctx *types.CrossChainTx, logger zerolog.Logger) (Gas, error) {
Expand Down Expand Up @@ -89,9 +114,9 @@ func gasFromCCTX(cctx *types.CrossChainTx, logger zerolog.Logger) (Gas, error) {
}

return Gas{
Limit: limit,
Price: gasPrice,
PriorityFee: priorityFee,
limit: limit,
price: gasPrice,
priorityFee: priorityFee,
}, nil
}

Expand Down
53 changes: 29 additions & 24 deletions zetaclient/chains/evm/signer/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/zeta-chain/zetacore/x/crosschain/types"
)

func Test_makeGasFromCCTX(t *testing.T) {
func TestGasFromCCTX(t *testing.T) {
logger := zerolog.New(zerolog.NewTestWriter(t))

makeCCTX := func(gasLimit uint64, price, priorityFee string) *types.CrossChainTx {
Expand All @@ -32,59 +32,63 @@ func Test_makeGasFromCCTX(t *testing.T) {
name: "legacy: gas is too low",
cctx: makeCCTX(minGasLimit-200, gwei(2).String(), ""),
assert: func(t *testing.T, g Gas) {
assert.True(t, g.isLegacy())
assert.True(t, g.IsLegacy())
assertGasEquals(t, Gas{
Limit: minGasLimit,
PriorityFee: gwei(0),
Price: gwei(2),
limit: minGasLimit,
price: gwei(2),
priorityFee: gwei(0),
}, g)
},
},
{
name: "london: gas is too low",
cctx: makeCCTX(minGasLimit-200, gwei(2).String(), gwei(1).String()),
assert: func(t *testing.T, g Gas) {
assert.False(t, g.isLegacy())
assert.False(t, g.IsLegacy())
assertGasEquals(t, Gas{
Limit: minGasLimit,
Price: gwei(2),
PriorityFee: gwei(1),
limit: minGasLimit,
price: gwei(2),
priorityFee: gwei(1),
}, g)

// gasPrice=2, priorityFee=1, so baseFee=1
// gasFeeCap = 2*baseFee + priorityFee = 2 + 1 = 3
assert.Equal(t, gwei(3).Int64(), g.GasFeeCap().Int64())
},
},
{
name: "pre London gas logic",
cctx: makeCCTX(minGasLimit+100, gwei(3).String(), ""),
assert: func(t *testing.T, g Gas) {
assert.True(t, g.isLegacy())
assert.True(t, g.IsLegacy())
assertGasEquals(t, Gas{
Limit: 100_100,
Price: gwei(3),
PriorityFee: gwei(0),
limit: 100_100,
price: gwei(3),
priorityFee: gwei(0),
}, g)
},
},
{
name: "post London gas logic",
cctx: makeCCTX(minGasLimit+200, gwei(4).String(), gwei(1).String()),
assert: func(t *testing.T, g Gas) {
assert.False(t, g.isLegacy())
assert.False(t, g.IsLegacy())
assertGasEquals(t, Gas{
Limit: 100_200,
Price: gwei(4),
PriorityFee: gwei(1),
limit: 100_200,
price: gwei(4),
priorityFee: gwei(1),
}, g)
},
},
{
name: "gas is too high, force to the ceiling",
cctx: makeCCTX(maxGasLimit+200, gwei(4).String(), gwei(1).String()),
assert: func(t *testing.T, g Gas) {
assert.False(t, g.isLegacy())
assert.False(t, g.IsLegacy())
assertGasEquals(t, Gas{
Limit: maxGasLimit,
Price: gwei(4),
PriorityFee: gwei(1),
limit: maxGasLimit,
price: gwei(4),
priorityFee: gwei(1),
}, g)
},
},
Expand Down Expand Up @@ -123,9 +127,10 @@ func Test_makeGasFromCCTX(t *testing.T) {
}

func assertGasEquals(t *testing.T, expected, actual Gas) {
assert.Equal(t, int64(expected.Limit), int64(actual.Limit), "gas limit")
assert.Equal(t, expected.Price.Int64(), actual.Price.Int64(), "max fee per unit")
assert.Equal(t, expected.PriorityFee.Int64(), actual.PriorityFee.Int64(), "priority fee per unit")
assert.Equal(t, int64(expected.Limit()), int64(actual.Limit()), "gas limit")
assert.Equal(t, expected.GasPrice().Int64(), actual.GasPrice().Int64(), "gas price")
assert.Equal(t, expected.GasFeeCap().Int64(), actual.GasFeeCap().Int64(), "max fee cap")
assert.Equal(t, expected.PriorityFee().Int64(), actual.PriorityFee().Int64(), "priority fee")
}

func gwei(i int64) *big.Int {
Expand Down
6 changes: 3 additions & 3 deletions zetaclient/chains/evm/signer/outbound_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ func NewOutboundData(
Uint64("cctx.pending_tx_nonce", nonce)

Check warning on line 95 in zetaclient/chains/evm/signer/outbound_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/outbound_data.go#L93-L95

Added lines #L93 - L95 were not covered by tests

// new gas price is less or equal to pending tx gas
if gas.Price.Cmp(tx.GasPrice()) <= 0 {
if gas.GasPrice().Cmp(tx.GasPrice()) <= 0 {
evt.Msg("Please wait for pending outbound to be included in the block")

Check warning on line 99 in zetaclient/chains/evm/signer/outbound_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/outbound_data.go#L98-L99

Added lines #L98 - L99 were not covered by tests
return nil, true, nil
}

evt.
Uint64("cctx.gas_price", gas.Price.Uint64()).
Uint64("cctx.priority_fee", gas.PriorityFee.Uint64()).
Uint64("cctx.gas_price", gas.GasPrice().Uint64()).
Uint64("cctx.priority_fee", gas.PriorityFee().Uint64()).
Msg("Replacing pending outbound transaction with higher gas fees")

Check warning on line 106 in zetaclient/chains/evm/signer/outbound_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/outbound_data.go#L103-L106

Added lines #L103 - L106 were not covered by tests
}

Expand Down
4 changes: 2 additions & 2 deletions zetaclient/chains/evm/signer/outbound_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func TestNewOutboundData(t *testing.T) {
assert.NotEmpty(t, out.nonce)
assert.NotEmpty(t, out.height)
assert.NotEmpty(t, out.gas)
assert.True(t, out.gas.isLegacy())
assert.Equal(t, uint64(minGasLimit), out.gas.Limit)
assert.True(t, out.gas.IsLegacy())
assert.Equal(t, uint64(minGasLimit), out.gas.Limit())

assert.Empty(t, out.message)
assert.NotEmpty(t, out.cctxIndex)
Expand Down
32 changes: 16 additions & 16 deletions zetaclient/chains/evm/signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,13 @@ func newTx(
return nil, errors.Wrap(err, "invalid gas parameters")

Check warning on line 217 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L217

Added line #L217 was not covered by tests
}

if gas.isLegacy() {
if gas.IsLegacy() {
return ethtypes.NewTx(&ethtypes.LegacyTx{
To: &to,
Value: amount,
Data: data,
GasPrice: gas.Price,
Gas: gas.Limit,
GasPrice: gas.GasPrice(),
Gas: gas.Limit(),
Nonce: nonce,
}), nil
}
Expand All @@ -233,9 +233,9 @@ func newTx(
To: &to,
Value: amount,
Data: data,
GasFeeCap: gas.Price,
GasTipCap: gas.PriorityFee,
Gas: gas.Limit,
GasFeeCap: gas.GasFeeCap(),
GasTipCap: gas.PriorityFee(),
Gas: gas.Limit(),
Nonce: nonce,
}), nil
}
Expand Down Expand Up @@ -331,7 +331,7 @@ func (signer *Signer) SignRevertTx(ctx context.Context, txData *OutboundData) (*

// SignCancelTx signs a transaction from TSS address to itself with a zero amount in order to increment the nonce
func (signer *Signer) SignCancelTx(ctx context.Context, txData *OutboundData) (*ethtypes.Transaction, error) {
txData.gas.Limit = evm.EthTransferGasLimit
txData.gas.limit = evm.EthTransferGasLimit
tx, _, _, err := signer.Sign(
ctx,
nil,
Expand All @@ -350,7 +350,7 @@ func (signer *Signer) SignCancelTx(ctx context.Context, txData *OutboundData) (*

// SignWithdrawTx signs a withdrawal transaction sent from the TSS address to the destination
func (signer *Signer) SignWithdrawTx(ctx context.Context, txData *OutboundData) (*ethtypes.Transaction, error) {
txData.gas.Limit = evm.EthTransferGasLimit
txData.gas.limit = evm.EthTransferGasLimit
tx, _, _, err := signer.Sign(
ctx,
nil,
Expand Down Expand Up @@ -507,7 +507,7 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),
)
tx, err = signer.SignWithdrawTx(ctx, txData)
case coin.CoinType_ERC20:
Expand All @@ -516,7 +516,7 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 519 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L519

Added line #L519 was not covered by tests
)
tx, err = signer.SignERC20WithdrawTx(ctx, txData)
case coin.CoinType_Zeta:
Expand All @@ -525,7 +525,7 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 528 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L528

Added line #L528 was not covered by tests
)
tx, err = signer.SignOutbound(ctx, txData)
}
Expand All @@ -540,7 +540,7 @@ func (signer *Signer) TryProcessOutbound(
"SignRevertTx: %d => %d, nonce %d, gasPrice %d",
cctx.InboundParams.SenderChainId,
toChain.ID(), cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 543 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L543

Added line #L543 was not covered by tests
)
txData.srcChainID = big.NewInt(cctx.OutboundParams[0].ReceiverChainId)
txData.toChainID = big.NewInt(cctx.GetCurrentOutboundParam().ReceiverChainId)
Expand All @@ -551,15 +551,15 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 554 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L554

Added line #L554 was not covered by tests
)
tx, err = signer.SignWithdrawTx(ctx, txData)
case coin.CoinType_ERC20:
logger.Info().Msgf("SignERC20WithdrawTx: %d => %d, nonce %d, gasPrice %d",
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 562 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L562

Added line #L562 was not covered by tests
)
tx, err = signer.SignERC20WithdrawTx(ctx, txData)
}
Expand All @@ -573,7 +573,7 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 576 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L576

Added line #L576 was not covered by tests
)
txData.srcChainID = big.NewInt(cctx.OutboundParams[0].ReceiverChainId)
txData.toChainID = big.NewInt(cctx.GetCurrentOutboundParam().ReceiverChainId)
Expand All @@ -589,7 +589,7 @@ func (signer *Signer) TryProcessOutbound(
cctx.InboundParams.SenderChainId,
toChain.ID(),
cctx.GetCurrentOutboundParam().TssNonce,
txData.gas.Price,
txData.gas.GasPrice(),

Check warning on line 592 in zetaclient/chains/evm/signer/signer.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/evm/signer/signer.go#L592

Added line #L592 was not covered by tests
)
tx, err = signer.SignOutbound(ctx, txData)
if err != nil {
Expand Down
9 changes: 5 additions & 4 deletions zetaclient/chains/evm/signer/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,10 @@ func TestSigner_SignOutbound(t *testing.T) {
t.Run("SignOutbound - should successfully sign DynamicFeeTx", func(t *testing.T) {
// ARRANGE
const (
gwei = 1_000_000_000
priorityFee = 1 * gwei
gasPrice = 3 * gwei
gwei = 1_000_000_000
priorityFee = 1 * gwei
gasPrice = 3 * gwei
londonGasFeeCap = 2*gasPrice - priorityFee
)

// Given a CCTX with gas price and priority fee
Expand All @@ -256,7 +257,7 @@ func TestSigner_SignOutbound(t *testing.T) {
assert.Equal(t, ethtypes.DynamicFeeTxType, int(tx.Type()))

// check that the gasPrice & priorityFee are set correctly
assert.Equal(t, int64(gasPrice), tx.GasFeeCap().Int64())
assert.Equal(t, int64(londonGasFeeCap), tx.GasFeeCap().Int64())
assert.Equal(t, int64(priorityFee), tx.GasTipCap().Int64())
})
}
Expand Down

0 comments on commit 2260925

Please sign in to comment.