From 60f1a5b2fec835333973af12fb6ae723aeccb49e Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Fri, 19 Jan 2024 18:01:01 -0600 Subject: [PATCH] fix: some necessary code refactor for banned address and bug fix during refactor (#1603) --- changelog.md | 1 + zetaclient/btc_signer.go | 4 +- zetaclient/evm_client.go | 56 +++++++++++----------- zetaclient/inbound_tracker.go | 69 ++++++++++++++++----------- zetaclient/utils.go | 87 ++++++++++++++++++++--------------- 5 files changed, 123 insertions(+), 94 deletions(-) diff --git a/changelog.md b/changelog.md index fdb0f879d2..9b128de51b 100644 --- a/changelog.md +++ b/changelog.md @@ -28,6 +28,7 @@ ### Features * [1591](https://github.com/zeta-chain/node/pull/1591) - support lower gas limit for voting on inbound and outbound transactions +* [1592](https://github.com/zeta-chain/node/issues/1592) - check inbound tracker tx hash against Tss address and some refactor on inTx observation ## Version: v12.0.0 diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index d175c9af71..ba493a9fce 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -119,11 +119,11 @@ func (signer *BTCSigner) SignWithdrawTx( signer.logger.Info().Msgf("sizeLimit %d is less than txSize %d for nonce %d", sizeLimit, txSize, nonce) } if txSize < outTxBytesMin { // outbound shouldn't be blocked a low sizeLimit - signer.logger.Warn().Msgf("sizeLimit %d is less than outTxBytesMin %d; use outTxBytesMin", sizeLimit, outTxBytesMin) + signer.logger.Warn().Msgf("txSize %d is less than outTxBytesMin %d; use outTxBytesMin", txSize, outTxBytesMin) txSize = outTxBytesMin } if txSize > outTxBytesMax { // in case of accident - signer.logger.Warn().Msgf("sizeLimit %d is greater than outTxBytesMax %d; use outTxBytesMax", sizeLimit, outTxBytesMax) + signer.logger.Warn().Msgf("txSize %d is greater than outTxBytesMax %d; use outTxBytesMax", txSize, outTxBytesMax) txSize = outTxBytesMax } diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index d9cda1c1eb..aefc94fdfc 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -1,7 +1,6 @@ package zetaclient import ( - "bytes" "context" "fmt" "math" @@ -980,13 +979,11 @@ func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { if event.Raw.BlockNumber > beingScanned { beingScanned = event.Raw.BlockNumber } - msg, err := ob.GetInboundVoteMsgForZetaSentEvent(event) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( - "observeZetaSent: error getting inbound vote msg for tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + msg := ob.GetInboundVoteMsgForZetaSentEvent(event) + if msg == nil { continue } - zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeZetaSent: error posting event to zeta core for tx %s at height %d for chain %d", @@ -1059,13 +1056,24 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint if event.Raw.BlockNumber > beingScanned { beingScanned = event.Raw.BlockNumber } - msg, err := ob.GetInboundVoteMsgForDepositedEvent(event) + tx, _, err := ob.evmClient.TransactionByHash(context.Background(), event.Raw.TxHash) if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( - "observeERC20Deposited: error getting inbound vote msg for tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeERC20Deposited: TransactionByHash error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return beingScanned - 1 // we have to re-scan from this block next time + } + sender, err := ob.GetTransactionSender(tx, event.Raw.BlockHash, event.Raw.TxIndex) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeERC20Deposited: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return beingScanned - 1 // we have to re-scan from this block next time + } + + msg := ob.GetInboundVoteMsgForDepositedEvent(event, sender) + if msg == nil { continue } - zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeERC20Deposited: error posting event to zeta core for tx %s at height %d for chain %d", @@ -1108,43 +1116,33 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse block, err := ob.GetBlockByNumberCached(bn) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("observeTssRecvd: error getting block %d for chain %d", bn, ob.chain.ChainId) - return startBlock - 1 // we have to re-scan from this block next time + return bn - 1 // we have to re-scan from this block next time } for _, tx := range block.Transactions() { if tx.To() == nil { continue } - if bytes.Equal(tx.Data(), []byte(DonationMessage)) { - ob.logger.ExternalChainWatcher.Info().Msgf( - "observeTssRecvd: thank you rich folk for your donation!: %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - continue - } if *tx.To() == tssAddress { receipt, err := ob.evmClient.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msgf( "observeTssRecvd: TransactionReceipt error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - return startBlock - 1 // we have to re-scan this block next time + return bn - 1 // we have to re-scan this block next time } if receipt.Status != 1 { // 1: successful, 0: failed ob.logger.ExternalChainWatcher.Info().Msgf("observeTssRecvd: tx %s chain %d failed; don't act", tx.Hash().Hex(), ob.chain.ChainId) continue } - from, err := ob.evmClient.TransactionSender(context.Background(), tx, block.Hash(), receipt.TransactionIndex) + sender, err := ob.GetTransactionSender(tx, block.Hash(), receipt.TransactionIndex) if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf("observeTssRecvd: TransactionSender error for tx %s", tx.Hash().Hex()) - // trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - from, err = signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf( - "observeTssRecvd: local recovery of sender address failed for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - continue - } + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeTssRecvd: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return bn - 1 // we have to re-scan this block next time } - msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx.Hash(), tx.Value(), receipt, from, tx.Data()) + + msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, receipt.BlockNumber.Uint64()) if msg == nil { continue } @@ -1152,7 +1150,7 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeTssRecvd: error posting to zeta core for tx %s at height %d for chain %d", tx.Hash().Hex(), bn, ob.chain.ChainId) - return startBlock - 1 // we have to re-scan this block next time + return bn - 1 // we have to re-scan this block next time } else if zetaHash != "" { ob.logger.ExternalChainWatcher.Info().Msgf( "observeTssRecvd: gas asset deposit detected in tx %s at height %d for chain %d, PostVoteInbound zeta tx: %s ballot %s", diff --git a/zetaclient/inbound_tracker.go b/zetaclient/inbound_tracker.go index 6137f9f20a..31ea30f06e 100644 --- a/zetaclient/inbound_tracker.go +++ b/zetaclient/inbound_tracker.go @@ -3,11 +3,9 @@ package zetaclient import ( "errors" "fmt" - "math/big" "github.com/btcsuite/btcd/chaincfg/chainhash" ethcommon "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" "golang.org/x/net/context" @@ -172,15 +170,15 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - var msg types.MsgVoteOnObservedInboundTx + var msg *types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { event, err := connector.ParseZetaSent(*log) if err == nil && event != nil { // sanity check tx event err = ob.CheckEvmTxLog(&event.Raw, addrConnector, txHash, TopicsZetaSent) if err == nil { - msg, err = ob.GetInboundVoteMsgForZetaSentEvent(event) - if err == nil { + msg = ob.GetInboundVoteMsgForZetaSentEvent(event) + if msg != nil { break } } else { @@ -188,11 +186,14 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) } } } + if msg == nil { + return "", errors.New("no ZetaSent event found") + } if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") return "", err @@ -208,11 +209,20 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) if err != nil { return "", err } + // get transaction, receipt and sender hash := ethcommon.HexToHash(txHash) + tx, _, err := ob.evmClient.TransactionByHash(context.Background(), hash) + if err != nil { + return "", err + } receipt, err := ob.evmClient.TransactionReceipt(context.Background(), hash) if err != nil { return "", err } + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, receipt.BlockHash, receipt.TransactionIndex) + if err != nil { + return "", err + } // check if the tx is confirmed lastHeight := ob.GetLastBlockHeight() @@ -220,27 +230,30 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - var msg types.MsgVoteOnObservedInboundTx + var msg *types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { zetaDeposited, err := custody.ParseDeposited(*log) if err == nil && zetaDeposited != nil { // sanity check tx event err = ob.CheckEvmTxLog(&zetaDeposited.Raw, addrCustory, txHash, TopicsDeposited) if err == nil { - msg, err = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited) + msg = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited, sender) if err == nil { break } } else { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on Deposited event") + ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on ERC20CustodyDeposited event") } } } + if msg == nil { + return "", errors.New("no ERC20CustodyDeposited event found") + } if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") return "", err @@ -252,6 +265,13 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) } func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) (string, error) { + // TSS address should be set + tssAddress := ob.Tss.EVMAddress() + if tssAddress == (ethcommon.Address{}) { + return "", errors.New("TSS address not set") + } + + // check transaction and receipt hash := ethcommon.HexToHash(txHash) tx, isPending, err := ob.evmClient.TransactionByHash(context.Background(), hash) if err != nil { @@ -260,6 +280,12 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) ( if isPending { return "", errors.New("tx is still pending") } + if tx.To() == nil { + return "", errors.New("tx.To() is nil") + } + if *tx.To() != tssAddress { + return "", fmt.Errorf("tx.To() %s is not TSS address", tssAddress.Hex()) + } receipt, err := ob.evmClient.TransactionReceipt(context.Background(), hash) if err != nil { @@ -270,29 +296,20 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) ( ob.logger.ExternalChainWatcher.Info().Msgf("tx %s failed; don't act", tx.Hash().Hex()) return "", errors.New("tx not successful yet") } + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, receipt.BlockHash, receipt.TransactionIndex) + if err != nil { + return "", err + } // check if the tx is confirmed lastHeight := ob.GetLastBlockHeight() if !ob.HasEnoughConfirmations(receipt, lastHeight) { return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - - block, err := ob.evmClient.BlockByNumber(context.Background(), receipt.BlockNumber) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("BlockByNumber error") - return "", err - } - from, err := ob.evmClient.TransactionSender(context.Background(), tx, block.Hash(), receipt.TransactionIndex) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("TransactionSender error; trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address") - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - from, err = signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("local recovery of sender address failed") - return "", err - } + msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, receipt.BlockNumber.Uint64()) + if msg == nil { + return "", errors.New("no message built for token sent to TSS") } - msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx.Hash(), tx.Value(), receipt, from, tx.Data()) if !vote { return msg.Digest(), nil } diff --git a/zetaclient/utils.go b/zetaclient/utils.go index 0dfa5cb973..5a0fcd9ab2 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -196,26 +196,31 @@ func (ob *EVMChainClient) HasEnoughConfirmations(receipt *ethtypes.Receipt, last return lastHeight >= confHeight } -func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody.ERC20CustodyDeposited) (types.MsgVoteOnObservedInboundTx, error) { - ob.logger.ExternalChainWatcher.Info().Msgf("TxBlockNumber %d Transaction Hash: %s Message : %s", event.Raw.BlockNumber, event.Raw.TxHash, event.Message) - if bytes.Equal(event.Message, []byte(DonationMessage)) { - ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) - } - // get the sender of the event's transaction - tx, _, err := ob.evmClient.TransactionByHash(context.Background(), event.Raw.TxHash) +// GetTransactionSender returns the sender of the given transaction +func (ob *EVMChainClient) GetTransactionSender(tx *ethtypes.Transaction, blockHash ethcommon.Hash, txIndex uint) (ethcommon.Address, error) { + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, blockHash, txIndex) if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) - return types.MsgVoteOnObservedInboundTx{}, errors.Wrap(err, fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) + // trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address + signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) + sender, err = signer.Sender(tx) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf("can't recover the sender from tx hash %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return ethcommon.Address{}, err + } } - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - sender, err := signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) - return types.MsgVoteOnObservedInboundTx{}, errors.Wrap(err, fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) + return sender, nil +} +func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody.ERC20CustodyDeposited, sender ethcommon.Address) *types.MsgVoteOnObservedInboundTx { + if bytes.Equal(event.Message, []byte(DonationMessage)) { + ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation! tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + return nil } - return *GetInBoundVoteMessage( + message := hex.EncodeToString(event.Message) + ob.logger.ExternalChainWatcher.Info().Msgf("ERC20CustodyDeposited inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, sender.Hex(), event.Amount.String(), message) + + return GetInBoundVoteMessage( sender.Hex(), ob.chain.ChainId, "", @@ -230,35 +235,39 @@ func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody event.Asset.String(), ob.zetaClient.GetKeys().GetOperatorAddress().String(), event.Raw.Index, - ), nil + ) } -func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector.ZetaConnectorNonEthZetaSent) (types.MsgVoteOnObservedInboundTx, error) { - ob.logger.ExternalChainWatcher.Info().Msgf("TxBlockNumber %d Transaction Hash: %s Message : %s", event.Raw.BlockNumber, event.Raw.TxHash, event.Message) +func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector.ZetaConnectorNonEthZetaSent) *types.MsgVoteOnObservedInboundTx { destChain := common.GetChainFromChainID(event.DestinationChainId.Int64()) if destChain == nil { ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not supported %d", event.DestinationChainId.Int64()) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("chain id not supported %d", event.DestinationChainId.Int64()) + return nil } destAddr := clienttypes.BytesToEthHex(event.DestinationAddress) if !destChain.IsZetaChain() { cfgDest, found := ob.cfg.GetEVMConfig(destChain.ChainId) if !found { - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) + ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) + return nil } if strings.EqualFold(destAddr, cfgDest.ZetaTokenContractAddress) { ob.logger.ExternalChainWatcher.Warn().Msgf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) + return nil } } - return *GetInBoundVoteMessage( + message := base64.StdEncoding.EncodeToString(event.Message) + ob.logger.ExternalChainWatcher.Info().Msgf("ZetaSent inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, event.ZetaTxSenderAddress.Hex(), event.ZetaValueAndGas.String(), message) + + return GetInBoundVoteMessage( event.ZetaTxSenderAddress.Hex(), ob.chain.ChainId, event.SourceTxOriginAddress.Hex(), clienttypes.BytesToEthHex(event.DestinationAddress), destChain.ChainId, sdkmath.NewUintFromBigInt(event.ZetaValueAndGas), - base64.StdEncoding.EncodeToString(event.Message), + message, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, event.DestinationGasLimit.Uint64(), @@ -266,27 +275,31 @@ func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector "", ob.zetaClient.GetKeys().GetOperatorAddress().String(), event.Raw.Index, - ), nil + ) } -func (ob *EVMChainClient) GetInboundVoteMsgForTokenSentToTSS(txhash ethcommon.Hash, value *big.Int, receipt *ethtypes.Receipt, from ethcommon.Address, data []byte) *types.MsgVoteOnObservedInboundTx { - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx detected: %s, blocknum %d", txhash.Hex(), receipt.BlockNumber) - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx value: %s", value.String()) - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx from: %s", from.Hex()) +func (ob *EVMChainClient) GetInboundVoteMsgForTokenSentToTSS(tx *ethtypes.Transaction, sender ethcommon.Address, blockNumber uint64) *types.MsgVoteOnObservedInboundTx { + if bytes.Equal(tx.Data(), []byte(DonationMessage)) { + ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation! tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return nil + } message := "" - if len(data) != 0 { - message = hex.EncodeToString(data) + if len(tx.Data()) != 0 { + message = hex.EncodeToString(tx.Data()) } + ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, tx.Hash().Hex(), blockNumber, sender.Hex(), tx.Value().String(), hex.EncodeToString(tx.Data())) + return GetInBoundVoteMessage( - from.Hex(), + sender.Hex(), ob.chain.ChainId, - from.Hex(), - from.Hex(), + sender.Hex(), + sender.Hex(), ob.zetaClient.ZetaChain().ChainId, - sdkmath.NewUintFromBigInt(value), + sdkmath.NewUintFromBigInt(tx.Value()), message, - txhash.Hex(), - receipt.BlockNumber.Uint64(), + tx.Hash().Hex(), + blockNumber, 90_000, common.CoinType_Gas, "",