Skip to content

Commit

Permalink
feat: add gas limit multiplication (#358)
Browse files Browse the repository at this point in the history
* feat: add gas limit multiplication

* fix: rotator test
  • Loading branch information
byte-bandit authored Mar 7, 2024
1 parent a5d1b58 commit ee6a927
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
49 changes: 42 additions & 7 deletions chain/evm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ type mevClient interface {

//go:generate mockery --name=ethClientConn --inpackage --testonly
type ethClientConn interface {
bind.ContractBackend
ethClienter
TransactionByHash(ctx context.Context, hash common.Hash) (tx *etherumtypes.Transaction, isPending bool, err error)
HeaderByNumber(ctx context.Context, number *big.Int) (*etherumtypes.Header, error)
BlockByHash(ctx context.Context, hash common.Hash) (*etherumtypes.Block, error)
Expand Down Expand Up @@ -170,6 +170,11 @@ type CompassBindingFilterer interface {
WatchValsetUpdated(opts *bind.WatchOpts, sink chan<- *compassABI.CompassValsetUpdated) (event.Subscription, error)
}

//go:generate mockery --name=ethClienter --inpackage --testonly
type ethClienter interface {
bind.ContractBackend
}

//go:generate mockery --name=CompassBinding
type CompassBinding interface {
CompassBindingCaller
Expand Down Expand Up @@ -217,11 +222,6 @@ func (c *Client) newCompass(addr common.Address) (CompassBinding, error) {
return compassABI.NewCompass(addr, c.conn)
}

//go:generate mockery --name=ethClienter --inpackage --testonly
type ethClienter interface {
bind.ContractBackend
}

type executeSmartContractIn struct {
ethClient ethClienter
mevClient mevClient
Expand Down Expand Up @@ -333,7 +333,14 @@ func callSmartContract(
txOpts.From = args.signingAddr

// https://github.com/VolumeFi/paloma/issues/1048
txOpts.GasLimit = uint64(float64(txOpts.GasLimit) * 1.1)
value := new(big.Int)
gasFeeCap := new(big.Int)
if args.txType == 2 {
gasFeeCap = gasPrice
}
gasLimit, err := estimateGasLimit(ctx, args.ethClient, txOpts, &args.contract, packedBytes, gasPrice, gasTipCap, gasFeeCap, value)
whoops.Assert(err)
txOpts.GasLimit = uint64(float64(gasLimit) * 1.2)

if args.txType == 2 {
txOpts.GasFeeCap = gasPrice
Expand Down Expand Up @@ -406,6 +413,34 @@ func callSmartContract(
})
}

// Copied from https://github.com/ethereum/go-ethereum/blob/e5d5e09faae48dac3723634e2b1813e4f2e89535/accounts/abi/bind/base.go#L357
// since the original implementation is not exported, but we need access to the gas limit to multiply it
// before we send the TX.
// More detail: https://github.com/VolumeFi/paloma/issues/1048
// And: https://github.com/VolumeFi/paloma/issues/1158#issuecomment-1896488916
func estimateGasLimit(ctx context.Context, c ethClienter, opts *bind.TransactOpts, contract *ethcommon.Address, input []byte, gasPrice, gasTipCap, gasFeeCap, value *big.Int) (uint64, error) {
if contract != nil {
// Gas estimation cannot succeed without code for method invocations.
if code, err := c.PendingCodeAt(ctx, *contract); err != nil {
return 0, err
} else if len(code) == 0 {
return 0, bind.ErrNoCode
}
}

msg := ethereum.CallMsg{
From: opts.From,
To: contract,
GasPrice: gasPrice,
GasTipCap: gasTipCap,
GasFeeCap: gasFeeCap,
Value: value,
Data: input,
}

return c.EstimateGas(ctx, msg)
}

func (c *Client) sign(ctx context.Context, bytes []byte) ([]byte, error) {
return c.keystore.SignHash(
accounts.Account{Address: c.addr},
Expand Down
2 changes: 1 addition & 1 deletion chain/evm/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func TestExecutingSmartContract(t *testing.T) {
ethMock.On("EstimateGas", mock.Anything, mock.Anything).Return(uint64(222), nil)

mevMock := newMockMevClient(t)
mevMock.On("Relay", mock.Anything, mock.Anything, mock.Anything).Return(common.HexToHash("0xb19cc052f5066cb445ea09461d99df913f6938fc825676e645f40d5d24abddda"), nil)
mevMock.On("Relay", mock.Anything, mock.Anything, mock.Anything).Return(common.HexToHash("0xde13fda4e25fc73f1d7f3b3e7652a56a0d0a8a6a361dcaec4c8c77f3720a05d1"), nil)

args.ethClient = ethMock
args.mevClient = mevMock
Expand Down
2 changes: 1 addition & 1 deletion util/rotator/rotator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func Test_Rotator_RotateKeys(t *testing.T) {
wg := &sync.WaitGroup{}

// Confirm rotator is concurrency safe
wg.Add(3 * 99)
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
for i := 1; i < 100; i++ {
r.RotateKeys(context.Background())
Expand Down

0 comments on commit ee6a927

Please sign in to comment.