Skip to content

Commit

Permalink
addressed comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinssgh committed Mar 1, 2024
1 parent 68fff48 commit aca80ad
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 242 deletions.
7 changes: 3 additions & 4 deletions zetaclient/bitcoin/bitcoin_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"sync"
"testing"

"github.com/zeta-chain/zetacore/zetaclient/testutils/mock"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg"
Expand All @@ -21,13 +19,14 @@ import (
crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types"
observertypes "github.com/zeta-chain/zetacore/x/observer/types"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
"github.com/zeta-chain/zetacore/zetaclient/testutils/stub"
)

func MockBTCClientMainnet() *BTCChainClient {
return &BTCChainClient{
chain: common.BtcMainnetChain(),
zetaClient: mock.NewZetaCoreBridge(),
Tss: mock.NewTSSMainnet(),
zetaClient: stub.NewZetaCoreBridge(),
Tss: stub.NewTSSMainnet(),
}
}

Expand Down
187 changes: 187 additions & 0 deletions zetaclient/evm/base_transaction_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package evm

import (
"context"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"math/big"

ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/rs/zerolog"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/x/crosschain/types"
"github.com/zeta-chain/zetacore/zetaclient/interfaces"
)

const (
MinGasLimit = 100_000
MaxGasLimit = 1_000_000
)

// BaseTransactionData is a data structure containing input fields used to construct each type of transaction.
// This is populated using cctx and other input parameters passed to TryProcessOutTx
type BaseTransactionData struct {
srcChainID *big.Int
toChainID *big.Int
sender ethcommon.Address
to ethcommon.Address
asset ethcommon.Address
amount *big.Int
gasPrice *big.Int
gasLimit uint64
message []byte
nonce uint64
height uint64

// cmd field is used to determine whether to execute ERC20 whitelist or migrate TSS funds given that the coin type
// from the cctx is CMD
cmd string

// params field is used to pass input parameters for command requests, currently it is used to pass the ERC20
// contract address when a whitelist command is requested
params string

// sendHash field is the inbound message digest that is sent to the destination contract
sendHash [32]byte

// outboundParams field contains data detailing the receiver chain and outbound transaction
outboundParams *types.OutboundTxParams
}

// SetChainAndSender populates the destination address and Chain ID based on the status of the cross chain tx
// returns true if transaction should be skipped
// returns false otherwise
func (txData *BaseTransactionData) SetChainAndSender(cctx *types.CrossChainTx, logger zerolog.Logger) bool {
switch cctx.CctxStatus.Status {
case types.CctxStatus_PendingRevert:
txData.to = ethcommon.HexToAddress(cctx.InboundTxParams.Sender)
txData.toChainID = big.NewInt(cctx.InboundTxParams.SenderChainId)
logger.Info().Msgf("Abort: reverting inbound")
case types.CctxStatus_PendingOutbound:
txData.to = ethcommon.HexToAddress(cctx.GetCurrentOutTxParam().Receiver)
txData.toChainID = big.NewInt(cctx.GetCurrentOutTxParam().ReceiverChainId)
default:
logger.Info().Msgf("Transaction doesn't need to be processed status: %d", cctx.CctxStatus.Status)
return true
}
return false
}

// SetupGas sets the gas limit and price
func (txData *BaseTransactionData) SetupGas(
cctx *types.CrossChainTx,
logger zerolog.Logger,
client interfaces.EVMRPCClient,
chain *common.Chain,
) error {

txData.gasLimit = cctx.GetCurrentOutTxParam().OutboundTxGasLimit
if txData.gasLimit < MinGasLimit {
txData.gasLimit = MinGasLimit
logger.Warn().Msgf("gasLimit %d is too low; set to %d", cctx.GetCurrentOutTxParam().OutboundTxGasLimit, txData.gasLimit)
}
if txData.gasLimit > MaxGasLimit {
txData.gasLimit = MaxGasLimit
logger.Warn().Msgf("gasLimit %d is too high; set to %d", cctx.GetCurrentOutTxParam().OutboundTxGasLimit, txData.gasLimit)

Check warning on line 87 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L86-L87

Added lines #L86 - L87 were not covered by tests
}

// use dynamic gas price for ethereum chains.
// The code below is a fix for https://github.com/zeta-chain/node/issues/1085
// doesn't close directly the issue because we should determine if we want to keep using SuggestGasPrice if no OutboundTxGasPrice
// we should possibly remove it completely and return an error if no OutboundTxGasPrice is provided because it means no fee is processed on ZetaChain
specified, ok := new(big.Int).SetString(cctx.GetCurrentOutTxParam().OutboundTxGasPrice, 10)
if !ok {
if common.IsEthereumChain(chain.ChainId) {
suggested, err := client.SuggestGasPrice(context.Background())
if err != nil {
return errors.Join(err, fmt.Errorf("cannot get gas price from chain %s ", chain))

Check warning on line 99 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L97-L99

Added lines #L97 - L99 were not covered by tests
}
txData.gasPrice = roundUpToNearestGwei(suggested)

Check warning on line 101 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L101

Added line #L101 was not covered by tests
} else {
return fmt.Errorf("cannot convert gas price %s ", cctx.GetCurrentOutTxParam().OutboundTxGasPrice)
}
} else {
txData.gasPrice = specified
}
return nil
}

// SetTransactionData populates transaction input fields parsed from the cctx and other parameters
// returns
// bool (skipTx) - if the transaction doesn't qualify to be processed the function will return true, meaning that this
//
// cctx will be skipped and false otherwise.
//
// error
func (txData *BaseTransactionData) SetTransactionData(
cctx *types.CrossChainTx,
evmClient *ChainClient,
evmRPC interfaces.EVMRPCClient,
logger zerolog.Logger,
) (bool, error) {

txData.outboundParams = cctx.GetCurrentOutTxParam()
txData.amount = cctx.GetCurrentOutTxParam().Amount.BigInt()
txData.nonce = cctx.GetCurrentOutTxParam().OutboundTxTssNonce
txData.sender = ethcommon.HexToAddress(cctx.InboundTxParams.Sender)
txData.srcChainID = big.NewInt(cctx.InboundTxParams.SenderChainId)
txData.asset = ethcommon.HexToAddress(cctx.InboundTxParams.Asset)

skipTx := txData.SetChainAndSender(cctx, logger)
if skipTx {
return true, nil

Check warning on line 134 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L134

Added line #L134 was not covered by tests
}

toChain := common.GetChainFromChainID(txData.toChainID.Int64())
if toChain == nil {
return true, fmt.Errorf("unknown chain: %d", txData.toChainID.Int64())

Check warning on line 139 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L139

Added line #L139 was not covered by tests
}

// Get nonce, Early return if the cctx is already processed
nonce := cctx.GetCurrentOutTxParam().OutboundTxTssNonce
included, confirmed, err := evmClient.IsSendOutTxProcessed(cctx, logger)
if err != nil {
return true, errors.New("IsSendOutTxProcessed failed")

Check warning on line 146 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L146

Added line #L146 was not covered by tests
}
if included || confirmed {
logger.Info().Msgf("CCTX already processed; exit signer")
return true, nil

Check warning on line 150 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L149-L150

Added lines #L149 - L150 were not covered by tests
}

// Set up gas limit and gas price
err = txData.SetupGas(cctx, logger, evmRPC, toChain)
if err != nil {
return true, err

Check warning on line 156 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L156

Added line #L156 was not covered by tests
}

// Get sendHash
logger.Info().Msgf("chain %s minting %d to %s, nonce %d, finalized zeta bn %d", toChain, cctx.InboundTxParams.Amount, txData.to.Hex(), nonce, cctx.InboundTxParams.InboundTxFinalizedZetaHeight)
sendHash, err := hex.DecodeString(cctx.Index[2:]) // remove the leading 0x
if err != nil || len(sendHash) != 32 {
return true, fmt.Errorf("decode CCTX %s error", cctx.Index)

Check warning on line 163 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L163

Added line #L163 was not covered by tests
}
copy(txData.sendHash[:32], sendHash[:32])

// In case there is a pending transaction, make sure this keysign is a transaction replacement
pendingTx := evmClient.GetPendingTx(nonce)
if pendingTx != nil {
if txData.gasPrice.Cmp(pendingTx.GasPrice()) > 0 {
logger.Info().Msgf("replace pending outTx %s nonce %d using gas price %d", pendingTx.Hash().Hex(), nonce, txData.gasPrice)
} else {
logger.Info().Msgf("please wait for pending outTx %s nonce %d to be included", pendingTx.Hash().Hex(), nonce)
return true, nil

Check warning on line 174 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L170-L174

Added lines #L170 - L174 were not covered by tests
}
}

// Base64 decode message
if cctx.GetCurrentOutTxParam().CoinType != common.CoinType_Cmd {
txData.message, err = base64.StdEncoding.DecodeString(cctx.RelayedMessage)
if err != nil {
logger.Err(err).Msgf("decode CCTX.Message %s error", cctx.RelayedMessage)

Check warning on line 182 in zetaclient/evm/base_transaction_data.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/evm/base_transaction_data.go#L182

Added line #L182 was not covered by tests
}
}

return false, nil
}
Loading

0 comments on commit aca80ad

Please sign in to comment.