Skip to content

Commit

Permalink
pass in gas info to fireblocks transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-shim committed Mar 23, 2024
1 parent d57bfdd commit 5f558cd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
5 changes: 4 additions & 1 deletion chainio/clients/fireblocks/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ func TestContractCall(t *testing.T) {
destinationAccountID,
"0",
"0x6057361d00000000000000000000000000000000000000000000000000000000000f4240",
"",
"", // replaceTxByHash
"", // gasLimit
"", // maxFee
"", // priorityFee
fireblocks.FeeLevelHigh,
)
resp, err := c.ContractCall(context.Background(), req)
Expand Down
14 changes: 13 additions & 1 deletion chainio/clients/fireblocks/contract_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,17 @@ type ContractCallRequest struct {
// In case a transaction is stuck, specify the hash of the stuck transaction to replace it
// by this transaction with a higher fee, or to replace it with this transaction with a zero fee and drop it from the blockchain.
ReplaceTxByHash string `json:"replaceTxByHash"`
gasLimit string `json:"gasLimit"`
// MaxFee and PriorityFee are the maximum and priority fees for the transaction.
// If the transaction is stuck, the Fireblocks platform will replace the transaction with a new one with a higher fee.
// These fields are required if FeeLevel is not specified.
MaxFee string `json:"maxFee"`
PriorityFee string `json:"priorityFee"`
// FeeLevel is the fee level for the transaction which Fireblocks estimates based on the current network conditions.
// The fee level can be HIGH, MEDIUM, or LOW.
// If MaxFee and PriorityFee are not specified, the Fireblocks platform will use the default fee level MEDIUM.
// Ref: https://developers.fireblocks.com/docs/gas-estimation#estimated-network-fee
FeeLevel FeeLevel `json:"feeLevel"`
// TODO: add maxFee and priorityFee
}

type ContractCallResponse struct {
Expand All @@ -63,6 +69,9 @@ func NewContractCallRequest(
amount string,
calldata string,
replaceTxByHash string,
gasLimit string,
maxFee string,
priorityFee string,
feeLevel FeeLevel,
) *ContractCallRequest {
return &ContractCallRequest{
Expand All @@ -83,6 +92,9 @@ func NewContractCallRequest(
Calldata: calldata,
},
ReplaceTxByHash: replaceTxByHash,
gasLimit: gasLimit,
MaxFee: maxFee,
PriorityFee: priorityFee,
FeeLevel: feeLevel,
}
}
Expand Down
24 changes: 22 additions & 2 deletions chainio/clients/wallet/fireblocks_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"math/big"
"strconv"
"sync"

"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
Expand Down Expand Up @@ -155,6 +156,23 @@ func (t *fireblocksWallet) SendTransaction(ctx context.Context, tx *types.Transa
}
}

gasLimit := ""
if tx.Gas() > 0 {
gasLimit = strconv.FormatUint(tx.Gas(), 10)
}

// if the gas fees are specified in the transaction, use them.
// Otherwise, use the default "HIGH" gas price estimated by Fireblocks
maxFee := ""
priorityFee := ""
feeLevel := fireblocks.FeeLevel("")
if tx.GasFeeCap().Cmp(big.NewInt(0)) > 0 && tx.GasTipCap().Cmp(big.NewInt(0)) > 0 {
maxFee = tx.GasFeeCap().String()
priorityFee = tx.GasTipCap().String()
} else {
feeLevel = fireblocks.FeeLevelHigh
}

req := fireblocks.NewContractCallRequest(
tx.Hash().Hex(),
assetID,
Expand All @@ -163,8 +181,10 @@ func (t *fireblocksWallet) SendTransaction(ctx context.Context, tx *types.Transa
tx.Value().String(), // amount
hexutil.Encode(tx.Data()), // calldata
replaceTxByHash, // replaceTxByHash
// TODO: make this configurable
fireblocks.FeeLevelHigh, // feeLevel
gasLimit,
maxFee,
priorityFee,
feeLevel,
)
res, err := t.fireblocksClient.ContractCall(ctx, req)
if err != nil {
Expand Down
29 changes: 18 additions & 11 deletions chainio/clients/wallet/fireblocks_wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,35 +235,42 @@ func TestSendTransactionReplaceTx(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "1234", txID)

newTx := types.NewTransaction(
0, // nonce
common.HexToAddress(contractAddress), // to
big.NewInt(0), // value
100000, // gas
big.NewInt(100), // gasPrice
common.Hex2Bytes("0x6057361d00000000000000000000000000000000000000000000000000000000000f4240"), // data
)
addr := common.HexToAddress(contractAddress)
gasLimit := uint64(1000000)
baseTx := &types.DynamicFeeTx{
To: &addr,
Nonce: 0,
GasFeeCap: big.NewInt(10),
GasTipCap: big.NewInt(1),
Gas: gasLimit,
Value: big.NewInt(0),
Data: common.Hex2Bytes("0x6057361d00000000000000000000000000000000000000000000000000000000000f4240"),
}
replacementTx := types.NewTx(baseTx)
expectedTxHash := "0xdeadbeef"
fireblocksClient.EXPECT().GetTransaction(gomock.Any(), "1234").Return(&fireblocks.Transaction{
ID: expectedTxHash,
Status: fireblocks.Completed,
TxHash: expectedTxHash,
}, nil)
fireblocksClient.EXPECT().ContractCall(gomock.Any(), fireblocks.NewContractCallRequest(
newTx.Hash().Hex(),
replacementTx.Hash().Hex(),
"ETH_TEST3",
"vaultAccountID",
"contractID",
"0",
"0x",
expectedTxHash,
fireblocks.FeeLevelHigh,
"1000000", // gasLimit
"10", // maxFee
"1", // priorityFee
"", // feeLevel
)).Return(&fireblocks.ContractCallResponse{
ID: "5678",
Status: fireblocks.Confirming,
}, nil)
// send another tx with the same nonce
txID, err = sender.SendTransaction(context.Background(), newTx)
txID, err = sender.SendTransaction(context.Background(), replacementTx)
assert.NoError(t, err)
assert.Equal(t, "5678", txID)
}
Expand Down

0 comments on commit 5f558cd

Please sign in to comment.