From 3e8f2e6621185723c13f2fbcacf8396ae8211910 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Fri, 26 Apr 2024 15:25:04 +0200 Subject: [PATCH 1/5] refactor(`zetaclient`): improve some general structure of the codebase (#2032) * bitcoin * bitcoin 2 * config * evm * testutil and supply checker * tss and zetabridge * Update zetaclient/bitcoin/bitcoin_client.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> * Update zetaclient/evm/evm_client.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> * comments * changelog * change comments * review comments * fix tests --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- changelog.md | 6 + zetaclient/bitcoin/bitcoin_client.go | 830 ++++++++++-------- zetaclient/bitcoin/bitcoin_client_db_test.go | 3 +- zetaclient/bitcoin/bitcoin_client_test.go | 2 +- zetaclient/bitcoin/bitcoin_signer.go | 11 +- zetaclient/bitcoin/bitcoin_test.go | 5 +- zetaclient/bitcoin/fee.go | 13 +- zetaclient/bitcoin/inbound_tracker.go | 15 + zetaclient/bitcoin/tx_script.go | 26 +- zetaclient/common/logger.go | 2 + zetaclient/compliance/compliance.go | 26 +- zetaclient/config/config.go | 3 + zetaclient/config/config_chain.go | 8 - zetaclient/core_context/zeta_core_context.go | 10 + zetaclient/evm/constant.go | 5 + zetaclient/evm/evm_client.go | 756 +++++++++++----- zetaclient/evm/evm_signer.go | 228 ++--- zetaclient/evm/inbounds.go | 11 +- zetaclient/interfaces/interfaces.go | 1 - zetaclient/interfaces/signer.go | 8 +- zetaclient/keys/keys.go | 47 +- zetaclient/keys/keys_test.go | 19 +- zetaclient/metrics/burn_rate.go | 17 +- zetaclient/metrics/telemetry.go | 46 +- zetaclient/supplychecker/logger.go | 29 + zetaclient/supplychecker/validate.go | 30 + .../supplychecker/zeta_supply_checker.go | 73 +- zetaclient/testutils/constant.go | 24 +- zetaclient/testutils/testdata.go | 75 +- ...ager.go => concurrent_keysigns_tracker.go} | 0 ...go => concurrent_keysigns_tracker_test.go} | 0 zetaclient/tss/tss_signer.go | 53 +- zetaclient/tss/tss_signer_test.go | 17 +- zetaclient/types/account_resp.go | 12 - zetaclient/types/ethish_test.go | 1 - zetaclient/zetabridge/block_height.go | 24 - zetaclient/zetabridge/query_test.go | 6 - zetaclient/zetabridge/zetacore_bridge.go | 15 - zetaclient/zetacore_observer.go | 116 +-- 39 files changed, 1559 insertions(+), 1014 deletions(-) create mode 100644 zetaclient/supplychecker/logger.go create mode 100644 zetaclient/supplychecker/validate.go rename zetaclient/tss/{tss_keysign_manager.go => concurrent_keysigns_tracker.go} (100%) rename zetaclient/tss/{tss_keysign_manager_test.go => concurrent_keysigns_tracker_test.go} (100%) delete mode 100644 zetaclient/types/account_resp.go delete mode 100644 zetaclient/types/ethish_test.go delete mode 100644 zetaclient/zetabridge/block_height.go diff --git a/changelog.md b/changelog.md index 19c08aebc9..80054959a8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # CHANGELOG +## Unreleased + +### Refactor + +* [2032](https://github.com/zeta-chain/node/pull/2032) - improve some general structure of the ZetaClient codebase + ## Unreleased ### Breaking Changes diff --git a/zetaclient/bitcoin/bitcoin_client.go b/zetaclient/bitcoin/bitcoin_client.go index 801171a88c..4f57bc2a7a 100644 --- a/zetaclient/bitcoin/bitcoin_client.go +++ b/zetaclient/bitcoin/bitcoin_client.go @@ -43,51 +43,100 @@ import ( ) const ( - DynamicDepositorFeeHeight = 834500 // The starting height (Bitcoin mainnet) from which dynamic depositor fee will take effect - maxHeightDiff = 10000 // in case the last block is too old when the observer starts - btcBlocksPerDay = 144 // for LRU block cache size - bigValueSats = 200000000 // 2 BTC - bigValueConfirmationCount = 6 // 6 confirmations for value >= 2 BTC + // DynamicDepositorFeeHeight contains the starting height (Bitcoin mainnet) from which dynamic depositor fee will take effect + DynamicDepositorFeeHeight = 834500 + + // maxHeightDiff contains the max height diff in case the last block is too old when the observer starts + maxHeightDiff = 10000 + + // btcBlocksPerDay represents Bitcoin blocks per days for LRU block cache size + btcBlocksPerDay = 144 + + // bigValueSats contains the threshold to determine a big value in Bitcoin represents 2 BTC + bigValueSats = 200000000 + + // bigValueConfirmationCount represents the number of confirmation necessary for bigger values: 6 confirmations + bigValueConfirmationCount = 6 ) var _ interfaces.ChainClient = &BTCChainClient{} -type BTCLog struct { - Chain zerolog.Logger // The parent logger for the chain - InTx zerolog.Logger // The logger for incoming transactions - OutTx zerolog.Logger // The logger for outgoing transactions - UTXOS zerolog.Logger // The logger for UTXOs management - GasPrice zerolog.Logger // The logger for gas price +// BTCLogger contains list of loggers used by Bitcoin chain client +// TODO: Merge this logger with the one in evm +// https://github.com/zeta-chain/node/issues/2022 +type BTCLogger struct { + // Chain is the parent logger for the chain + Chain zerolog.Logger + + // InTx is the logger for incoming transactions + InTx zerolog.Logger // The logger for incoming transactions + + // OutTx is the logger for outgoing transactions + OutTx zerolog.Logger // The logger for outgoing transactions + + // UTXOS is the logger for UTXOs management + UTXOS zerolog.Logger // The logger for UTXOs management + + // GasPrice is the logger for gas price + GasPrice zerolog.Logger // The logger for gas price + + // Compliance is the logger for compliance checks Compliance zerolog.Logger // The logger for compliance checks } +// BTCInTxEvent represents an incoming transaction event +type BTCInTxEvent struct { + // FromAddress is the first input address + FromAddress string + + // ToAddress is the TSS address + ToAddress string + + // Value is the amount of BTC + Value float64 + + MemoBytes []byte + BlockNumber uint64 + TxHash string +} + // BTCChainClient represents a chain configuration for Bitcoin // Filled with above constants depending on chain type BTCChainClient struct { + // BlockTime contains the block time in seconds + BlockTime uint64 + + BlockCache *lru.Cache + + // Mu is lock for all the maps, utxos and core params + Mu *sync.Mutex + + Tss interfaces.TSSSigner + chain chains.Chain netParams *chaincfg.Params rpcClient interfaces.BTCRPCClient zetaClient interfaces.ZetaCoreBridger - Tss interfaces.TSSSigner lastBlock int64 lastBlockScanned int64 - BlockTime uint64 // block time in seconds + pendingNonce uint64 + utxos []btcjson.ListUnspentResult + params observertypes.ChainParams + coreContext *corecontext.ZetaCoreContext + + // includedTxHashes indexes included tx with tx hash + includedTxHashes map[string]bool + + // includedTxResults indexes tx results with the outbound tx identifier + includedTxResults map[string]*btcjson.GetTransactionResult - Mu *sync.Mutex // lock for all the maps, utxos and core params - pendingNonce uint64 - includedTxHashes map[string]bool // key: tx hash - includedTxResults map[string]*btcjson.GetTransactionResult // key: chain-tss-nonce - broadcastedTx map[string]string // key: chain-tss-nonce, value: outTx hash - utxos []btcjson.ListUnspentResult - params observertypes.ChainParams - coreContext *corecontext.ZetaCoreContext + // broadcastedTx indexes the outbound hash with the outbound tx identifier + broadcastedTx map[string]string db *gorm.DB stop chan struct{} - logger BTCLog + logger BTCLogger ts *metrics.TelemetryServer - - BlockCache *lru.Cache } func (ob *BTCChainClient) WithZetaClient(bridge *zetabridge.ZetaCoreBridge) { @@ -99,7 +148,7 @@ func (ob *BTCChainClient) WithZetaClient(bridge *zetabridge.ZetaCoreBridge) { func (ob *BTCChainClient) WithLogger(logger zerolog.Logger) { ob.Mu.Lock() defer ob.Mu.Unlock() - ob.logger = BTCLog{ + ob.logger = BTCLogger{ Chain: logger, InTx: logger.With().Str("module", "WatchInTx").Logger(), OutTx: logger.With().Str("module", "WatchOutTx").Logger(), @@ -143,19 +192,24 @@ func NewBitcoinClient( btcCfg config.BTCConfig, ts *metrics.TelemetryServer, ) (*BTCChainClient, error) { + // initialize the BTCChainClient ob := BTCChainClient{ ts: ts, } ob.stop = make(chan struct{}) ob.chain = chain + + // get the bitcoin network params netParams, err := chains.BitcoinNetParamsFromChainID(ob.chain.ChainId) if err != nil { return nil, fmt.Errorf("error getting net params for chain %d: %s", ob.chain.ChainId, err) } ob.netParams = netParams + ob.Mu = &sync.Mutex{} + chainLogger := loggers.Std.With().Str("chain", chain.ChainName.String()).Logger() - ob.logger = BTCLog{ + ob.logger = BTCLogger{ Chain: chainLogger, InTx: chainLogger.With().Str("module", "WatchInTx").Logger(), OutTx: chainLogger.With().Str("module", "WatchOutTx").Logger(), @@ -170,12 +224,15 @@ func NewBitcoinClient( ob.includedTxHashes = make(map[string]bool) ob.includedTxResults = make(map[string]*btcjson.GetTransactionResult) ob.broadcastedTx = make(map[string]string) + + // set the Bitcoin chain params _, chainParams, found := appcontext.ZetaCoreContext().GetBTCChainParams() if !found { return nil, fmt.Errorf("btc chains params not initialized") } ob.params = *chainParams - // initialize the Client + + // create the RPC client ob.logger.Chain.Info().Msgf("Chain %s endpoint %s", ob.chain.String(), btcCfg.RPCHost) connCfg := &rpcclient.ConnConfig{ Host: btcCfg.RPCHost, @@ -189,6 +246,8 @@ func NewBitcoinClient( if err != nil { return nil, fmt.Errorf("error creating rpc client: %s", err) } + + // try connection ob.rpcClient = client err = client.Ping() if err != nil { @@ -201,7 +260,7 @@ func NewBitcoinClient( return nil, err } - //Load btc chain client DB + // load btc chain client DB err = ob.loadDB(dbpath) if err != nil { return nil, err @@ -210,6 +269,7 @@ func NewBitcoinClient( return &ob, nil } +// Start starts the Go routine to observe the Bitcoin chain func (ob *BTCChainClient) Start() { ob.logger.Chain.Info().Msgf("BitcoinChainClient is starting") go ob.WatchInTx() // watch bitcoin chain for incoming txs and post votes to zetacore @@ -231,37 +291,44 @@ func (ob *BTCChainClient) WatchRPCStatus() { if !ob.GetChainParams().IsSupported { continue } + bn, err := ob.rpcClient.GetBlockCount() if err != nil { ob.logger.Chain.Error().Err(err).Msg("RPC status check: RPC down? ") continue } + hash, err := ob.rpcClient.GetBlockHash(bn) if err != nil { ob.logger.Chain.Error().Err(err).Msg("RPC status check: RPC down? ") continue } + header, err := ob.rpcClient.GetBlockHeader(hash) if err != nil { ob.logger.Chain.Error().Err(err).Msg("RPC status check: RPC down? ") continue } + blockTime := header.Timestamp elapsedSeconds := time.Since(blockTime).Seconds() if elapsedSeconds > 1200 { ob.logger.Chain.Error().Err(err).Msg("RPC status check: RPC down? ") continue } + tssAddr := ob.Tss.BTCAddressWitnessPubkeyHash() res, err := ob.rpcClient.ListUnspentMinMaxAddresses(0, 1000000, []btcutil.Address{tssAddr}) if err != nil { ob.logger.Chain.Error().Err(err).Msg("RPC status check: can't list utxos of TSS address; wallet or loaded? TSS address is not imported? ") continue } + if len(res) == 0 { ob.logger.Chain.Error().Err(err).Msg("RPC status check: TSS address has no utxos; TSS address is not imported? ") continue } + ob.logger.Chain.Info().Msgf("[OK] RPC status check: latest block number %d, timestamp %s (%.fs ago), tss addr %s, #utxos: %d", bn, blockTime, elapsedSeconds, tssAddr, len(res)) case <-ob.stop: @@ -327,10 +394,11 @@ func (ob *BTCChainClient) WatchInTx() { ob.logger.InTx.Error().Err(err).Msg("error creating ticker") return } - defer ticker.Stop() + ob.logger.InTx.Info().Msgf("WatchInTx started for chain %d", ob.chain.ChainId) sampledLogger := ob.logger.InTx.Sample(&zerolog.BasicSampler{N: 10}) + for { select { case <-ticker.C(): @@ -350,41 +418,6 @@ func (ob *BTCChainClient) WatchInTx() { } } -func (ob *BTCChainClient) postBlockHeader(tip int64) error { - ob.logger.InTx.Info().Msgf("postBlockHeader: tip %d", tip) - bn := tip - res, err := ob.zetaClient.GetBlockHeaderChainState(ob.chain.ChainId) - if err == nil && res.ChainState != nil && res.ChainState.EarliestHeight > 0 { - bn = res.ChainState.LatestHeight + 1 - } - if bn > tip { - return fmt.Errorf("postBlockHeader: must post block confirmed block header: %d > %d", bn, tip) - } - res2, err := ob.GetBlockByNumberCached(bn) - if err != nil { - return fmt.Errorf("error getting bitcoin block %d: %s", bn, err) - } - - var headerBuf bytes.Buffer - err = res2.Header.Serialize(&headerBuf) - if err != nil { // should never happen - ob.logger.InTx.Error().Err(err).Msgf("error serializing bitcoin block header: %d", bn) - return err - } - blockHash := res2.Header.BlockHash() - _, err = ob.zetaClient.PostVoteBlockHeader( - ob.chain.ChainId, - blockHash[:], - res2.Block.Height, - proofs.NewBitcoinHeader(headerBuf.Bytes()), - ) - ob.logger.InTx.Info().Msgf("posted block header %d: %s", bn, blockHash) - if err != nil { // error shouldn't block the process - ob.logger.InTx.Error().Err(err).Msgf("error posting bitcoin block header: %d", bn) - } - return err -} - func (ob *BTCChainClient) ObserveInTx() error { // get and update latest block height cnt, err := ob.rpcClient.GetBlockCount() @@ -413,34 +446,41 @@ func (ob *BTCChainClient) ObserveInTx() error { } // query incoming gas asset to TSS address - { - bn := lastScanned + 1 - res, err := ob.GetBlockByNumberCached(bn) + blockNumber := lastScanned + 1 + res, err := ob.GetBlockByNumberCached(blockNumber) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error getting bitcoin block %d", blockNumber) + return err + } + ob.logger.InTx.Info().Msgf("observeInTxBTC: block %d has %d txs, current block %d, last block %d", + blockNumber, len(res.Block.Tx), cnt, lastScanned) + + // add block header to zetabridge + // TODO: consider having a separate ticker(from TSS scaning) for posting block headers + // https://github.com/zeta-chain/node/issues/1847 + flags := ob.coreContext.GetCrossChainFlags() + if flags.BlockHeaderVerificationFlags != nil && flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled { + err = ob.postBlockHeader(blockNumber) if err != nil { - ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error getting bitcoin block %d", bn) - return err + ob.logger.InTx.Warn().Err(err).Msgf("observeInTxBTC: error posting block header %d", blockNumber) } - ob.logger.InTx.Info().Msgf("observeInTxBTC: block %d has %d txs, current block %d, last block %d", - bn, len(res.Block.Tx), cnt, lastScanned) + } - // print some debug information - if len(res.Block.Tx) > 1 { - for idx, tx := range res.Block.Tx { - ob.logger.InTx.Debug().Msgf("BTC InTX | %d: %s\n", idx, tx.Txid) - for vidx, vout := range tx.Vout { - ob.logger.InTx.Debug().Msgf("vout %d \n value: %v\n scriptPubKey: %v\n", vidx, vout.Value, vout.ScriptPubKey.Hex) - } - } - } + if len(res.Block.Tx) > 1 { + // get depositor fee + depositorFee := CalcDepositorFee(res.Block, ob.chain.ChainId, ob.netParams, ob.logger.InTx) + + // filter incoming txs to TSS address + tssAddress := ob.Tss.BTCAddress() // add block header to zetabridge // TODO: consider having a separate ticker(from TSS scaning) for posting block headers // https://github.com/zeta-chain/node/issues/1847 verificationFlags := ob.coreContext.GetVerificationFlags() if verificationFlags.BtcTypeChainEnabled { - err = ob.postBlockHeader(bn) + err = ob.postBlockHeader(blockNumber) if err != nil { - ob.logger.InTx.Warn().Err(err).Msgf("observeInTxBTC: error posting block header %d", bn) + ob.logger.InTx.Warn().Err(err).Msgf("observeInTxBTC: error posting block header %d", blockNumber) } } @@ -461,7 +501,7 @@ func (ob *BTCChainClient) ObserveInTx() error { depositorFee, ) if err != nil { - ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error filtering incoming txs for block %d", bn) + ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error filtering incoming txs for block %d", blockNumber) return err // we have to re-scan this block next time } @@ -482,13 +522,47 @@ func (ob *BTCChainClient) ObserveInTx() error { } // Save LastBlockHeight - ob.SetLastBlockHeightScanned(bn) + ob.SetLastBlockHeightScanned(blockNumber) + // #nosec G701 always positive - if err := ob.db.Save(clienttypes.ToLastBlockSQLType(uint64(bn))).Error; err != nil { - ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error writing last scanned block %d to db", bn) + inTxs, err := FilterAndParseIncomingTx( + ob.rpcClient, + res.Block.Tx, + uint64(res.Block.Height), + tssAddress, + ob.logger.InTx, + ob.netParams, + depositorFee, + ) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error filtering incoming txs for block %d", blockNumber) + return err // we have to re-scan this block next time + } + + // post inbound vote message to zetacore + for _, inTx := range inTxs { + msg := ob.GetInboundVoteMessageFromBtcEvent(inTx) + if msg != nil { + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(zetabridge.PostVoteInboundGasLimit, zetabridge.PostVoteInboundExecutionGasLimit, msg) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error posting to zeta core for tx %s", inTx.TxHash) + return err // we have to re-scan this block next time + } else if zetaHash != "" { + ob.logger.InTx.Info().Msgf("observeInTxBTC: PostVoteInbound zeta tx hash: %s inTx %s ballot %s fee %v", + zetaHash, inTx.TxHash, ballot, depositorFee) + } + } } } + // Save LastBlockHeight + ob.SetLastBlockHeightScanned(blockNumber) + + // #nosec G701 always positive + if err := ob.db.Save(clienttypes.ToLastBlockSQLType(uint64(blockNumber))).Error; err != nil { + ob.logger.InTx.Error().Err(err).Msgf("observeInTxBTC: error writing last scanned block %d to db", blockNumber) + } + return nil } @@ -500,6 +574,7 @@ func (ob *BTCChainClient) ConfirmationsThreshold(amount *big.Int) int64 { if bigValueConfirmationCount < ob.GetChainParams().ConfirmationCount { return bigValueConfirmationCount } + // #nosec G701 always in range return int64(ob.GetChainParams().ConfirmationCount) } @@ -577,6 +652,7 @@ func (ob *BTCChainClient) IsOutboundProcessed(cctx *types.CrossChainTx, logger z } else if zetaHash != "" { logger.Info().Msgf("IsOutboundProcessed: confirmed Bitcoin outTx %s, zeta tx hash %s nonce %d ballot %s", res.TxID, zetaHash, nonce, ballot) } + return true, true, nil } @@ -618,20 +694,20 @@ func (ob *BTCChainClient) WatchGasPrice() { func (ob *BTCChainClient) PostGasPrice() error { if ob.chain.ChainId == 18444 { //bitcoin regtest; hardcode here since this RPC is not available on regtest - bn, err := ob.rpcClient.GetBlockCount() + blockNumber, err := ob.rpcClient.GetBlockCount() if err != nil { return err } + // #nosec G701 always in range - zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, 1, "100", uint64(bn)) + _, err = ob.zetaClient.PostGasPrice(ob.chain, 1, "100", uint64(blockNumber)) if err != nil { ob.logger.GasPrice.Err(err).Msg("PostGasPrice:") return err } - _ = zetaHash - //ob.logger.WatchGasPrice.Debug().Msgf("PostGasPrice zeta tx: %s", zetaHash) return nil } + // EstimateSmartFee returns the fees per kilobyte (BTC/kb) targeting given block confirmation feeResult, err := ob.rpcClient.EstimateSmartFee(1, &btcjson.EstimateModeEconomical) if err != nil { @@ -644,27 +720,20 @@ func (ob *BTCChainClient) PostGasPrice() error { return fmt.Errorf("gas price is too large: %f", *feeResult.FeeRate) } feeRatePerByte := FeeRateToSatPerByte(*feeResult.FeeRate) - bn, err := ob.rpcClient.GetBlockCount() + + blockNumber, err := ob.rpcClient.GetBlockCount() if err != nil { return err } + // #nosec G701 always positive - zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, feeRatePerByte.Uint64(), "100", uint64(bn)) + _, err = ob.zetaClient.PostGasPrice(ob.chain, feeRatePerByte.Uint64(), "100", uint64(blockNumber)) if err != nil { ob.logger.GasPrice.Err(err).Msg("PostGasPrice:") return err } - _ = zetaHash - return nil -} -type BTCInTxEvnet struct { - FromAddress string // the first input address - ToAddress string // some TSS address - Value float64 // in BTC, not satoshi - MemoBytes []byte - BlockNumber uint64 - TxHash string + return nil } // FilterAndParseIncomingTx given txs list returned by the "getblock 2" RPC command, return the txs that are relevant to us @@ -679,17 +748,19 @@ func FilterAndParseIncomingTx( logger zerolog.Logger, netParams *chaincfg.Params, depositorFee float64, -) ([]*BTCInTxEvnet, error) { - inTxs := make([]*BTCInTxEvnet, 0) +) ([]*BTCInTxEvent, error) { + inTxs := make([]*BTCInTxEvent, 0) for idx, tx := range txs { if idx == 0 { continue // the first tx is coinbase; we do not process coinbase tx } + inTx, err := GetBtcEvent(rpcClient, tx, tssAddress, blockNumber, logger, netParams, depositorFee) if err != nil { // unable to parse the tx, the caller should retry return nil, errors.Wrapf(err, "error getting btc event for tx %s in block %d", tx.Txid, blockNumber) } + if inTx != nil { inTxs = append(inTxs, inTx) logger.Info().Msgf("FilterAndParseIncomingTx: found btc event for tx %s in block %d", tx.Txid, blockNumber) @@ -698,7 +769,7 @@ func FilterAndParseIncomingTx( return inTxs, nil } -func (ob *BTCChainClient) GetInboundVoteMessageFromBtcEvent(inTx *BTCInTxEvnet) *types.MsgVoteOnObservedInboundTx { +func (ob *BTCChainClient) GetInboundVoteMessageFromBtcEvent(inTx *BTCInTxEvent) *types.MsgVoteOnObservedInboundTx { ob.logger.InTx.Debug().Msgf("Processing inTx: %s", inTx.TxHash) amount := big.NewFloat(inTx.Value) amount = amount.Mul(amount, big.NewFloat(1e8)) @@ -706,6 +777,7 @@ func (ob *BTCChainClient) GetInboundVoteMessageFromBtcEvent(inTx *BTCInTxEvnet) message := hex.EncodeToString(inTx.MemoBytes) // compliance check + // if the inbound contains restricted addresses, return nil if ob.IsInTxRestricted(inTx) { return nil } @@ -729,7 +801,7 @@ func (ob *BTCChainClient) GetInboundVoteMessageFromBtcEvent(inTx *BTCInTxEvnet) } // IsInTxRestricted returns true if the inTx contains restricted addresses -func (ob *BTCChainClient) IsInTxRestricted(inTx *BTCInTxEvnet) bool { +func (ob *BTCChainClient) IsInTxRestricted(inTx *BTCInTxEvent) bool { receiver := "" parsedAddress, _, err := chains.ParseAddressAndData(hex.EncodeToString(inTx.MemoBytes)) if err == nil && parsedAddress != (ethcommon.Address{}) { @@ -753,7 +825,7 @@ func GetBtcEvent( logger zerolog.Logger, netParams *chaincfg.Params, depositorFee float64, -) (*BTCInTxEvnet, error) { +) (*BTCInTxEvent, error) { found := false var value float64 var memo []byte @@ -761,15 +833,18 @@ func GetBtcEvent( // 1st vout must have tss address as receiver with p2wpkh scriptPubKey vout0 := tx.Vout[0] script := vout0.ScriptPubKey.Hex - if len(script) == 44 && script[:4] == "0014" { // P2WPKH output: 0x00 + 20 bytes of pubkey hash + if len(script) == 44 && script[:4] == "0014" { + // P2WPKH output: 0x00 + 20 bytes of pubkey hash receiver, err := DecodeScriptP2WPKH(vout0.ScriptPubKey.Hex, netParams) if err != nil { // should never happen return nil, err } + // skip irrelevant tx to us if receiver != tssAddress { return nil, nil } + // deposit amount has to be no less than the minimum depositor fee if vout0.Value < depositorFee { logger.Info().Msgf("GetBtcEvent: btc deposit amount %v in txid %s is less than depositor fee %v", vout0.Value, tx.Txid, depositorFee) @@ -791,11 +866,13 @@ func GetBtcEvent( if len(tx.Vin) == 0 { // should never happen return nil, fmt.Errorf("GetBtcEvent: no input found for intx: %s", tx.Txid) } + fromAddress, err := GetSenderAddressByVin(rpcClient, tx.Vin[0], netParams) if err != nil { return nil, errors.Wrapf(err, "error getting sender address for intx: %s", tx.Txid) } - return &BTCInTxEvnet{ + + return &BTCInTxEvent{ FromAddress: fromAddress, ToAddress: tssAddress, Value: value, @@ -815,10 +892,12 @@ func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, n if err != nil { return "", err } + tx, err := rpcClient.GetRawTransaction(hash) if err != nil { return "", errors.Wrapf(err, "error getting raw transaction %s", vin.Txid) } + // #nosec G701 - always in range if len(tx.MsgTx().TxOut) <= int(vin.Vout) { return "", fmt.Errorf("vout index %d out of range for tx %s", vin.Vout, vin.Txid) @@ -842,6 +921,7 @@ func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, n if IsPkScriptP2PKH(pkScript) { return DecodeScriptP2PKH(scriptHex, net) } + // sender address not found, return nil and move on to the next tx return "", nil } @@ -935,92 +1015,6 @@ func (ob *BTCChainClient) FetchUTXOS() error { return nil } -// isTssTransaction checks if a given transaction was sent by TSS itself. -// An unconfirmed transaction is safe to spend only if it was sent by TSS and verified by ourselves. -func (ob *BTCChainClient) isTssTransaction(txid string) bool { - _, found := ob.includedTxHashes[txid] - return found -} - -// refreshPendingNonce tries increasing the artificial pending nonce of outTx (if lagged behind). -// There could be many (unpredictable) reasons for a pending nonce lagging behind, for example: -// 1. The zetaclient gets restarted. -// 2. The tracker is missing in zetabridge. -func (ob *BTCChainClient) refreshPendingNonce() { - // get pending nonces from zetabridge - p, err := ob.zetaClient.GetPendingNoncesByChain(ob.chain.ChainId) - if err != nil { - ob.logger.Chain.Error().Err(err).Msg("refreshPendingNonce: error getting pending nonces") - } - - // increase pending nonce if lagged behind - ob.Mu.Lock() - pendingNonce := ob.pendingNonce - ob.Mu.Unlock() - - // #nosec G701 always non-negative - nonceLow := uint64(p.NonceLow) - if nonceLow > pendingNonce { - // get the last included outTx hash - txid, err := ob.getOutTxidByNonce(nonceLow-1, false) - if err != nil { - ob.logger.Chain.Error().Err(err).Msg("refreshPendingNonce: error getting last outTx txid") - } - - // set 'NonceLow' as the new pending nonce - ob.Mu.Lock() - defer ob.Mu.Unlock() - ob.pendingNonce = nonceLow - ob.logger.Chain.Info().Msgf("refreshPendingNonce: increase pending nonce to %d with txid %s", ob.pendingNonce, txid) - } -} - -func (ob *BTCChainClient) getOutTxidByNonce(nonce uint64, test bool) (string, error) { - - // There are 2 types of txids an observer can trust - // 1. The ones had been verified and saved by observer self. - // 2. The ones had been finalized in zetabridge based on majority vote. - if res := ob.getIncludedTx(nonce); res != nil { - return res.TxID, nil - } - if !test { // if not unit test, get cctx from zetabridge - send, err := ob.zetaClient.GetCctxByNonce(ob.chain.ChainId, nonce) - if err != nil { - return "", errors.Wrapf(err, "getOutTxidByNonce: error getting cctx for nonce %d", nonce) - } - txid := send.GetCurrentOutTxParam().OutboundTxHash - if txid == "" { - return "", fmt.Errorf("getOutTxidByNonce: cannot find outTx txid for nonce %d", nonce) - } - // make sure it's a real Bitcoin txid - _, getTxResult, err := GetTxResultByHash(ob.rpcClient, txid) - if err != nil { - return "", errors.Wrapf(err, "getOutTxidByNonce: error getting outTx result for nonce %d hash %s", nonce, txid) - } - if getTxResult.Confirmations <= 0 { // just a double check - return "", fmt.Errorf("getOutTxidByNonce: outTx txid %s for nonce %d is not included", txid, nonce) - } - return txid, nil - } - return "", fmt.Errorf("getOutTxidByNonce: cannot find outTx txid for nonce %d", nonce) -} - -func (ob *BTCChainClient) findNonceMarkUTXO(nonce uint64, txid string) (int, error) { - tssAddress := ob.Tss.BTCAddressWitnessPubkeyHash().EncodeAddress() - amount := chains.NonceMarkAmount(nonce) - for i, utxo := range ob.utxos { - sats, err := GetSatoshis(utxo.Amount) - if err != nil { - ob.logger.OutTx.Error().Err(err).Msgf("findNonceMarkUTXO: error getting satoshis for utxo %v", utxo) - } - if utxo.Address == tssAddress && sats == amount && utxo.TxID == txid && utxo.Vout == 0 { - ob.logger.OutTx.Info().Msgf("findNonceMarkUTXO: found nonce-mark utxo with txid %s, amount %d satoshi", utxo.TxID, sats) - return i, nil - } - } - return -1, fmt.Errorf("findNonceMarkUTXO: cannot find nonce-mark utxo with nonce %d", nonce) -} - // SelectUTXOs selects a sublist of utxos to be used as inputs. // // Parameters: @@ -1035,7 +1029,13 @@ func (ob *BTCChainClient) findNonceMarkUTXO(nonce uint64, txid string) (int, err // - the total value of the selected UTXOs. // - the number of consolidated UTXOs. // - the total value of the consolidated UTXOs. -func (ob *BTCChainClient) SelectUTXOs(amount float64, utxosToSpend uint16, nonce uint64, consolidateRank uint16, test bool) ([]btcjson.ListUnspentResult, float64, uint16, float64, error) { +func (ob *BTCChainClient) SelectUTXOs( + amount float64, + utxosToSpend uint16, + nonce uint64, + consolidateRank uint16, + test bool, +) ([]btcjson.ListUnspentResult, float64, uint16, float64, error) { idx := -1 if nonce == 0 { // for nonce = 0; make exception; no need to include nonce-mark utxo @@ -1128,10 +1128,11 @@ func (ob *BTCChainClient) WatchOutTx() { ob.logger.OutTx.Error().Err(err).Msg("error creating ticker ") return } - defer ticker.Stop() + ob.logger.OutTx.Info().Msgf("WatchInTx started for chain %d", ob.chain.ChainId) sampledLogger := ob.logger.OutTx.Sample(&zerolog.BasicSampler{N: 10}) + for { select { case <-ticker.C(): @@ -1152,14 +1153,17 @@ func (ob *BTCChainClient) WatchOutTx() { ob.logger.OutTx.Info().Err(err).Msgf("WatchOutTx: can't find cctx for chain %d nonce %d", ob.chain.ChainId, tracker.Nonce) break } + nonce := cctx.GetCurrentOutTxParam().OutboundTxTssNonce if tracker.Nonce != nonce { // Tanmay: it doesn't hurt to check ob.logger.OutTx.Error().Msgf("WatchOutTx: tracker nonce %d not match cctx nonce %d", tracker.Nonce, nonce) break } + if len(tracker.HashList) > 1 { ob.logger.OutTx.Warn().Msgf("WatchOutTx: oops, outTxID %s got multiple (%d) outTx hashes", outTxID, len(tracker.HashList)) } + // iterate over all txHashes to find the truly included one. // we do it this (inefficient) way because we don't rely on the first one as it may be a false positive (for unknown reason). txCount := 0 @@ -1176,6 +1180,7 @@ func (ob *BTCChainClient) WatchOutTx() { } } } + if txCount == 1 { // should be only one txHash included for each nonce ob.setIncludedTx(tracker.Nonce, txResult) } else if txCount > 1 { @@ -1191,42 +1196,288 @@ func (ob *BTCChainClient) WatchOutTx() { } } -// checkIncludedTx checks if a txHash is included and returns (txResult, inMempool) -// Note: if txResult is nil, then inMempool flag should be ignored. -func (ob *BTCChainClient) checkIncludedTx(cctx *types.CrossChainTx, txHash string) (*btcjson.GetTransactionResult, bool) { - outTxID := ob.GetTxID(cctx.GetCurrentOutTxParam().OutboundTxTssNonce) - hash, getTxResult, err := GetTxResultByHash(ob.rpcClient, txHash) +// GetTxResultByHash gets the transaction result by hash +func GetTxResultByHash(rpcClient interfaces.BTCRPCClient, txID string) (*chainhash.Hash, *btcjson.GetTransactionResult, error) { + hash, err := chainhash.NewHashFromStr(txID) if err != nil { - ob.logger.OutTx.Error().Err(err).Msgf("checkIncludedTx: error GetTxResultByHash: %s", txHash) - return nil, false - } - if txHash != getTxResult.TxID { // just in case, we'll use getTxResult.TxID later - ob.logger.OutTx.Error().Msgf("checkIncludedTx: inconsistent txHash %s and getTxResult.TxID %s", txHash, getTxResult.TxID) - return nil, false + return nil, nil, errors.Wrapf(err, "GetTxResultByHash: error NewHashFromStr: %s", txID) } - if getTxResult.Confirmations >= 0 { // check included tx only - err = ob.checkTssOutTxResult(cctx, hash, getTxResult) - if err != nil { - ob.logger.OutTx.Error().Err(err).Msgf("checkIncludedTx: error verify bitcoin outTx %s outTxID %s", txHash, outTxID) - return nil, false - } - return getTxResult, false // included + + // The Bitcoin node has to be configured to watch TSS address + txResult, err := rpcClient.GetTransaction(hash) + if err != nil { + return nil, nil, errors.Wrapf(err, "GetOutTxByTxHash: error GetTransaction %s", hash.String()) } - return getTxResult, true // in mempool + return hash, txResult, nil } -// setIncludedTx saves included tx result in memory -func (ob *BTCChainClient) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransactionResult) { - txHash := getTxResult.TxID - outTxID := ob.GetTxID(nonce) - - ob.Mu.Lock() - defer ob.Mu.Unlock() - res, found := ob.includedTxResults[outTxID] - - if !found { // not found. - ob.includedTxHashes[txHash] = true - ob.includedTxResults[outTxID] = getTxResult // include new outTx and enforce rigid 1-to-1 mapping: nonce <===> txHash +// GetRawTxResult gets the raw tx result +func GetRawTxResult(rpcClient interfaces.BTCRPCClient, hash *chainhash.Hash, res *btcjson.GetTransactionResult) (btcjson.TxRawResult, error) { + if res.Confirmations == 0 { // for pending tx, we query the raw tx directly + rawResult, err := rpcClient.GetRawTransactionVerbose(hash) // for pending tx, we query the raw tx + if err != nil { + return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error GetRawTransactionVerbose %s", res.TxID) + } + return *rawResult, nil + } else if res.Confirmations > 0 { // for confirmed tx, we query the block + blkHash, err := chainhash.NewHashFromStr(res.BlockHash) + if err != nil { + return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error NewHashFromStr for block hash %s", res.BlockHash) + } + block, err := rpcClient.GetBlockVerboseTx(blkHash) + if err != nil { + return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error GetBlockVerboseTx %s", res.BlockHash) + } + if res.BlockIndex < 0 || res.BlockIndex >= int64(len(block.Tx)) { + return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: invalid outTx with invalid block index, TxID %s, BlockIndex %d", res.TxID, res.BlockIndex) + } + return block.Tx[res.BlockIndex], nil + } + + // res.Confirmations < 0 (meaning not included) + return btcjson.TxRawResult{}, fmt.Errorf("getRawTxResult: tx %s not included yet", hash) +} + +func (ob *BTCChainClient) BuildBroadcastedTxMap() error { + var broadcastedTransactions []clienttypes.OutTxHashSQLType + if err := ob.db.Find(&broadcastedTransactions).Error; err != nil { + ob.logger.Chain.Error().Err(err).Msg("error iterating over db") + return err + } + for _, entry := range broadcastedTransactions { + ob.broadcastedTx[entry.Key] = entry.Hash + } + return nil +} + +func (ob *BTCChainClient) LoadLastBlock() error { + bn, err := ob.rpcClient.GetBlockCount() + if err != nil { + return err + } + + //Load persisted block number + var lastBlockNum clienttypes.LastBlockSQLType + if err := ob.db.First(&lastBlockNum, clienttypes.LastBlockNumID).Error; err != nil { + ob.logger.Chain.Info().Msg("LastBlockNum not found in DB, scan from latest") + ob.SetLastBlockHeightScanned(bn) + } else { + // #nosec G701 always in range + lastBN := int64(lastBlockNum.Num) + ob.SetLastBlockHeightScanned(lastBN) + + //If persisted block number is too low, use the latest height + if (bn - lastBN) > maxHeightDiff { + ob.logger.Chain.Info().Msgf("LastBlockNum too low: %d, scan from latest", lastBlockNum.Num) + ob.SetLastBlockHeightScanned(bn) + } + } + + if ob.chain.ChainId == 18444 { // bitcoin regtest: start from block 100 + ob.SetLastBlockHeightScanned(100) + } + ob.logger.Chain.Info().Msgf("%s: start scanning from block %d", ob.chain.String(), ob.GetLastBlockHeightScanned()) + + return nil +} + +func (ob *BTCChainClient) GetTxID(nonce uint64) string { + tssAddr := ob.Tss.BTCAddress() + return fmt.Sprintf("%d-%s-%d", ob.chain.ChainId, tssAddr, nonce) +} + +type BTCBlockNHeader struct { + Header *wire.BlockHeader + Block *btcjson.GetBlockVerboseTxResult +} + +func (ob *BTCChainClient) GetBlockByNumberCached(blockNumber int64) (*BTCBlockNHeader, error) { + if result, ok := ob.BlockCache.Get(blockNumber); ok { + return result.(*BTCBlockNHeader), nil + } + // Get the block hash + hash, err := ob.rpcClient.GetBlockHash(blockNumber) + if err != nil { + return nil, err + } + // Get the block header + header, err := ob.rpcClient.GetBlockHeader(hash) + if err != nil { + return nil, err + } + // Get the block with verbose transactions + block, err := ob.rpcClient.GetBlockVerboseTx(hash) + if err != nil { + return nil, err + } + blockNheader := &BTCBlockNHeader{ + Header: header, + Block: block, + } + ob.BlockCache.Add(blockNumber, blockNheader) + ob.BlockCache.Add(hash, blockNheader) + return blockNheader, nil +} + +func (ob *BTCChainClient) postBlockHeader(tip int64) error { + ob.logger.InTx.Info().Msgf("postBlockHeader: tip %d", tip) + bn := tip + res, err := ob.zetaClient.GetBlockHeaderChainState(ob.chain.ChainId) + if err == nil && res.ChainState != nil && res.ChainState.EarliestHeight > 0 { + bn = res.ChainState.LatestHeight + 1 + } + if bn > tip { + return fmt.Errorf("postBlockHeader: must post block confirmed block header: %d > %d", bn, tip) + } + res2, err := ob.GetBlockByNumberCached(bn) + if err != nil { + return fmt.Errorf("error getting bitcoin block %d: %s", bn, err) + } + + var headerBuf bytes.Buffer + err = res2.Header.Serialize(&headerBuf) + if err != nil { // should never happen + ob.logger.InTx.Error().Err(err).Msgf("error serializing bitcoin block header: %d", bn) + return err + } + blockHash := res2.Header.BlockHash() + _, err = ob.zetaClient.PostVoteBlockHeader( + ob.chain.ChainId, + blockHash[:], + res2.Block.Height, + proofs.NewBitcoinHeader(headerBuf.Bytes()), + ) + ob.logger.InTx.Info().Msgf("posted block header %d: %s", bn, blockHash) + if err != nil { // error shouldn't block the process + ob.logger.InTx.Error().Err(err).Msgf("error posting bitcoin block header: %d", bn) + } + return err +} + +// isTssTransaction checks if a given transaction was sent by TSS itself. +// An unconfirmed transaction is safe to spend only if it was sent by TSS and verified by ourselves. +func (ob *BTCChainClient) isTssTransaction(txid string) bool { + _, found := ob.includedTxHashes[txid] + return found +} + +// refreshPendingNonce tries increasing the artificial pending nonce of outTx (if lagged behind). +// There could be many (unpredictable) reasons for a pending nonce lagging behind, for example: +// 1. The zetaclient gets restarted. +// 2. The tracker is missing in zetabridge. +func (ob *BTCChainClient) refreshPendingNonce() { + // get pending nonces from zetabridge + p, err := ob.zetaClient.GetPendingNoncesByChain(ob.chain.ChainId) + if err != nil { + ob.logger.Chain.Error().Err(err).Msg("refreshPendingNonce: error getting pending nonces") + } + + // increase pending nonce if lagged behind + ob.Mu.Lock() + pendingNonce := ob.pendingNonce + ob.Mu.Unlock() + + // #nosec G701 always non-negative + nonceLow := uint64(p.NonceLow) + if nonceLow > pendingNonce { + // get the last included outTx hash + txid, err := ob.getOutTxidByNonce(nonceLow-1, false) + if err != nil { + ob.logger.Chain.Error().Err(err).Msg("refreshPendingNonce: error getting last outTx txid") + } + + // set 'NonceLow' as the new pending nonce + ob.Mu.Lock() + defer ob.Mu.Unlock() + ob.pendingNonce = nonceLow + ob.logger.Chain.Info().Msgf("refreshPendingNonce: increase pending nonce to %d with txid %s", ob.pendingNonce, txid) + } +} + +func (ob *BTCChainClient) getOutTxidByNonce(nonce uint64, test bool) (string, error) { + + // There are 2 types of txids an observer can trust + // 1. The ones had been verified and saved by observer self. + // 2. The ones had been finalized in zetabridge based on majority vote. + if res := ob.getIncludedTx(nonce); res != nil { + return res.TxID, nil + } + if !test { // if not unit test, get cctx from zetabridge + send, err := ob.zetaClient.GetCctxByNonce(ob.chain.ChainId, nonce) + if err != nil { + return "", errors.Wrapf(err, "getOutTxidByNonce: error getting cctx for nonce %d", nonce) + } + txid := send.GetCurrentOutTxParam().OutboundTxHash + if txid == "" { + return "", fmt.Errorf("getOutTxidByNonce: cannot find outTx txid for nonce %d", nonce) + } + // make sure it's a real Bitcoin txid + _, getTxResult, err := GetTxResultByHash(ob.rpcClient, txid) + if err != nil { + return "", errors.Wrapf(err, "getOutTxidByNonce: error getting outTx result for nonce %d hash %s", nonce, txid) + } + if getTxResult.Confirmations <= 0 { // just a double check + return "", fmt.Errorf("getOutTxidByNonce: outTx txid %s for nonce %d is not included", txid, nonce) + } + return txid, nil + } + return "", fmt.Errorf("getOutTxidByNonce: cannot find outTx txid for nonce %d", nonce) +} + +func (ob *BTCChainClient) findNonceMarkUTXO(nonce uint64, txid string) (int, error) { + tssAddress := ob.Tss.BTCAddressWitnessPubkeyHash().EncodeAddress() + amount := chains.NonceMarkAmount(nonce) + for i, utxo := range ob.utxos { + sats, err := GetSatoshis(utxo.Amount) + if err != nil { + ob.logger.OutTx.Error().Err(err).Msgf("findNonceMarkUTXO: error getting satoshis for utxo %v", utxo) + } + if utxo.Address == tssAddress && sats == amount && utxo.TxID == txid && utxo.Vout == 0 { + ob.logger.OutTx.Info().Msgf("findNonceMarkUTXO: found nonce-mark utxo with txid %s, amount %d satoshi", utxo.TxID, sats) + return i, nil + } + } + return -1, fmt.Errorf("findNonceMarkUTXO: cannot find nonce-mark utxo with nonce %d", nonce) +} + +// checkIncludedTx checks if a txHash is included and returns (txResult, inMempool) +// Note: if txResult is nil, then inMempool flag should be ignored. +func (ob *BTCChainClient) checkIncludedTx(cctx *types.CrossChainTx, txHash string) (*btcjson.GetTransactionResult, bool) { + outTxID := ob.GetTxID(cctx.GetCurrentOutTxParam().OutboundTxTssNonce) + hash, getTxResult, err := GetTxResultByHash(ob.rpcClient, txHash) + if err != nil { + ob.logger.OutTx.Error().Err(err).Msgf("checkIncludedTx: error GetTxResultByHash: %s", txHash) + return nil, false + } + + if txHash != getTxResult.TxID { // just in case, we'll use getTxResult.TxID later + ob.logger.OutTx.Error().Msgf("checkIncludedTx: inconsistent txHash %s and getTxResult.TxID %s", txHash, getTxResult.TxID) + return nil, false + } + + if getTxResult.Confirmations >= 0 { // check included tx only + err = ob.checkTssOutTxResult(cctx, hash, getTxResult) + if err != nil { + ob.logger.OutTx.Error().Err(err).Msgf("checkIncludedTx: error verify bitcoin outTx %s outTxID %s", txHash, outTxID) + return nil, false + } + return getTxResult, false // included + } + return getTxResult, true // in mempool +} + +// setIncludedTx saves included tx result in memory +func (ob *BTCChainClient) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransactionResult) { + txHash := getTxResult.TxID + outTxID := ob.GetTxID(nonce) + + ob.Mu.Lock() + defer ob.Mu.Unlock() + res, found := ob.includedTxResults[outTxID] + + if !found { // not found. + ob.includedTxHashes[txHash] = true + ob.includedTxResults[outTxID] = getTxResult // include new outTx and enforce rigid 1-to-1 mapping: nonce <===> txHash if nonce >= ob.pendingNonce { // try increasing pending nonce on every newly included outTx ob.pendingNonce = nonce + 1 } @@ -1293,48 +1544,6 @@ func (ob *BTCChainClient) checkTssOutTxResult(cctx *types.CrossChainTx, hash *ch return nil } -// GetTxResultByHash gets the transaction result by hash -func GetTxResultByHash(rpcClient interfaces.BTCRPCClient, txID string) (*chainhash.Hash, *btcjson.GetTransactionResult, error) { - hash, err := chainhash.NewHashFromStr(txID) - if err != nil { - return nil, nil, errors.Wrapf(err, "GetTxResultByHash: error NewHashFromStr: %s", txID) - } - - // The Bitcoin node has to be configured to watch TSS address - txResult, err := rpcClient.GetTransaction(hash) - if err != nil { - return nil, nil, errors.Wrapf(err, "GetOutTxByTxHash: error GetTransaction %s", hash.String()) - } - return hash, txResult, nil -} - -// GetRawTxResult gets the raw tx result -func GetRawTxResult(rpcClient interfaces.BTCRPCClient, hash *chainhash.Hash, res *btcjson.GetTransactionResult) (btcjson.TxRawResult, error) { - if res.Confirmations == 0 { // for pending tx, we query the raw tx directly - rawResult, err := rpcClient.GetRawTransactionVerbose(hash) // for pending tx, we query the raw tx - if err != nil { - return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error GetRawTransactionVerbose %s", res.TxID) - } - return *rawResult, nil - } else if res.Confirmations > 0 { // for confirmed tx, we query the block - blkHash, err := chainhash.NewHashFromStr(res.BlockHash) - if err != nil { - return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error NewHashFromStr for block hash %s", res.BlockHash) - } - block, err := rpcClient.GetBlockVerboseTx(blkHash) - if err != nil { - return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: error GetBlockVerboseTx %s", res.BlockHash) - } - if res.BlockIndex < 0 || res.BlockIndex >= int64(len(block.Tx)) { - return btcjson.TxRawResult{}, errors.Wrapf(err, "getRawTxResult: invalid outTx with invalid block index, TxID %s, BlockIndex %d", res.TxID, res.BlockIndex) - } - return block.Tx[res.BlockIndex], nil - } - - // res.Confirmations < 0 (meaning not included) - return btcjson.TxRawResult{}, fmt.Errorf("getRawTxResult: tx %s not included yet", hash) -} - // checkTSSVin checks vin is valid if: // - The first input is the nonce-mark // - All inputs are from TSS address @@ -1449,49 +1658,6 @@ func (ob *BTCChainClient) checkTSSVoutCancelled(params *types.OutboundTxParams, return nil } -func (ob *BTCChainClient) BuildBroadcastedTxMap() error { - var broadcastedTransactions []clienttypes.OutTxHashSQLType - if err := ob.db.Find(&broadcastedTransactions).Error; err != nil { - ob.logger.Chain.Error().Err(err).Msg("error iterating over db") - return err - } - for _, entry := range broadcastedTransactions { - ob.broadcastedTx[entry.Key] = entry.Hash - } - return nil -} - -func (ob *BTCChainClient) LoadLastBlock() error { - bn, err := ob.rpcClient.GetBlockCount() - if err != nil { - return err - } - - //Load persisted block number - var lastBlockNum clienttypes.LastBlockSQLType - if err := ob.db.First(&lastBlockNum, clienttypes.LastBlockNumID).Error; err != nil { - ob.logger.Chain.Info().Msg("LastBlockNum not found in DB, scan from latest") - ob.SetLastBlockHeightScanned(bn) - } else { - // #nosec G701 always in range - lastBN := int64(lastBlockNum.Num) - ob.SetLastBlockHeightScanned(lastBN) - - //If persisted block number is too low, use the latest height - if (bn - lastBN) > maxHeightDiff { - ob.logger.Chain.Info().Msgf("LastBlockNum too low: %d, scan from latest", lastBlockNum.Num) - ob.SetLastBlockHeightScanned(bn) - } - } - - if ob.chain.ChainId == 18444 { // bitcoin regtest: start from block 100 - ob.SetLastBlockHeightScanned(100) - } - ob.logger.Chain.Info().Msgf("%s: start scanning from block %d", ob.chain.String(), ob.GetLastBlockHeightScanned()) - - return nil -} - func (ob *BTCChainClient) loadDB(dbpath string) error { if _, err := os.Stat(dbpath); os.IsNotExist(err) { err := os.MkdirAll(dbpath, os.ModePerm) @@ -1524,41 +1690,3 @@ func (ob *BTCChainClient) loadDB(dbpath string) error { return err } - -func (ob *BTCChainClient) GetTxID(nonce uint64) string { - tssAddr := ob.Tss.BTCAddress() - return fmt.Sprintf("%d-%s-%d", ob.chain.ChainId, tssAddr, nonce) -} - -type BTCBlockNHeader struct { - Header *wire.BlockHeader - Block *btcjson.GetBlockVerboseTxResult -} - -func (ob *BTCChainClient) GetBlockByNumberCached(blockNumber int64) (*BTCBlockNHeader, error) { - if result, ok := ob.BlockCache.Get(blockNumber); ok { - return result.(*BTCBlockNHeader), nil - } - // Get the block hash - hash, err := ob.rpcClient.GetBlockHash(blockNumber) - if err != nil { - return nil, err - } - // Get the block header - header, err := ob.rpcClient.GetBlockHeader(hash) - if err != nil { - return nil, err - } - // Get the block with verbose transactions - block, err := ob.rpcClient.GetBlockVerboseTx(hash) - if err != nil { - return nil, err - } - blockNheader := &BTCBlockNHeader{ - Header: header, - Block: block, - } - ob.BlockCache.Add(blockNumber, blockNheader) - ob.BlockCache.Add(hash, blockNheader) - return blockNheader, nil -} diff --git a/zetaclient/bitcoin/bitcoin_client_db_test.go b/zetaclient/bitcoin/bitcoin_client_db_test.go index 2f4a58943f..751713b4d7 100644 --- a/zetaclient/bitcoin/bitcoin_client_db_test.go +++ b/zetaclient/bitcoin/bitcoin_client_db_test.go @@ -58,8 +58,7 @@ func (suite *BitcoinClientDBTestSuite) SetupTest() { } } -func (suite *BitcoinClientDBTestSuite) TearDownSuite() { -} +func (suite *BitcoinClientDBTestSuite) TearDownSuite() {} func (suite *BitcoinClientDBTestSuite) TestSubmittedTx() { var submittedTransactions []clienttypes.TransactionResultSQLType diff --git a/zetaclient/bitcoin/bitcoin_client_test.go b/zetaclient/bitcoin/bitcoin_client_test.go index dfa576c9c1..82c7d69917 100644 --- a/zetaclient/bitcoin/bitcoin_client_test.go +++ b/zetaclient/bitcoin/bitcoin_client_test.go @@ -512,7 +512,7 @@ func TestGetBtcEvent(t *testing.T) { // expected result memo, err := hex.DecodeString(tx.Vout[1].ScriptPubKey.Hex[4:]) require.NoError(t, err) - eventExpected := &BTCInTxEvnet{ + eventExpected := &BTCInTxEvent{ FromAddress: "bc1q68kxnq52ahz5vd6c8czevsawu0ux9nfrzzrh6e", ToAddress: tssAddress, Value: tx.Vout[0].Value - depositorFee, // 7008 sataoshis diff --git a/zetaclient/bitcoin/bitcoin_signer.go b/zetaclient/bitcoin/bitcoin_signer.go index a5ff22fa6a..246f6b4de7 100644 --- a/zetaclient/bitcoin/bitcoin_signer.go +++ b/zetaclient/bitcoin/bitcoin_signer.go @@ -38,6 +38,8 @@ const ( consolidationRank = 10 ) +var _ interfaces.ChainSigner = &BTCSigner{} + // BTCSigner deals with signing BTC transactions and implements the ChainSigner interface type BTCSigner struct { tssSigner interfaces.TSSSigner @@ -48,8 +50,6 @@ type BTCSigner struct { coreContext *corecontext.ZetaCoreContext } -var _ interfaces.ChainSigner = &BTCSigner{} - func NewBTCSigner( cfg config.BTCConfig, tssSigner interfaces.TSSSigner, @@ -247,11 +247,12 @@ func (signer *BTCSigner) SignWithdrawTx( return nil, err } } - tss, ok := signer.tssSigner.(*tss.TSS) + + tssSigner, ok := signer.tssSigner.(*tss.TSS) if !ok { return nil, fmt.Errorf("tssSigner is not a TSS") } - sig65Bs, err := tss.SignBatch(witnessHashes, height, nonce, chain) + sig65Bs, err := tssSigner.SignBatch(witnessHashes, height, nonce, chain) if err != nil { return nil, fmt.Errorf("SignBatch error: %v", err) } @@ -270,6 +271,7 @@ func (signer *BTCSigner) SignWithdrawTx( txWitness := wire.TxWitness{append(sig.Serialize(), byte(hashType)), pkCompressed} tx.TxIn[ix].Witness = txWitness } + return tx, nil } @@ -288,6 +290,7 @@ func (signer *BTCSigner) Broadcast(signedTx *wire.MsgTx) error { if err != nil { return err } + signer.logger.Info().Msgf("Broadcasting BTC tx , hash %s ", hash) return nil } diff --git a/zetaclient/bitcoin/bitcoin_test.go b/zetaclient/bitcoin/bitcoin_test.go index 4dae7f8590..5bd13a0d31 100644 --- a/zetaclient/bitcoin/bitcoin_test.go +++ b/zetaclient/bitcoin/bitcoin_test.go @@ -29,9 +29,7 @@ type BTCSignTestSuite struct { const ( prevOut = "07a84f4bd45a633e93871be5c98d958afd13a37f3cf5010f40eec0840d19f5fa" - // tb1q7r6lnqjhvdjuw9uf4ehx7fs0euc6cxnqz7jj50 - pk = "cQkjdfeMU8vHvE6jErnFVqZYYZnGGYy64jH6zovbSXdfTjte6QgY" - utxoCount = 5 + pk = "cQkjdfeMU8vHvE6jErnFVqZYYZnGGYy64jH6zovbSXdfTjte6QgY" ) func (suite *BTCSignTestSuite) SetupTest() { @@ -70,7 +68,6 @@ func (suite *BTCSignTestSuite) TestSign() { suite.T().Logf("wallet signed tx : %v\n", walletSignedTX) // sign tx using tss signature - tssSignedTX, err := getTSSTX(suite.testSigner, tx, txSigHashes, idx, amt, subscript, txscript.SigHashAll) suite.Require().NoError(err) suite.T().Logf("tss signed tx : %v\n", tssSignedTX) diff --git a/zetaclient/bitcoin/fee.go b/zetaclient/bitcoin/fee.go index ab19240264..7b184021aa 100644 --- a/zetaclient/bitcoin/fee.go +++ b/zetaclient/bitcoin/fee.go @@ -36,13 +36,13 @@ const ( ) var ( - // The outtx size incurred by the depositor: 68vB + // BtcOutTxBytesDepositor is the outtx size incurred by the depositor: 68vB BtcOutTxBytesDepositor = OuttxSizeDepositor() - // The outtx size incurred by the withdrawer: 177vB + // BtcOutTxBytesWithdrawer is the outtx size incurred by the withdrawer: 177vB BtcOutTxBytesWithdrawer = OuttxSizeWithdrawer() - // The default depositor fee is 0.00001360 BTC (20 * 68vB / 100000000) + // DefaultDepositorFee is the default depositor fee is 0.00001360 BTC (20 * 68vB / 100000000) // default depositor fee calculation is based on a fixed fee rate of 20 sat/byte just for simplicity. DefaultDepositorFee = DepositorFee(defaultDepositorFeeRate) ) @@ -82,8 +82,10 @@ func EstimateOuttxSize(numInputs uint64, payees []btcutil.Address) (uint64, erro } bytesToPayees += sizeOutput } + // calculate the size of the witness bytesWitness := bytes1stWitness + (numInputs-1)*bytesPerWitness + // https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#transaction-size-calculations // Calculation for signed SegWit tx: blockchain.GetTransactionWeight(tx) / 4 return bytesWiredTx + bytesInput + bytesOutput + bytesToPayees + bytesWitness/blockchain.WitnessScaleFactor, nil @@ -133,6 +135,7 @@ func OuttxSizeWithdrawer() uint64 { bytesInput := uint64(1) * bytesPerInput // nonce mark bytesOutput := uint64(2) * bytesPerOutputP2WPKH // 2 P2WPKH outputs: new nonce mark, change bytesOutput += bytesPerOutputAvg // 1 output to withdrawer's address + return bytesWiredTx + bytesInput + bytesOutput + bytes1stWitness/blockchain.WitnessScaleFactor } @@ -151,6 +154,7 @@ func CalcBlockAvgFeeRate(blockVb *btcjson.GetBlockVerboseTxResult, netParams *ch if len(blockVb.Tx) == 1 { return 0, nil // only coinbase tx, it happens } + txCoinbase := &blockVb.Tx[0] if blockVb.Weight < blockchain.WitnessScaleFactor { return 0, fmt.Errorf("block weight %d too small", blockVb.Weight) @@ -200,6 +204,7 @@ func CalcBlockAvgFeeRate(blockVb *btcjson.GetBlockVerboseTxResult, netParams *ch // calculate average fee rate. vBytes := txsWeight / blockchain.WitnessScaleFactor + return txsFees / int64(vBytes), nil } @@ -220,7 +225,9 @@ func CalcDepositorFee(blockVb *btcjson.GetBlockVerboseTxResult, chainID int64, n feeRate = defaultDepositorFeeRate // use default fee rate if calculation fails, should not happen logger.Error().Err(err).Msgf("cannot calculate fee rate for block %d", blockVb.Height) } + // #nosec G701 always in range feeRate = int64(float64(feeRate) * clientcommon.BTCOuttxGasPriceMultiplier) + return DepositorFee(feeRate) } diff --git a/zetaclient/bitcoin/inbound_tracker.go b/zetaclient/bitcoin/inbound_tracker.go index e0dbd595cb..c1e97c14d2 100644 --- a/zetaclient/bitcoin/inbound_tracker.go +++ b/zetaclient/bitcoin/inbound_tracker.go @@ -38,11 +38,13 @@ func (ob *BTCChainClient) WatchIntxTracker() { } } +// ObserveTrackerSuggestions checks for inbound tracker suggestions func (ob *BTCChainClient) ObserveTrackerSuggestions() error { trackers, err := ob.zetaClient.GetInboundTrackersForChain(ob.chain.ChainId) if err != nil { return err } + for _, tracker := range trackers { ob.logger.InTx.Info().Msgf("checking tracker with hash :%s and coin-type :%s ", tracker.TxHash, tracker.CoinType) ballotIdentifier, err := ob.CheckReceiptForBtcTxHash(tracker.TxHash, true) @@ -51,49 +53,61 @@ func (ob *BTCChainClient) ObserveTrackerSuggestions() error { } ob.logger.InTx.Info().Msgf("Vote submitted for inbound Tracker,Chain : %s,Ballot Identifier : %s, coin-type %s", ob.chain.ChainName, ballotIdentifier, coin.CoinType_Gas.String()) } + return nil } +// CheckReceiptForBtcTxHash checks the receipt for a btc tx hash func (ob *BTCChainClient) CheckReceiptForBtcTxHash(txHash string, vote bool) (string, error) { hash, err := chainhash.NewHashFromStr(txHash) if err != nil { return "", err } + tx, err := ob.rpcClient.GetRawTransactionVerbose(hash) if err != nil { return "", err } + blockHash, err := chainhash.NewHashFromStr(tx.BlockHash) if err != nil { return "", err } + blockVb, err := ob.rpcClient.GetBlockVerboseTx(blockHash) if err != nil { return "", err } + if len(blockVb.Tx) <= 1 { return "", fmt.Errorf("block %d has no transactions", blockVb.Height) } + depositorFee := CalcDepositorFee(blockVb, ob.chain.ChainId, ob.netParams, ob.logger.InTx) tss, err := ob.zetaClient.GetBtcTssAddress(ob.chain.ChainId) if err != nil { return "", err } + // #nosec G701 always positive event, err := GetBtcEvent(ob.rpcClient, *tx, tss, uint64(blockVb.Height), ob.logger.InTx, ob.netParams, depositorFee) if err != nil { return "", err } + if event == nil { return "", errors.New("no btc deposit event found") } + msg := ob.GetInboundVoteMessageFromBtcEvent(event) if msg == nil { return "", errors.New("no message built for btc sent to TSS") } + if !vote { return msg.Digest(), nil } + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(zetabridge.PostVoteInboundGasLimit, zetabridge.PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.InTx.Error().Err(err).Msg("error posting to zeta core") @@ -102,5 +116,6 @@ func (ob *BTCChainClient) CheckReceiptForBtcTxHash(txHash string, vote bool) (st ob.logger.InTx.Info().Msgf("BTC deposit detected and reported: PostVoteInbound zeta tx hash: %s inTx %s ballot %s fee %v", zetaHash, txHash, ballot, depositorFee) } + return msg.Digest(), nil } diff --git a/zetaclient/bitcoin/tx_script.go b/zetaclient/bitcoin/tx_script.go index 08046b0171..f68fc0e224 100644 --- a/zetaclient/bitcoin/tx_script.go +++ b/zetaclient/bitcoin/tx_script.go @@ -18,19 +18,19 @@ import ( ) const ( - // Lenth of P2TR script [OP_1 0x20 <32-byte-hash>] + // LengthScriptP2TR is the lenth of P2TR script [OP_1 0x20 <32-byte-hash>] LengthScriptP2TR = 34 - // Length of P2WSH script [OP_0 0x20 <32-byte-hash>] + // LengthScriptP2WSH is the length of P2WSH script [OP_0 0x20 <32-byte-hash>] LengthScriptP2WSH = 34 - // Length of P2WPKH script [OP_0 0x14 <20-byte-hash>] + // LengthScriptP2WPKH is the length of P2WPKH script [OP_0 0x14 <20-byte-hash>] LengthScriptP2WPKH = 22 - // Length of P2SH script [OP_HASH160 0x14 <20-byte-hash> OP_EQUAL] + // LengthScriptP2SH is the length of P2SH script [OP_HASH160 0x14 <20-byte-hash> OP_EQUAL] LengthScriptP2SH = 23 - // Length of P2PKH script [OP_DUP OP_HASH160 0x14 <20-byte-hash> OP_EQUALVERIFY OP_CHECKSIG] + // LengthScriptP2PKH is the length of P2PKH script [OP_DUP OP_HASH160 0x14 <20-byte-hash> OP_EQUALVERIFY OP_CHECKSIG] LengthScriptP2PKH = 25 ) @@ -87,11 +87,13 @@ func DecodeScriptP2TR(scriptHex string, net *chaincfg.Params) (string, error) { if !IsPkScriptP2TR(script) { return "", fmt.Errorf("invalid P2TR script: %s", scriptHex) } + witnessProg := script[2:] receiverAddress, err := chains.NewAddressTaproot(witnessProg, net) if err != nil { // should never happen return "", errors.Wrapf(err, "error getting address from script %s", scriptHex) } + return receiverAddress.EncodeAddress(), nil } @@ -104,11 +106,13 @@ func DecodeScriptP2WSH(scriptHex string, net *chaincfg.Params) (string, error) { if !IsPkScriptP2WSH(script) { return "", fmt.Errorf("invalid P2WSH script: %s", scriptHex) } + witnessProg := script[2:] receiverAddress, err := btcutil.NewAddressWitnessScriptHash(witnessProg, net) if err != nil { // should never happen return "", errors.Wrapf(err, "error getting receiver from script: %s", scriptHex) } + return receiverAddress.EncodeAddress(), nil } @@ -121,11 +125,13 @@ func DecodeScriptP2WPKH(scriptHex string, net *chaincfg.Params) (string, error) if !IsPkScriptP2WPKH(script) { return "", fmt.Errorf("invalid P2WPKH script: %s", scriptHex) } + witnessProg := script[2:] receiverAddress, err := btcutil.NewAddressWitnessPubKeyHash(witnessProg, net) if err != nil { // should never happen return "", errors.Wrapf(err, "error getting receiver from script: %s", scriptHex) } + return receiverAddress.EncodeAddress(), nil } @@ -138,7 +144,9 @@ func DecodeScriptP2SH(scriptHex string, net *chaincfg.Params) (string, error) { if !IsPkScriptP2SH(script) { return "", fmt.Errorf("invalid P2SH script: %s", scriptHex) } + scriptHash := script[2:22] + return EncodeAddress(scriptHash, net.ScriptHashAddrID), nil } @@ -151,7 +159,9 @@ func DecodeScriptP2PKH(scriptHex string, net *chaincfg.Params) (string, error) { if !IsPkScriptP2PKH(script) { return "", fmt.Errorf("invalid P2PKH script: %s", scriptHex) } + pubKeyHash := script[3:23] + return EncodeAddress(pubKeyHash, net.PubKeyHashAddrID), nil } @@ -166,6 +176,7 @@ func DecodeOpReturnMemo(scriptHex string, txid string) ([]byte, bool, error) { if int(memoSize) != (len(scriptHex)-4)/2 { return nil, false, fmt.Errorf("memo size mismatch: %d != %d", memoSize, (len(scriptHex)-4)/2) } + memoBytes, err := hex.DecodeString(scriptHex[4:]) if err != nil { return nil, false, errors.Wrapf(err, "error hex decoding memo: %s", scriptHex) @@ -175,6 +186,7 @@ func DecodeOpReturnMemo(scriptHex string, txid string) ([]byte, bool, error) { } return memoBytes, true, nil } + return nil, false, nil } @@ -196,16 +208,19 @@ func DecodeTSSVout(vout btcjson.Vout, receiverExpected string, chain chains.Chai if err != nil { return "", 0, errors.Wrap(err, "error getting satoshis") } + // get btc chain params chainParams, err := chains.GetBTCChainParams(chain.ChainId) if err != nil { return "", 0, errors.Wrapf(err, "error GetBTCChainParams for chain %d", chain.ChainId) } + // decode cctx receiver address addr, err := chains.DecodeBtcAddress(receiverExpected, chain.ChainId) if err != nil { return "", 0, errors.Wrapf(err, "error decoding receiver %s", receiverExpected) } + // parse receiver address from vout var receiverVout string switch addr.(type) { @@ -225,5 +240,6 @@ func DecodeTSSVout(vout btcjson.Vout, receiverExpected string, chain chains.Chai if err != nil { return "", 0, errors.Wrap(err, "error decoding TSS vout") } + return receiverVout, amount, nil } diff --git a/zetaclient/common/logger.go b/zetaclient/common/logger.go index 251f4cf774..6098b67084 100644 --- a/zetaclient/common/logger.go +++ b/zetaclient/common/logger.go @@ -5,11 +5,13 @@ import ( "github.com/rs/zerolog/log" ) +// ClientLogger is a struct that contains the logger for a chain client type ClientLogger struct { Std zerolog.Logger Compliance zerolog.Logger } +// DefaultLoggers returns the default loggers for a chain client func DefaultLoggers() ClientLogger { return ClientLogger{ Std: log.Logger, diff --git a/zetaclient/compliance/compliance.go b/zetaclient/compliance/compliance.go index 4bfd08fdf5..db7db6bcc4 100644 --- a/zetaclient/compliance/compliance.go +++ b/zetaclient/compliance/compliance.go @@ -10,30 +10,34 @@ import ( func IsCctxRestricted(cctx *crosschaintypes.CrossChainTx) bool { sender := cctx.InboundTxParams.Sender receiver := cctx.GetCurrentOutTxParam().Receiver + return config.ContainRestrictedAddress(sender, receiver) } // PrintComplianceLog prints compliance log with fields [chain, cctx/intx, chain, sender, receiver, token] func PrintComplianceLog( - logger1 zerolog.Logger, - logger2 zerolog.Logger, + inboundLogger zerolog.Logger, + complianceLogger zerolog.Logger, outbound bool, chainID int64, - identifier, sender, receiver, token string) { + identifier, sender, receiver, token string, +) { var logMsg string - var logWithFields1 zerolog.Logger - var logWithFields2 zerolog.Logger + var inboundLoggerWithFields zerolog.Logger + var complianceLoggerWithFields zerolog.Logger + if outbound { // we print cctx for outbound tx logMsg = "Restricted address detected in cctx" - logWithFields1 = logger1.With().Int64("chain", chainID).Str("cctx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() - logWithFields2 = logger2.With().Int64("chain", chainID).Str("cctx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() + inboundLoggerWithFields = inboundLogger.With().Int64("chain", chainID).Str("cctx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() + complianceLoggerWithFields = complianceLogger.With().Int64("chain", chainID).Str("cctx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() } else { // we print intx for inbound tx logMsg = "Restricted address detected in intx" - logWithFields1 = logger1.With().Int64("chain", chainID).Str("intx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() - logWithFields2 = logger2.With().Int64("chain", chainID).Str("intx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() + inboundLoggerWithFields = inboundLogger.With().Int64("chain", chainID).Str("intx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() + complianceLoggerWithFields = complianceLogger.With().Int64("chain", chainID).Str("intx", identifier).Str("sender", sender).Str("receiver", receiver).Str("token", token).Logger() } - logWithFields1.Warn().Msg(logMsg) - logWithFields2.Warn().Msg(logMsg) + + inboundLoggerWithFields.Warn().Msg(logMsg) + complianceLoggerWithFields.Warn().Msg(logMsg) } diff --git a/zetaclient/config/config.go b/zetaclient/config/config.go index 4cb0e6b21b..8680071c3c 100644 --- a/zetaclient/config/config.go +++ b/zetaclient/config/config.go @@ -21,6 +21,7 @@ func Save(config *Config, path string) error { if err != nil { return err } + file := filepath.Join(path, folder, filename) file = filepath.Clean(file) @@ -28,10 +29,12 @@ func Save(config *Config, path string) error { if err != nil { return err } + err = os.WriteFile(file, jsonFile, 0600) if err != nil { return err } + return nil } diff --git a/zetaclient/config/config_chain.go b/zetaclient/config/config_chain.go index f211f1030d..bb414c6161 100644 --- a/zetaclient/config/config_chain.go +++ b/zetaclient/config/config_chain.go @@ -3,14 +3,6 @@ package config import "github.com/zeta-chain/zetacore/pkg/chains" const ( - BtcConfirmationCount = 1 - DevEthConfirmationCount = 2 - - // TssTestPrivkey is the private key of the TSS address - // #nosec G101 - used for testing only - TssTestPrivkey = "2082bc9775d6ee5a05ef221a9d1c00b3cc3ecb274a4317acc0a182bc1e05d1bb" - TssTestAddress = "0xE80B6467863EbF8865092544f441da8fD3cF6074" - MaxBlocksPerPeriod = 100 ) diff --git a/zetaclient/core_context/zeta_core_context.go b/zetaclient/core_context/zeta_core_context.go index 5bb8d23089..e602512fd6 100644 --- a/zetaclient/core_context/zeta_core_context.go +++ b/zetaclient/core_context/zeta_core_context.go @@ -35,11 +35,13 @@ func NewZetaCoreContext(cfg config.Config) *ZetaCoreContext { for _, e := range cfg.EVMChainConfigs { evmChainParams[e.Chain.ChainId] = &observertypes.ChainParams{} } + var bitcoinChainParams *observertypes.ChainParams _, found := cfg.GetBTCConfig() if found { bitcoinChainParams = &observertypes.ChainParams{} } + return &ZetaCoreContext{ coreContextLock: new(sync.RWMutex), chainsEnabled: []chains.Chain{}, @@ -59,6 +61,7 @@ func (c *ZetaCoreContext) GetKeygen() observertypes.Keygen { copiedPubkeys = make([]string, len(c.keygen.GranteePubkeys)) copy(copiedPubkeys, c.keygen.GranteePubkeys) } + return observertypes.Keygen{ Status: c.keygen.Status, GranteePubkeys: copiedPubkeys, @@ -107,10 +110,12 @@ func (c *ZetaCoreContext) GetBTCChainParams() (chains.Chain, *observertypes.Chai if c.bitcoinChainParams == nil { // bitcoin is not enabled return chains.Chain{}, &observertypes.ChainParams{}, false } + chain := chains.GetChainFromChainID(c.bitcoinChainParams.ChainId) if chain == nil { panic(fmt.Sprintf("BTCChain is missing for chainID %d", c.bitcoinChainParams.ChainId)) } + return *chain, c.bitcoinChainParams, true } @@ -146,6 +151,7 @@ func (c *ZetaCoreContext) Update( sort.SliceStable(newChains, func(i, j int) bool { return newChains[i].ChainId < newChains[j].ChainId }) + if len(newChains) == 0 { logger.Warn().Msg("UpdateChainParams: No chains enabled in ZeroCore") } @@ -170,16 +176,20 @@ func (c *ZetaCoreContext) Update( } } } + if keygen != nil { c.keygen = *keygen } + c.chainsEnabled = newChains c.crossChainFlags = crosschainFlags c.verificationFlags = verificationFlags + // update chain params for bitcoin if it has config in file if c.bitcoinChainParams != nil && btcChainParams != nil { c.bitcoinChainParams = btcChainParams } + // update core params for evm chains we have configs in file for _, params := range evmChainParams { _, found := c.evmChainParams[params.ChainId] diff --git a/zetaclient/evm/constant.go b/zetaclient/evm/constant.go index 8dcd2309d6..d3a22adef9 100644 --- a/zetaclient/evm/constant.go +++ b/zetaclient/evm/constant.go @@ -12,22 +12,27 @@ const ( // OutTxTrackerReportTimeout is the timeout for waiting for an outtx tracker report OutTxTrackerReportTimeout = 10 * time.Minute + // TopicsZetaSent is the number of topics for a Zeta sent event // [signature, zetaTxSenderAddress, destinationChainId] // https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L34 TopicsZetaSent = 3 + // TopicsZetaReceived is the number of topics for a Zeta received event // [signature, sourceChainId, destinationAddress, internalSendHash] // https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L45 TopicsZetaReceived = 4 + // TopicsZetaReverted is the number of topics for a Zeta reverted event // [signature, destinationChainId, internalSendHash] // https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L54 TopicsZetaReverted = 3 + // TopicsWithdrawn is the number of topics for a withdrawn event // [signature, recipient, asset] // https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L43 TopicsWithdrawn = 3 + // TopicsDeposited is the number of topics for a deposited event // [signature, asset] // https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L42 TopicsDeposited = 2 diff --git a/zetaclient/evm/evm_client.go b/zetaclient/evm/evm_client.go index 63e8da7d7c..f86211fe60 100644 --- a/zetaclient/evm/evm_client.go +++ b/zetaclient/evm/evm_client.go @@ -13,6 +13,9 @@ import ( "sync/atomic" "time" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" @@ -31,35 +34,37 @@ import ( "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" "github.com/zeta-chain/zetacore/pkg/proofs" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" appcontext "github.com/zeta-chain/zetacore/zetaclient/app_context" clientcommon "github.com/zeta-chain/zetacore/zetaclient/common" + "github.com/zeta-chain/zetacore/zetaclient/compliance" "github.com/zeta-chain/zetacore/zetaclient/config" corecontext "github.com/zeta-chain/zetacore/zetaclient/core_context" "github.com/zeta-chain/zetacore/zetaclient/interfaces" "github.com/zeta-chain/zetacore/zetaclient/metrics" clienttypes "github.com/zeta-chain/zetacore/zetaclient/types" "github.com/zeta-chain/zetacore/zetaclient/zetabridge" - "gorm.io/driver/sqlite" - "gorm.io/gorm" ) -type TxHashEnvelope struct { - TxHash string - Done chan struct{} -} +// Logger is the logger for evm chains +// TODO: Merge this logger with the one in bitcoin +// https://github.com/zeta-chain/node/issues/2022 +type Logger struct { + // Chain is the parent logger for the chain + Chain zerolog.Logger -type OutTx struct { - SendHash string - TxHash string - Nonce int64 -} -type Log struct { - Chain zerolog.Logger // The parent logger for the chain - InTx zerolog.Logger // Logger for incoming trasnactions - OutTx zerolog.Logger // Logger for outgoing transactions - GasPrice zerolog.Logger // Logger for gas prices - Compliance zerolog.Logger // Logger for compliance checks + // InTx is the logger for incoming transactions + InTx zerolog.Logger + + // OutTx is the logger for outgoing transactions + OutTx zerolog.Logger + + // GasPrice is the logger for gas prices + GasPrice zerolog.Logger + + // Compliance is the logger for compliance checks + Compliance zerolog.Logger } var _ interfaces.ChainClient = &ChainClient{} @@ -67,22 +72,26 @@ var _ interfaces.ChainClient = &ChainClient{} // ChainClient represents the chain configuration for an EVM chain // Filled with above constants depending on chain type ChainClient struct { + Tss interfaces.TSSSigner + + // BlockTimeExternalChain is the block time of the external chain + BlockTimeExternalChain uint64 + + Mu *sync.Mutex + chain chains.Chain evmClient interfaces.EVMRPCClient evmJSONRPC interfaces.EVMJSONRPCClient zetaBridge interfaces.ZetaCoreBridger - Tss interfaces.TSSSigner lastBlockScanned uint64 lastBlock uint64 - BlockTimeExternalChain uint64 // block time in seconds txWatchList map[ethcommon.Hash]string - Mu *sync.Mutex db *gorm.DB outTxPendingTransactions map[string]*ethtypes.Transaction outTXConfirmedReceipts map[string]*ethtypes.Receipt outTXConfirmedTransactions map[string]*ethtypes.Transaction stop chan struct{} - logger Log + logger Logger coreContext *corecontext.ZetaCoreContext chainParams observertypes.ChainParams ts *metrics.TelemetryServer @@ -104,19 +113,22 @@ func NewEVMChainClient( ob := ChainClient{ ts: ts, } + chainLogger := loggers.Std.With().Str("chain", evmCfg.Chain.ChainName.String()).Logger() - ob.logger = Log{ + ob.logger = Logger{ Chain: chainLogger, InTx: chainLogger.With().Str("module", "WatchInTx").Logger(), OutTx: chainLogger.With().Str("module", "WatchOutTx").Logger(), GasPrice: chainLogger.With().Str("module", "WatchGasPrice").Logger(), Compliance: loggers.Compliance, } + ob.coreContext = appContext.ZetaCoreContext() chainParams, found := ob.coreContext.GetEVMChainParams(evmCfg.Chain.ChainId) if !found { return nil, fmt.Errorf("evm chains params not initialized for chain %d", evmCfg.Chain.ChainId) } + ob.chainParams = *chainParams ob.stop = make(chan struct{}) ob.chain = evmCfg.Chain @@ -134,6 +146,7 @@ func NewEVMChainClient( ob.logger.Chain.Error().Err(err).Msg("eth Client Dial") return nil, err } + ob.evmClient = client ob.evmJSONRPC = ethrpc.NewEthRPC(evmCfg.Endpoint) @@ -143,6 +156,7 @@ func NewEVMChainClient( ob.logger.Chain.Error().Err(err).Msg("failed to create block cache") return nil, err } + ob.headerCache, err = lru.New(1000) if err != nil { ob.logger.Chain.Error().Err(err).Msg("failed to create header cache") @@ -170,7 +184,7 @@ func (ob *ChainClient) WithChain(chain chains.Chain) { func (ob *ChainClient) WithLogger(logger zerolog.Logger) { ob.Mu.Lock() defer ob.Mu.Unlock() - ob.logger = Log{ + ob.logger = Logger{ Chain: logger, InTx: logger.With().Str("module", "WatchInTx").Logger(), OutTx: logger.With().Str("module", "WatchOutTx").Logger(), @@ -262,11 +276,20 @@ func FetchERC20CustodyContract(addr ethcommon.Address, client interfaces.EVMRPCC // Start all observation routines for the evm chain func (ob *ChainClient) Start() { - go ob.WatchInTx() // watch evm chain for incoming txs and post votes to zetacore - go ob.WatchOutTx() // watch evm chain for outgoing txs status - go ob.WatchGasPrice() // watch evm chain for gas prices and post to zetacore - go ob.WatchIntxTracker() // watch zetacore for intx trackers - go ob.WatchRPCStatus() // watch the RPC status of the evm chain + // watch evm chain for incoming txs and post votes to zetacore + go ob.WatchInTx() + + // watch evm chain for outgoing txs status + go ob.WatchOutTx() + + // watch evm chain for gas prices and post to zetacore + go ob.WatchGasPrice() + + // watch zetacore for intx trackers + go ob.WatchIntxTracker() + + // watch the RPC status of the evm chain + go ob.WatchRPCStatus() } // WatchRPCStatus watches the RPC status of the evm chain @@ -325,6 +348,300 @@ func (ob *ChainClient) Stop() { ob.logger.Chain.Info().Msgf("%s observer stopped", ob.chain.String()) } +// IsSendOutTxProcessed returns isIncluded, isConfirmed, Error +// if isConfirmed, it also post to ZetaCore +func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, logger zerolog.Logger) (bool, bool, error) { + sendHash := cctx.Index + cointype := cctx.InboundTxParams.CoinType + nonce := cctx.GetCurrentOutTxParam().OutboundTxTssNonce + + // skip if outtx is not confirmed + params := ob.GetChainParams() + receipt, transaction := ob.GetTxNReceipt(nonce) + if receipt == nil || transaction == nil { // not confirmed yet + return false, false, nil + } + + sendID := fmt.Sprintf("%s-%d", ob.chain.String(), nonce) + logger = logger.With().Str("sendID", sendID).Logger() + + // compliance check, special handling the cancelled cctx + if compliance.IsCctxRestricted(cctx) { + recvStatus := chains.ReceiveStatus_Failed + if receipt.Status == 1 { + recvStatus = chains.ReceiveStatus_Success + } + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + // use cctx's amount to bypass the amount check in zetacore + cctx.GetCurrentOutTxParam().Amount.BigInt(), + recvStatus, + ob.chain, + nonce, + coin.CoinType_Cmd, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + + if cointype == coin.CoinType_Cmd { + recvStatus := chains.ReceiveStatus_Failed + if receipt.Status == 1 { + recvStatus = chains.ReceiveStatus_Success + } + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + transaction.Value(), + recvStatus, + ob.chain, + nonce, + coin.CoinType_Cmd, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + + } else if cointype == coin.CoinType_Gas { // the outbound is a regular Ether/BNB/Matic transfer; no need to check events + if receipt.Status == 1 { + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + transaction.Value(), + chains.ReceiveStatus_Success, + ob.chain, + nonce, + coin.CoinType_Gas, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } else if receipt.Status == 0 { // the same as below events flow + logger.Info().Msgf("Found (failed tx) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), receipt.TxHash.Hex()) + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + big.NewInt(0), + chains.ReceiveStatus_Failed, + ob.chain, + nonce, + coin.CoinType_Gas, + ) + if err != nil { + logger.Error().Err(err).Msgf("PostVoteOutbound error in WatchTxHashWithTimeout; zeta tx hash %s cctx %s nonce %d", zetaTxHash, sendHash, nonce) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + } else if cointype == coin.CoinType_Zeta { // the outbound is a Zeta transfer; need to check events ZetaReceived + if receipt.Status == 1 { + logs := receipt.Logs + for _, vLog := range logs { + confHeight := vLog.BlockNumber + params.ConfirmationCount + // TODO rewrite this to return early if not confirmed + connectorAddr, connector, err := ob.GetConnectorContract() + if err != nil { + return false, false, fmt.Errorf("error getting connector contract: %w", err) + } + receivedLog, err := connector.ZetaConnectorNonEthFilterer.ParseZetaReceived(*vLog) + if err == nil { + logger.Info().Msgf("Found (outTx) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), vLog.TxHash.Hex()) + if confHeight <= ob.GetLastBlockHeight() { + logger.Info().Msg("Confirmed! Sending PostConfirmation to zetabridge...") + // sanity check tx event + err = ValidateEvmTxLog(vLog, connectorAddr, transaction.Hash().Hex(), TopicsZetaReceived) + if err != nil { + logger.Error().Err(err).Msgf("CheckEvmTxLog error on ZetaReceived event, chain %d nonce %d txhash %s", ob.chain.ChainId, nonce, transaction.Hash().Hex()) + return false, false, err + } + sendhash := vLog.Topics[3].Hex() + //var rxAddress string = ethcommon.HexToAddress(vLog.Topics[1].Hex()).Hex() + mMint := receivedLog.ZetaValue + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendhash, + vLog.TxHash.Hex(), + vLog.BlockNumber, + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + mMint, + chains.ReceiveStatus_Success, + ob.chain, + nonce, + coin.CoinType_Zeta, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + continue + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + logger.Info().Msgf("Included; %d blocks before confirmed! chain %s nonce %d", confHeight-ob.GetLastBlockHeight(), ob.chain.String(), nonce) + return true, false, nil + } + revertedLog, err := connector.ZetaConnectorNonEthFilterer.ParseZetaReverted(*vLog) + if err == nil { + logger.Info().Msgf("Found (revertTx) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), vLog.TxHash.Hex()) + if confHeight <= ob.GetLastBlockHeight() { + logger.Info().Msg("Confirmed! Sending PostConfirmation to zetabridge...") + // sanity check tx event + err = ValidateEvmTxLog(vLog, connectorAddr, transaction.Hash().Hex(), TopicsZetaReverted) + if err != nil { + logger.Error().Err(err).Msgf("CheckEvmTxLog error on ZetaReverted event, chain %d nonce %d txhash %s", ob.chain.ChainId, nonce, transaction.Hash().Hex()) + return false, false, err + } + sendhash := vLog.Topics[2].Hex() + mMint := revertedLog.RemainingZetaValue + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendhash, + vLog.TxHash.Hex(), + vLog.BlockNumber, + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + mMint, + chains.ReceiveStatus_Success, + ob.chain, + nonce, + coin.CoinType_Zeta, + ) + if err != nil { + logger.Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + continue + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + logger.Info().Msgf("Included; %d blocks before confirmed! chain %s nonce %d", confHeight-ob.GetLastBlockHeight(), ob.chain.String(), nonce) + return true, false, nil + } + } + } else if receipt.Status == 0 { + //FIXME: check nonce here by getTransaction RPC + logger.Info().Msgf("Found (failed tx) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), receipt.TxHash.Hex()) + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + big.NewInt(0), + chains.ReceiveStatus_Failed, + ob.chain, + nonce, + coin.CoinType_Zeta, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + } else if cointype == coin.CoinType_ERC20 { + if receipt.Status == 1 { + logs := receipt.Logs + addrCustody, ERC20Custody, err := ob.GetERC20CustodyContract() + if err != nil { + logger.Warn().Msgf("NewERC20Custody err: %s", err) + } + for _, vLog := range logs { + event, err := ERC20Custody.ParseWithdrawn(*vLog) + confHeight := vLog.BlockNumber + params.ConfirmationCount + if err == nil { + logger.Info().Msgf("Found (ERC20Custody.Withdrawn Event) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), vLog.TxHash.Hex()) + // sanity check tx event + err = ValidateEvmTxLog(vLog, addrCustody, transaction.Hash().Hex(), TopicsWithdrawn) + if err != nil { + logger.Error().Err(err).Msgf("CheckEvmTxLog error on Withdrawn event, chain %d nonce %d txhash %s", ob.chain.ChainId, nonce, transaction.Hash().Hex()) + return false, false, err + } + if confHeight <= ob.GetLastBlockHeight() { + logger.Info().Msg("Confirmed! Sending PostConfirmation to zetabridge...") + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + vLog.TxHash.Hex(), + vLog.BlockNumber, + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + event.Amount, + chains.ReceiveStatus_Success, + ob.chain, + nonce, + coin.CoinType_ERC20, + ) + if err != nil { + logger.Error().Err(err).Msgf("error posting confirmation to meta core for cctx %s nonce %d", sendHash, nonce) + continue + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + logger.Info().Msgf("Included; %d blocks before confirmed! chain %s nonce %d", confHeight-ob.GetLastBlockHeight(), ob.chain.String(), nonce) + return true, false, nil + } + } + } else { + logger.Info().Msgf("Found (failed tx) sendHash %s on chain %s txhash %s", sendHash, ob.chain.String(), receipt.TxHash.Hex()) + zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( + sendHash, + receipt.TxHash.Hex(), + receipt.BlockNumber.Uint64(), + receipt.GasUsed, + transaction.GasPrice(), + transaction.Gas(), + big.NewInt(0), + chains.ReceiveStatus_Failed, + ob.chain, + nonce, + coin.CoinType_ERC20, + ) + if err != nil { + logger.Error().Err(err).Msgf("PostVoteOutbound error in WatchTxHashWithTimeout; zeta tx hash %s", zetaTxHash) + } else if zetaTxHash != "" { + logger.Info().Msgf("Zeta tx hash: %s cctx %s nonce %d ballot %s", zetaTxHash, sendHash, nonce, ballot) + } + return true, true, nil + } + } + + return false, false, nil +} + // WatchOutTx watches evm chain for outgoing txs status func (ob *ChainClient) WatchOutTx() { ticker, err := clienttypes.NewDynamicTicker(fmt.Sprintf("EVM_WatchOutTx_%d", ob.chain.ChainId), ob.GetChainParams().OutTxTicker) @@ -420,77 +737,6 @@ func (ob *ChainClient) IsTxConfirmed(nonce uint64) bool { return ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] != nil && ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] != nil } -// checkConfirmedTx checks if a txHash is confirmed -// returns (receipt, transaction, true) if confirmed or (nil, nil, false) otherwise -func (ob *ChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction, bool) { - ctxt, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() - - // query transaction - transaction, isPending, err := ob.evmClient.TransactionByHash(ctxt, ethcommon.HexToHash(txHash)) - if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: error getting transaction for outtx %s chain %d", txHash, ob.chain.ChainId) - return nil, nil, false - } - if transaction == nil { // should not happen - log.Error().Msgf("confirmTxByHash: transaction is nil for txHash %s nonce %d", txHash, nonce) - return nil, nil, false - } - - // check tx sender and nonce - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - from, err := signer.Sender(transaction) - if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: local recovery of sender address failed for outtx %s chain %d", transaction.Hash().Hex(), ob.chain.ChainId) - return nil, nil, false - } - if from != ob.Tss.EVMAddress() { // must be TSS address - log.Error().Msgf("confirmTxByHash: sender %s for outtx %s chain %d is not TSS address %s", - from.Hex(), transaction.Hash().Hex(), ob.chain.ChainId, ob.Tss.EVMAddress().Hex()) - return nil, nil, false - } - if transaction.Nonce() != nonce { // must match cctx nonce - log.Error().Msgf("confirmTxByHash: outtx %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) - return nil, nil, false - } - - // save pending transaction - if isPending { - ob.SetPendingTx(nonce, transaction) - return nil, nil, false - } - - // query receipt - receipt, err := ob.evmClient.TransactionReceipt(ctxt, ethcommon.HexToHash(txHash)) - if err != nil { - if err != ethereum.NotFound { - log.Warn().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) - } - return nil, nil, false - } - if receipt == nil { // should not happen - log.Error().Msgf("confirmTxByHash: receipt is nil for txHash %s nonce %d", txHash, nonce) - return nil, nil, false - } - - // check confirmations - if !ob.HasEnoughConfirmations(receipt, ob.GetLastBlockHeight()) { - log.Debug().Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", - txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) - return nil, nil, false - } - - // cross-check tx inclusion against the block - // Note: a guard for false BlockNumber in receipt. The blob-carrying tx won't come here - err = ob.CheckTxInclusion(transaction, receipt) - if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: checkTxInclusion error for txHash %s nonce %d", txHash, nonce) - return nil, nil, false - } - - return receipt, transaction, true -} - // CheckTxInclusion returns nil only if tx is included at the position indicated by the receipt ([block, index]) func (ob *ChainClient) CheckTxInclusion(tx *ethtypes.Transaction, receipt *ethtypes.Receipt) error { block, err := ob.GetBlockByNumberCached(receipt.BlockNumber.Uint64()) @@ -498,17 +744,20 @@ func (ob *ChainClient) CheckTxInclusion(tx *ethtypes.Transaction, receipt *ethty return errors.Wrapf(err, "GetBlockByNumberCached error for block %d txHash %s nonce %d", receipt.BlockNumber.Uint64(), tx.Hash(), tx.Nonce()) } + // #nosec G701 non negative value if receipt.TransactionIndex >= uint(len(block.Transactions)) { return fmt.Errorf("transaction index %d out of range [0, %d), txHash %s nonce %d block %d", receipt.TransactionIndex, len(block.Transactions), tx.Hash(), tx.Nonce(), receipt.BlockNumber.Uint64()) } + txAtIndex := block.Transactions[receipt.TransactionIndex] if !strings.EqualFold(txAtIndex.Hash, tx.Hash().Hex()) { ob.RemoveCachedBlock(receipt.BlockNumber.Uint64()) // clean stale block from cache return fmt.Errorf("transaction at index %d has different hash %s, txHash %s nonce %d block %d", receipt.TransactionIndex, txAtIndex.Hash, tx.Hash(), tx.Nonce(), receipt.BlockNumber.Uint64()) } + return nil } @@ -548,10 +797,11 @@ func (ob *ChainClient) WatchInTx() { ob.logger.InTx.Error().Err(err).Msg("error creating ticker") return } - defer ticker.Stop() + ob.logger.InTx.Info().Msgf("WatchInTx started for chain %d", ob.chain.ChainId) sampledLogger := ob.logger.InTx.Sample(&zerolog.BasicSampler{N: 10}) + for { select { case <-ticker.C(): @@ -571,114 +821,6 @@ func (ob *ChainClient) WatchInTx() { } } -// calcBlockRangeToScan calculates the next range of blocks to scan -func (ob *ChainClient) calcBlockRangeToScan(latestConfirmed, lastScanned, batchSize uint64) (uint64, uint64) { - startBlock := lastScanned + 1 - toBlock := lastScanned + batchSize - if toBlock > latestConfirmed { - toBlock = latestConfirmed - } - return startBlock, toBlock -} - -func (ob *ChainClient) postBlockHeader(tip uint64) error { - bn := tip - - res, err := ob.zetaBridge.GetBlockHeaderChainState(ob.chain.ChainId) - if err == nil && res.ChainState != nil && res.ChainState.EarliestHeight > 0 { - // #nosec G701 always positive - bn = uint64(res.ChainState.LatestHeight) + 1 // the next header to post - } - - if bn > tip { - return fmt.Errorf("postBlockHeader: must post block confirmed block header: %d > %d", bn, tip) - } - - header, err := ob.GetBlockHeaderCached(bn) - if err != nil { - ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error getting block: %d", bn) - return err - } - headerRLP, err := rlp.EncodeToBytes(header) - if err != nil { - ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error encoding block header: %d", bn) - return err - } - - _, err = ob.zetaBridge.PostVoteBlockHeader( - ob.chain.ChainId, - header.Hash().Bytes(), - header.Number.Int64(), - proofs.NewEthereumHeader(headerRLP), - ) - if err != nil { - ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error posting block header: %d", bn) - return err - } - return nil -} - -func (ob *ChainClient) observeInTX(sampledLogger zerolog.Logger) error { - // get and update latest block height - blockNumber, err := ob.evmClient.BlockNumber(context.Background()) - if err != nil { - return err - } - if blockNumber < ob.GetLastBlockHeight() { - return fmt.Errorf("observeInTX: block number should not decrease: current %d last %d", blockNumber, ob.GetLastBlockHeight()) - } - ob.SetLastBlockHeight(blockNumber) - - // increment prom counter - metrics.GetBlockByNumberPerChain.WithLabelValues(ob.chain.ChainName.String()).Inc() - - // skip if current height is too low - if blockNumber < ob.GetChainParams().ConfirmationCount { - return fmt.Errorf("observeInTX: skipping observer, current block number %d is too low", blockNumber) - } - confirmedBlockNum := blockNumber - ob.GetChainParams().ConfirmationCount - - // skip if no new block is confirmed - lastScanned := ob.GetLastBlockHeightScanned() - if lastScanned >= confirmedBlockNum { - sampledLogger.Debug().Msgf("observeInTX: skipping observer, no new block is produced for chain %d", ob.chain.ChainId) - return nil - } - - // get last scanned block height (we simply use same height for all 3 events ZetaSent, Deposited, TssRecvd) - // Note: using different heights for each event incurs more complexity (metrics, db, etc) and not worth it - startBlock, toBlock := ob.calcBlockRangeToScan(confirmedBlockNum, lastScanned, config.MaxBlocksPerPeriod) - - // task 1: query evm chain for zeta sent logs (read at most 100 blocks in one go) - lastScannedZetaSent := ob.ObserveZetaSent(startBlock, toBlock) - - // task 2: query evm chain for deposited logs (read at most 100 blocks in one go) - lastScannedDeposited := ob.ObserveERC20Deposited(startBlock, toBlock) - - // task 3: query the incoming tx to TSS address (read at most 100 blocks in one go) - lastScannedTssRecvd := ob.ObserverTSSReceive(startBlock, toBlock) - - // note: using lowest height for all 3 events is not perfect, but it's simple and good enough - lastScannedLowest := lastScannedZetaSent - if lastScannedDeposited < lastScannedLowest { - lastScannedLowest = lastScannedDeposited - } - if lastScannedTssRecvd < lastScannedLowest { - lastScannedLowest = lastScannedTssRecvd - } - - // update last scanned block height for all 3 events (ZetaSent, Deposited, TssRecvd), ignore db error - if lastScannedLowest > lastScanned { - sampledLogger.Info().Msgf("observeInTX: lasstScanned heights for chain %d ZetaSent %d ERC20Deposited %d TssRecvd %d", - ob.chain.ChainId, lastScannedZetaSent, lastScannedDeposited, lastScannedTssRecvd) - ob.SetLastBlockHeightScanned(lastScannedLowest) - if err := ob.db.Save(clienttypes.ToLastBlockSQLType(lastScannedLowest)).Error; err != nil { - ob.logger.InTx.Error().Err(err).Msgf("observeInTX: error writing lastScannedLowest %d to db", lastScannedLowest) - } - } - return nil -} - // ObserveZetaSent queries the ZetaSent event from the connector contract and posts to zetabridge // returns the last block successfully scanned func (ob *ChainClient) ObserveZetaSent(startBlock, toBlock uint64) uint64 { @@ -760,6 +902,7 @@ func (ob *ChainClient) ObserveERC20Deposited(startBlock, toBlock uint64) uint64 ob.logger.InTx.Warn().Err(err).Msgf("ObserveERC20Deposited: GetERC20CustodyContract error:") return startBlock - 1 // lastScanned } + iter, err := erc20custodyContract.FilterDeposited(&bind.FilterOpts{ Start: startBlock, End: &toBlock, @@ -960,24 +1103,6 @@ func (ob *ChainClient) BuildLastBlock() error { return nil } -func (ob *ChainClient) BuildReceiptsMap() error { - logger := ob.logger - var receipts []clienttypes.ReceiptSQLType - if err := ob.db.Find(&receipts).Error; err != nil { - logger.Chain.Error().Err(err).Msg("error iterating over db") - return err - } - for _, receipt := range receipts { - r, err := clienttypes.FromReceiptDBType(receipt.Receipt) - if err != nil { - return err - } - ob.outTXConfirmedReceipts[receipt.Identifier] = r - } - - return nil -} - // LoadDB open sql database and load data into EVMChainClient func (ob *ChainClient) LoadDB(dbPath string, chain chains.Chain) error { if dbPath != "" { @@ -1077,3 +1202,182 @@ func (ob *ChainClient) GetBlockByNumberCached(blockNumber uint64) (*ethrpc.Block func (ob *ChainClient) RemoveCachedBlock(blockNumber uint64) { ob.blockCache.Remove(blockNumber) } + +// checkConfirmedTx checks if a txHash is confirmed +// returns (receipt, transaction, true) if confirmed or (nil, nil, false) otherwise +func (ob *ChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction, bool) { + ctxt, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + // query transaction + transaction, isPending, err := ob.evmClient.TransactionByHash(ctxt, ethcommon.HexToHash(txHash)) + if err != nil { + log.Error().Err(err).Msgf("confirmTxByHash: error getting transaction for outtx %s chain %d", txHash, ob.chain.ChainId) + return nil, nil, false + } + if transaction == nil { // should not happen + log.Error().Msgf("confirmTxByHash: transaction is nil for txHash %s nonce %d", txHash, nonce) + return nil, nil, false + } + + // check tx sender and nonce + signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) + from, err := signer.Sender(transaction) + if err != nil { + log.Error().Err(err).Msgf("confirmTxByHash: local recovery of sender address failed for outtx %s chain %d", transaction.Hash().Hex(), ob.chain.ChainId) + return nil, nil, false + } + if from != ob.Tss.EVMAddress() { // must be TSS address + log.Error().Msgf("confirmTxByHash: sender %s for outtx %s chain %d is not TSS address %s", + from.Hex(), transaction.Hash().Hex(), ob.chain.ChainId, ob.Tss.EVMAddress().Hex()) + return nil, nil, false + } + if transaction.Nonce() != nonce { // must match cctx nonce + log.Error().Msgf("confirmTxByHash: outtx %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) + return nil, nil, false + } + + // save pending transaction + if isPending { + ob.SetPendingTx(nonce, transaction) + return nil, nil, false + } + + // query receipt + receipt, err := ob.evmClient.TransactionReceipt(ctxt, ethcommon.HexToHash(txHash)) + if err != nil { + if err != ethereum.NotFound { + log.Warn().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) + } + return nil, nil, false + } + if receipt == nil { // should not happen + log.Error().Msgf("confirmTxByHash: receipt is nil for txHash %s nonce %d", txHash, nonce) + return nil, nil, false + } + + // check confirmations + if !ob.HasEnoughConfirmations(receipt, ob.GetLastBlockHeight()) { + log.Debug().Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", + txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) + return nil, nil, false + } + + // cross-check tx inclusion against the block + // Note: a guard for false BlockNumber in receipt. The blob-carrying tx won't come here + err = ob.CheckTxInclusion(transaction, receipt) + if err != nil { + log.Error().Err(err).Msgf("confirmTxByHash: checkTxInclusion error for txHash %s nonce %d", txHash, nonce) + return nil, nil, false + } + + return receipt, transaction, true +} + +// calcBlockRangeToScan calculates the next range of blocks to scan +func (ob *ChainClient) calcBlockRangeToScan(latestConfirmed, lastScanned, batchSize uint64) (uint64, uint64) { + startBlock := lastScanned + 1 + toBlock := lastScanned + batchSize + if toBlock > latestConfirmed { + toBlock = latestConfirmed + } + return startBlock, toBlock +} + +func (ob *ChainClient) postBlockHeader(tip uint64) error { + bn := tip + + res, err := ob.zetaBridge.GetBlockHeaderChainState(ob.chain.ChainId) + if err == nil && res.ChainState != nil && res.ChainState.EarliestHeight > 0 { + // #nosec G701 always positive + bn = uint64(res.ChainState.LatestHeight) + 1 // the next header to post + } + + if bn > tip { + return fmt.Errorf("postBlockHeader: must post block confirmed block header: %d > %d", bn, tip) + } + + header, err := ob.GetBlockHeaderCached(bn) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error getting block: %d", bn) + return err + } + headerRLP, err := rlp.EncodeToBytes(header) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error encoding block header: %d", bn) + return err + } + + _, err = ob.zetaBridge.PostVoteBlockHeader( + ob.chain.ChainId, + header.Hash().Bytes(), + header.Number.Int64(), + proofs.NewEthereumHeader(headerRLP), + ) + if err != nil { + ob.logger.InTx.Error().Err(err).Msgf("postBlockHeader: error posting block header: %d", bn) + return err + } + return nil +} + +func (ob *ChainClient) observeInTX(sampledLogger zerolog.Logger) error { + // get and update latest block height + blockNumber, err := ob.evmClient.BlockNumber(context.Background()) + if err != nil { + return err + } + if blockNumber < ob.GetLastBlockHeight() { + return fmt.Errorf("observeInTX: block number should not decrease: current %d last %d", blockNumber, ob.GetLastBlockHeight()) + } + ob.SetLastBlockHeight(blockNumber) + + // increment prom counter + metrics.GetBlockByNumberPerChain.WithLabelValues(ob.chain.ChainName.String()).Inc() + + // skip if current height is too low + if blockNumber < ob.GetChainParams().ConfirmationCount { + return fmt.Errorf("observeInTX: skipping observer, current block number %d is too low", blockNumber) + } + confirmedBlockNum := blockNumber - ob.GetChainParams().ConfirmationCount + + // skip if no new block is confirmed + lastScanned := ob.GetLastBlockHeightScanned() + if lastScanned >= confirmedBlockNum { + sampledLogger.Debug().Msgf("observeInTX: skipping observer, no new block is produced for chain %d", ob.chain.ChainId) + return nil + } + + // get last scanned block height (we simply use same height for all 3 events ZetaSent, Deposited, TssRecvd) + // Note: using different heights for each event incurs more complexity (metrics, db, etc) and not worth it + startBlock, toBlock := ob.calcBlockRangeToScan(confirmedBlockNum, lastScanned, config.MaxBlocksPerPeriod) + + // task 1: query evm chain for zeta sent logs (read at most 100 blocks in one go) + lastScannedZetaSent := ob.ObserveZetaSent(startBlock, toBlock) + + // task 2: query evm chain for deposited logs (read at most 100 blocks in one go) + lastScannedDeposited := ob.ObserveERC20Deposited(startBlock, toBlock) + + // task 3: query the incoming tx to TSS address (read at most 100 blocks in one go) + lastScannedTssRecvd := ob.ObserverTSSReceive(startBlock, toBlock) + + // note: using lowest height for all 3 events is not perfect, but it's simple and good enough + lastScannedLowest := lastScannedZetaSent + if lastScannedDeposited < lastScannedLowest { + lastScannedLowest = lastScannedDeposited + } + if lastScannedTssRecvd < lastScannedLowest { + lastScannedLowest = lastScannedTssRecvd + } + + // update last scanned block height for all 3 events (ZetaSent, Deposited, TssRecvd), ignore db error + if lastScannedLowest > lastScanned { + sampledLogger.Info().Msgf("observeInTX: lasstScanned heights for chain %d ZetaSent %d ERC20Deposited %d TssRecvd %d", + ob.chain.ChainId, lastScannedZetaSent, lastScannedDeposited, lastScannedTssRecvd) + ob.SetLastBlockHeightScanned(lastScannedLowest) + if err := ob.db.Save(clienttypes.ToLastBlockSQLType(lastScannedLowest)).Error; err != nil { + ob.logger.InTx.Error().Err(err).Msgf("observeInTX: error writing lastScannedLowest %d to db", lastScannedLowest) + } + } + return nil +} diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index d9b6eb25dd..9c2b0e1716 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -36,6 +36,8 @@ import ( zbridge "github.com/zeta-chain/zetacore/zetaclient/zetabridge" ) +var _ interfaces.ChainSigner = &Signer{} + // Signer deals with the signing EVM transactions and implements the ChainSigner interface type Signer struct { client interfaces.EVMRPCClient @@ -55,8 +57,6 @@ type Signer struct { outTxHashBeingReported map[string]bool } -var _ interfaces.ChainSigner = &Signer{} - func NewEVMSigner( chain chains.Chain, endpoint string, @@ -152,17 +152,20 @@ func (signer *Signer) Sign( if err != nil { return nil, nil, nil, err } + log.Debug().Msgf("Sign: Signature: %s", hex.EncodeToString(sig[:])) pubk, err := crypto.SigToPub(hashBytes, sig[:]) if err != nil { signer.logger.Std.Error().Err(err).Msgf("SigToPub error") } + addr := crypto.PubkeyToAddress(*pubk) signer.logger.Std.Info().Msgf("Sign: Ecrecovery of signature: %s", addr.Hex()) signedTX, err := tx.WithSignature(signer.ethSigner, sig[:]) if err != nil { return nil, nil, nil, err } + return signedTX, sig[:], hashBytes[:], nil } @@ -262,10 +265,12 @@ func (signer *Signer) SignCancelTx(nonce uint64, gasPrice *big.Int, height uint6 if err != nil { return nil, err } + pubk, err := crypto.SigToPub(hashBytes, sig[:]) if err != nil { signer.logger.Std.Error().Err(err).Msgf("SigToPub error") } + addr := crypto.PubkeyToAddress(*pubk) signer.logger.Std.Info().Msgf("Sign: Ecrecovery of signature: %s", addr.Hex()) signedTX, err := tx.WithSignature(signer.ethSigner, sig[:]) @@ -287,10 +292,12 @@ func (signer *Signer) SignWithdrawTx(txData *OutBoundTransactionData) (*ethtypes if err != nil { return nil, err } + pubk, err := crypto.SigToPub(hashBytes, sig[:]) if err != nil { signer.logger.Std.Error().Err(err).Msgf("SigToPub error") } + addr := crypto.PubkeyToAddress(*pubk) signer.logger.Std.Info().Msgf("Sign: Ecrecovery of signature: %s", addr.Hex()) signedTX, err := tx.WithSignature(signer.ethSigner, sig[:]) @@ -495,6 +502,116 @@ func (signer *Signer) BroadcastOutTx( } } +// SignERC20WithdrawTx +// function withdraw( +// address recipient, +// address asset, +// uint256 amount, +// ) external onlyTssAddress +func (signer *Signer) SignERC20WithdrawTx(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { + var data []byte + var err error + data, err = signer.erc20CustodyABI.Pack("withdraw", txData.to, txData.asset, txData.amount) + if err != nil { + return nil, fmt.Errorf("pack error: %w", err) + } + + tx, _, _, err := signer.Sign(data, signer.er20CustodyAddress, txData.gasLimit, txData.gasPrice, txData.nonce, txData.height) + if err != nil { + return nil, fmt.Errorf("sign error: %w", err) + } + + return tx, nil +} + +// SignWhitelistTx +// function whitelist( +// address asset, +// ) external onlyTssAddress +// function unwhitelist( +// address asset, +// ) external onlyTssAddress +func (signer *Signer) SignWhitelistTx( + action string, + _ ethcommon.Address, + asset ethcommon.Address, + gasLimit uint64, + nonce uint64, + gasPrice *big.Int, + height uint64, +) (*ethtypes.Transaction, error) { + var data []byte + + var err error + + data, err = signer.erc20CustodyABI.Pack(action, asset) + if err != nil { + return nil, fmt.Errorf("pack error: %w", err) + } + + tx, _, _, err := signer.Sign(data, signer.er20CustodyAddress, gasLimit, gasPrice, nonce, height) + if err != nil { + return nil, fmt.Errorf("Sign error: %w", err) + } + + return tx, nil +} + +// Exported for unit tests + +// GetReportedTxList returns a list of outTxHash being reported +// TODO: investigate pointer usage +// https://github.com/zeta-chain/node/issues/2084 +func (signer *Signer) GetReportedTxList() *map[string]bool { + return &signer.outTxHashBeingReported +} + +func (signer *Signer) EvmClient() interfaces.EVMRPCClient { + return signer.client +} + +func (signer *Signer) EvmSigner() ethtypes.Signer { + return signer.ethSigner +} + +func IsSenderZetaChain(cctx *types.CrossChainTx, zetaBridge interfaces.ZetaCoreBridger, flags *observertypes.CrosschainFlags) bool { + return cctx.InboundTxParams.SenderChainId == zetaBridge.ZetaChain().ChainId && cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound && flags.IsOutboundEnabled +} + +func SignerErrorMsg(cctx *types.CrossChainTx) string { + return fmt.Sprintf("signer SignOutbound error: nonce %d chain %d", cctx.GetCurrentOutTxParam().OutboundTxTssNonce, cctx.GetCurrentOutTxParam().ReceiverChainId) +} + +func (signer *Signer) SignWhitelistERC20Cmd(txData *OutBoundTransactionData, params string) (*ethtypes.Transaction, error) { + outboundParams := txData.outboundParams + erc20 := ethcommon.HexToAddress(params) + if erc20 == (ethcommon.Address{}) { + return nil, fmt.Errorf("SignCommandTx: invalid erc20 address %s", params) + } + custodyAbi, err := erc20custody.ERC20CustodyMetaData.GetAbi() + if err != nil { + return nil, err + } + data, err := custodyAbi.Pack("whitelist", erc20) + if err != nil { + return nil, err + } + tx, _, _, err := signer.Sign(data, txData.to, txData.gasLimit, txData.gasPrice, outboundParams.OutboundTxTssNonce, txData.height) + if err != nil { + return nil, fmt.Errorf("sign error: %w", err) + } + return tx, nil +} + +func (signer *Signer) SignMigrateTssFundsCmd(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { + outboundParams := txData.outboundParams + tx, _, _, err := signer.Sign(nil, txData.to, txData.gasLimit, txData.gasPrice, outboundParams.OutboundTxTssNonce, txData.height) + if err != nil { + return nil, err + } + return tx, nil +} + // reportToOutTxTracker reports outTxHash to tracker only when tx receipt is available func (signer *Signer) reportToOutTxTracker(zetaBridge interfaces.ZetaCoreBridger, chainID int64, nonce uint64, outTxHash string, logger zerolog.Logger) { // skip if already being reported @@ -590,75 +707,6 @@ func (signer *Signer) reportToOutTxTracker(zetaBridge interfaces.ZetaCoreBridger }() } -// SignERC20WithdrawTx -// function withdraw( -// address recipient, -// address asset, -// uint256 amount, -// ) external onlyTssAddress -func (signer *Signer) SignERC20WithdrawTx(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { - var data []byte - var err error - data, err = signer.erc20CustodyABI.Pack("withdraw", txData.to, txData.asset, txData.amount) - if err != nil { - return nil, fmt.Errorf("pack error: %w", err) - } - - tx, _, _, err := signer.Sign(data, signer.er20CustodyAddress, txData.gasLimit, txData.gasPrice, txData.nonce, txData.height) - if err != nil { - return nil, fmt.Errorf("sign error: %w", err) - } - - return tx, nil -} - -// SignWhitelistTx -// function whitelist( -// address asset, -// ) external onlyTssAddress -// function unwhitelist( -// address asset, -// ) external onlyTssAddress -func (signer *Signer) SignWhitelistTx( - action string, - _ ethcommon.Address, - asset ethcommon.Address, - gasLimit uint64, - nonce uint64, - gasPrice *big.Int, - height uint64, -) (*ethtypes.Transaction, error) { - var data []byte - - var err error - - data, err = signer.erc20CustodyABI.Pack(action, asset) - if err != nil { - return nil, fmt.Errorf("pack error: %w", err) - } - - tx, _, _, err := signer.Sign(data, signer.er20CustodyAddress, gasLimit, gasPrice, nonce, height) - if err != nil { - return nil, fmt.Errorf("Sign error: %w", err) - } - - return tx, nil -} - -// Exported for unit tests - -func (signer *Signer) GetReportedTxList() *map[string]bool { - return &signer.outTxHashBeingReported -} -func (signer *Signer) EvmClient() interfaces.EVMRPCClient { - return signer.client -} -func (signer *Signer) EvmSigner() ethtypes.Signer { - return signer.ethSigner -} - -// ________________________ - // getEVMRPC is a helper function to set up the client and signer, also initializes a mock client for unit tests func getEVMRPC(endpoint string) (interfaces.EVMRPCClient, ethtypes.Signer, error) { if endpoint == stub.EVMRPCEnabled { @@ -690,41 +738,3 @@ func roundUpToNearestGwei(gasPrice *big.Int) *big.Int { } return new(big.Int).Add(gasPrice, new(big.Int).Sub(oneGwei, mod)) } - -func IsSenderZetaChain(cctx *types.CrossChainTx, zetaBridge interfaces.ZetaCoreBridger, flags *observertypes.CrosschainFlags) bool { - return cctx.InboundTxParams.SenderChainId == zetaBridge.ZetaChain().ChainId && cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound && flags.IsOutboundEnabled -} - -func SignerErrorMsg(cctx *types.CrossChainTx) string { - return fmt.Sprintf("signer SignOutbound error: nonce %d chain %d", cctx.GetCurrentOutTxParam().OutboundTxTssNonce, cctx.GetCurrentOutTxParam().ReceiverChainId) -} - -func (signer *Signer) SignWhitelistERC20Cmd(txData *OutBoundTransactionData, params string) (*ethtypes.Transaction, error) { - outboundParams := txData.outboundParams - erc20 := ethcommon.HexToAddress(params) - if erc20 == (ethcommon.Address{}) { - return nil, fmt.Errorf("SignCommandTx: invalid erc20 address %s", params) - } - custodyAbi, err := erc20custody.ERC20CustodyMetaData.GetAbi() - if err != nil { - return nil, err - } - data, err := custodyAbi.Pack("whitelist", erc20) - if err != nil { - return nil, err - } - tx, _, _, err := signer.Sign(data, txData.to, txData.gasLimit, txData.gasPrice, outboundParams.OutboundTxTssNonce, txData.height) - if err != nil { - return nil, fmt.Errorf("sign error: %w", err) - } - return tx, nil -} - -func (signer *Signer) SignMigrateTssFundsCmd(txData *OutBoundTransactionData) (*ethtypes.Transaction, error) { - outboundParams := txData.outboundParams - tx, _, _, err := signer.Sign(nil, txData.to, txData.gasLimit, txData.gasPrice, outboundParams.OutboundTxTssNonce, txData.height) - if err != nil { - return nil, err - } - return tx, nil -} diff --git a/zetaclient/evm/inbounds.go b/zetaclient/evm/inbounds.go index 0ee0e0457f..deb94d38a7 100644 --- a/zetaclient/evm/inbounds.go +++ b/zetaclient/evm/inbounds.go @@ -37,8 +37,8 @@ func (ob *ChainClient) WatchIntxTracker() { ob.logger.InTx.Err(err).Msg("error creating ticker") return } - defer ticker.Stop() + ob.logger.InTx.Info().Msgf("Intx tracker watcher started for chain %d", ob.chain.ChainId) for { select { @@ -70,6 +70,7 @@ func (ob *ChainClient) ObserveIntxTrackers() error { if err != nil { return errors.Wrapf(err, "error getting transaction for intx %s chain %d", tracker.TxHash, ob.chain.ChainId) } + receipt, err := ob.evmClient.TransactionReceipt(context.Background(), ethcommon.HexToHash(tracker.TxHash)) if err != nil { return errors.Wrapf(err, "error getting receipt for intx %s chain %d", tracker.TxHash, ob.chain.ChainId) @@ -100,6 +101,7 @@ func (ob *ChainClient) CheckAndVoteInboundTokenZeta(tx *ethrpc.Transaction, rece if confirmed := ob.HasEnoughConfirmations(receipt, ob.GetLastBlockHeight()); !confirmed { return "", fmt.Errorf("intx %s has not been confirmed yet: receipt block %d", tx.Hash, receipt.BlockNumber.Uint64()) } + // get zeta connector contract addrConnector, connector, err := ob.GetConnectorContract() if err != nil { @@ -130,6 +132,7 @@ func (ob *ChainClient) CheckAndVoteInboundTokenZeta(tx *ethrpc.Transaction, rece if vote { return ob.PostVoteInbound(msg, coin.CoinType_Zeta, zetabridge.PostVoteInboundMessagePassingExecutionGasLimit) } + return msg.Digest(), nil } @@ -171,6 +174,7 @@ func (ob *ChainClient) CheckAndVoteInboundTokenERC20(tx *ethrpc.Transaction, rec if vote { return ob.PostVoteInbound(msg, coin.CoinType_ERC20, zetabridge.PostVoteInboundExecutionGasLimit) } + return msg.Digest(), nil } @@ -180,6 +184,7 @@ func (ob *ChainClient) CheckAndVoteInboundTokenGas(tx *ethrpc.Transaction, recei if confirmed := ob.HasEnoughConfirmations(receipt, ob.GetLastBlockHeight()); !confirmed { return "", fmt.Errorf("intx %s has not been confirmed yet: receipt block %d", tx.Hash, receipt.BlockNumber.Uint64()) } + // checks receiver and tx status if ethcommon.HexToAddress(tx.To) != ob.Tss.EVMAddress() { return "", fmt.Errorf("tx.To %s is not TSS address", tx.To) @@ -199,6 +204,7 @@ func (ob *ChainClient) CheckAndVoteInboundTokenGas(tx *ethrpc.Transaction, recei if vote { return ob.PostVoteInbound(msg, coin.CoinType_Gas, zetabridge.PostVoteInboundExecutionGasLimit) } + return msg.Digest(), nil } @@ -215,6 +221,7 @@ func (ob *ChainClient) PostVoteInbound(msg *types.MsgVoteOnObservedInboundTx, co } else { ob.logger.InTx.Info().Msgf("intx detected: chain %d token %s intx %s already voted on ballot %s", chainID, coinType, txHash, ballot) } + return ballot, err } @@ -366,6 +373,7 @@ func (ob *ChainClient) ObserveTSSReceiveInBlock(blockNumber uint64) error { if err != nil { return errors.Wrapf(err, "error getting block %d for chain %d", blockNumber, ob.chain.ChainId) } + for i := range block.Transactions { tx := block.Transactions[i] if ethcommon.HexToAddress(tx.To) == ob.Tss.EVMAddress() { @@ -373,6 +381,7 @@ func (ob *ChainClient) ObserveTSSReceiveInBlock(blockNumber uint64) error { if err != nil { return errors.Wrapf(err, "error getting receipt for intx %s chain %d", tx.Hash, ob.chain.ChainId) } + _, err = ob.CheckAndVoteInboundTokenGas(&tx, receipt, true) if err != nil { return errors.Wrapf(err, "error checking and voting inbound gas asset for intx %s chain %d", tx.Hash, ob.chain.ChainId) diff --git a/zetaclient/interfaces/interfaces.go b/zetaclient/interfaces/interfaces.go index 0fbaba26b3..91695c063b 100644 --- a/zetaclient/interfaces/interfaces.go +++ b/zetaclient/interfaces/interfaces.go @@ -94,7 +94,6 @@ type ZetaCoreBridger interface { txIndex int64, ) (string, error) GetKeys() *keys.Keys - GetBlockHeight() (int64, error) GetZetaBlockHeight() (int64, error) GetLastBlockHeightByChain(chain chains.Chain) (*crosschaintypes.LastBlockHeight, error) ListPendingCctx(chainID int64) ([]*crosschaintypes.CrossChainTx, uint64, error) diff --git a/zetaclient/interfaces/signer.go b/zetaclient/interfaces/signer.go index 461902359c..11142f8087 100644 --- a/zetaclient/interfaces/signer.go +++ b/zetaclient/interfaces/signer.go @@ -16,8 +16,13 @@ import ( type TSSSigner interface { Pubkey() []byte - // Sign: Specify optionalPubkey to use a different pubkey than the current pubkey set during keygen + + // Sign signs the data + // Note: it specifies optionalPubkey to use a different pubkey than the current pubkey set during keygen + // TODO: check if optionalPubkey is needed + // https://github.com/zeta-chain/node/issues/2085 Sign(data []byte, height uint64, nonce uint64, chain *chains.Chain, optionalPubkey string) ([65]byte, error) + EVMAddress() ethcommon.Address BTCAddress() string BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyHash @@ -90,6 +95,7 @@ func (s TestSigner) BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyH fmt.Printf("error parsing pubkey: %v", err) return nil } + // witness program: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Witness_program // The HASH160 of the public key must match the 20-byte witness program. addrWPKH, err := btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(pk.SerializeCompressed()), &chaincfg.TestNet3Params) diff --git a/zetaclient/keys/keys.go b/zetaclient/keys/keys.go index 1ca248aff9..4c3a4c48c1 100644 --- a/zetaclient/keys/keys.go +++ b/zetaclient/keys/keys.go @@ -14,7 +14,6 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/rs/zerolog/log" - "github.com/zeta-chain/zetacore/cmd" "github.com/zeta-chain/zetacore/pkg/cosmos" zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" "github.com/zeta-chain/zetacore/zetaclient/config" @@ -86,25 +85,6 @@ func GetKeyringKeybase(cfg config.Config, hotkeyPassword string) (ckeys.Keyring, return kb, pubkeyBech32, nil } -// getKeybase will create an instance of Keybase -func getKeybase(zetaCoreHome string, reader io.Reader, keyringBackend config.KeyringBackend) (ckeys.Keyring, error) { - cliDir := zetaCoreHome - if len(zetaCoreHome) == 0 { - return nil, fmt.Errorf("zetaCoreHome is empty") - } - registry := codectypes.NewInterfaceRegistry() - cryptocodec.RegisterInterfaces(registry) - cdc := codec.NewProtoCodec(registry) - - // create a new keybase based on the selected backend - backend := ckeys.BackendTest - if keyringBackend == config.KeyringBackendFile { - backend = ckeys.BackendFile - } - - return ckeys.New(sdk.KeyringServiceName(), backend, cliDir, reader, cdc) -} - // GetSignerInfo return signer info func (k *Keys) GetSignerInfo() *ckeys.Record { signer := GetGranteeKeyName(k.signerName) @@ -183,14 +163,21 @@ func (k *Keys) GetHotkeyPassword() string { return "" } -func SetupConfigForTest() { - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(cmd.Bech32PrefixAccAddr, cmd.Bech32PrefixAccPub) - config.SetBech32PrefixForValidator(cmd.Bech32PrefixValAddr, cmd.Bech32PrefixValPub) - config.SetBech32PrefixForConsensusNode(cmd.Bech32PrefixConsAddr, cmd.Bech32PrefixConsPub) - //config.SetCoinType(cmd.MetaChainCoinType) - config.SetFullFundraiserPath(cmd.ZetaChainHDPath) - sdk.SetCoinDenomRegex(func() string { - return cmd.DenomRegex - }) +// getKeybase will create an instance of Keybase +func getKeybase(zetaCoreHome string, reader io.Reader, keyringBackend config.KeyringBackend) (ckeys.Keyring, error) { + cliDir := zetaCoreHome + if len(zetaCoreHome) == 0 { + return nil, fmt.Errorf("zetaCoreHome is empty") + } + registry := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(registry) + cdc := codec.NewProtoCodec(registry) + + // create a new keybase based on the selected backend + backend := ckeys.BackendTest + if keyringBackend == config.KeyringBackendFile { + backend = ckeys.BackendFile + } + + return ckeys.New(sdk.KeyringServiceName(), backend, cliDir, reader, cdc) } diff --git a/zetaclient/keys/keys_test.go b/zetaclient/keys/keys_test.go index 347195869f..1d81397531 100644 --- a/zetaclient/keys/keys_test.go +++ b/zetaclient/keys/keys_test.go @@ -28,10 +28,6 @@ func Test(t *testing.T) { TestingT(t) } var _ = Suite(&KeysSuite{}) -func (*KeysSuite) SetUpSuite(c *C) { - SetupConfigForTest() -} - var ( password = "password" ) @@ -41,6 +37,21 @@ const ( signerPasswordForTest = `password` ) +func setupConfig() { + testConfig := sdk.GetConfig() + testConfig.SetBech32PrefixForAccount(cmd.Bech32PrefixAccAddr, cmd.Bech32PrefixAccPub) + testConfig.SetBech32PrefixForValidator(cmd.Bech32PrefixValAddr, cmd.Bech32PrefixValPub) + testConfig.SetBech32PrefixForConsensusNode(cmd.Bech32PrefixConsAddr, cmd.Bech32PrefixConsPub) + testConfig.SetFullFundraiserPath(cmd.ZetaChainHDPath) + sdk.SetCoinDenomRegex(func() string { + return cmd.DenomRegex + }) +} + +func (*KeysSuite) SetUpSuite(_ *C) { + setupConfig() +} + func (*KeysSuite) setupKeysForTest(c *C) string { ns := strconv.Itoa(time.Now().Nanosecond()) metaCliDir := filepath.Join(os.TempDir(), ns, ".metacli") diff --git a/zetaclient/metrics/burn_rate.go b/zetaclient/metrics/burn_rate.go index e4c6053ccd..844a862fb7 100644 --- a/zetaclient/metrics/burn_rate.go +++ b/zetaclient/metrics/burn_rate.go @@ -6,6 +6,7 @@ import ( sdkmath "cosmossdk.io/math" ) +// BurnRate calculates the average burn rate for a range of blocks. type BurnRate struct { blockLow int64 blockHigh int64 @@ -14,6 +15,7 @@ type BurnRate struct { queue []int64 } +// NewBurnRate creates a new BurnRate instance with a window size. func NewBurnRate(windowSize int64) *BurnRate { return &BurnRate{ blockLow: 1, @@ -24,9 +26,8 @@ func NewBurnRate(windowSize int64) *BurnRate { } } -// AddFee - adds fee amount spent on a tx for a particular block. It is added to a queue which is used to calculate -// -// the average burn rate for a range of blocks determined by the window size. +// AddFee adds fee amount spent on a tx for a particular block. It is added to a queue which is used to calculate +// the average burn rate for a range of blocks determined by the window size. func (br *BurnRate) AddFee(amount int64, block int64) error { // Check if block is in range of the window if block < br.blockLow { @@ -58,9 +59,8 @@ func (br *BurnRate) AddFee(amount int64, block int64) error { return nil } -// enqueueEntry - add fee entry into queue if is in range of the window. A padding is added if the block height is -// -// more than one block greater than the highest range. +// enqueueEntry adds fee entry into queue if is in range of the window. A padding is added if the block height is +// more than one block greater than the highest range. func (br *BurnRate) enqueueEntry(block int64, amount int64) error { diff := block - br.blockHigh if diff < 1 { @@ -82,7 +82,8 @@ func (br *BurnRate) enqueueEntry(block int64, amount int64) error { return nil } -// dequeueOldEntries - when the window slides forward, older entries in the queue need to be cleared. +// dequeueOldEntries dequeues old entries +// when the window slides forward, older entries in the queue need to be cleared. func (br *BurnRate) dequeueOldEntries() error { diff := br.blockHigh - br.blockLow if diff < br.windowSize { @@ -102,7 +103,7 @@ func (br *BurnRate) dequeueOldEntries() error { return nil } -// GetBurnRate - calculate current burn rate and return the value. +// GetBurnRate calculates current burn rate and return the value. func (br *BurnRate) GetBurnRate() sdkmath.Int { if br.blockHigh < br.windowSize { return sdkmath.NewInt(br.total).QuoRaw(br.blockHigh) diff --git a/zetaclient/metrics/telemetry.go b/zetaclient/metrics/telemetry.go index 209bf61fed..bdedbd9c50 100644 --- a/zetaclient/metrics/telemetry.go +++ b/zetaclient/metrics/telemetry.go @@ -39,32 +39,35 @@ func NewTelemetryServer() *TelemetryServer { return hs } -// setter/getter for p2pid +// SetP2PID sets p2pid func (t *TelemetryServer) SetP2PID(p2pid string) { t.mu.Lock() t.p2pid = p2pid t.mu.Unlock() } +// GetP2PID gets p2pid func (t *TelemetryServer) GetP2PID() string { t.mu.Lock() defer t.mu.Unlock() return t.p2pid } -// setter/getter for p2pid +// SetIPAddress sets p2pid func (t *TelemetryServer) SetIPAddress(ip string) { t.mu.Lock() t.ipAddress = ip t.mu.Unlock() } +// GetIPAddress gets p2pid func (t *TelemetryServer) GetIPAddress() string { t.mu.Lock() defer t.mu.Unlock() return t.ipAddress } +// AddFeeEntry adds fee entry func (t *TelemetryServer) AddFeeEntry(block int64, amount int64) { t.mu.Lock() err := t.HotKeyBurnRate.AddFee(amount, block) @@ -74,7 +77,7 @@ func (t *TelemetryServer) AddFeeEntry(block int64, amount int64) { t.mu.Unlock() } -// NewHandler registers the API routes and returns a new HTTP handler +// Handlers registers the API routes and returns a new HTTP handler func (t *TelemetryServer) Handlers() http.Handler { router := mux.NewRouter() router.Handle("/ping", http.HandlerFunc(t.pingHandler)).Methods(http.MethodGet) @@ -82,13 +85,8 @@ func (t *TelemetryServer) Handlers() http.Handler { router.Handle("/ip", http.HandlerFunc(t.ipHandler)).Methods(http.MethodGet) router.Handle("/hotkeyburnrate", http.HandlerFunc(t.hotKeyFeeBurnRate)).Methods(http.MethodGet) - // router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) - // router.Handle("/debug/pprof/heap", pprof.Handler("heap")) - // router.HandleFunc("/debug/pprof/", pprof.Index) - // router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - - //router.Handle("/pending", http.HandlerFunc(t.pendingHandler)).Methods(http.MethodGet) router.Use(logMiddleware()) + return router } @@ -97,7 +95,7 @@ func (t *TelemetryServer) Start() error { return errors.New("invalid http server instance") } if err := t.s.ListenAndServe(); err != nil { - if err != http.ErrServerClosed { + if !errors.Is(err, http.ErrServerClosed) { return fmt.Errorf("fail to start http server: %w", err) } } @@ -105,20 +103,6 @@ func (t *TelemetryServer) Start() error { return nil } -func logMiddleware() mux.MiddlewareFunc { - return func(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Debug(). - Str("route", r.URL.Path). - Str("port", r.URL.Port()). - Str("method", r.Method). - Msg("HTTP request received") - - handler.ServeHTTP(w, r) - }) - } -} - func (t *TelemetryServer) Stop() error { c, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -153,3 +137,17 @@ func (t *TelemetryServer) hotKeyFeeBurnRate(w http.ResponseWriter, _ *http.Reque defer t.mu.Unlock() fmt.Fprintf(w, "%v", t.HotKeyBurnRate.GetBurnRate()) } + +func logMiddleware() mux.MiddlewareFunc { + return func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Debug(). + Str("route", r.URL.Path). + Str("port", r.URL.Port()). + Str("method", r.Method). + Msg("HTTP request received") + + handler.ServeHTTP(w, r) + }) + } +} diff --git a/zetaclient/supplychecker/logger.go b/zetaclient/supplychecker/logger.go new file mode 100644 index 0000000000..dc80c3e490 --- /dev/null +++ b/zetaclient/supplychecker/logger.go @@ -0,0 +1,29 @@ +package supplychecker + +import ( + sdkmath "cosmossdk.io/math" + "github.com/rs/zerolog" + "github.com/zeta-chain/zetacore/zetaclient/bitcoin" +) + +// ZetaSupplyCheckLogs is a struct to log the output of the ZetaSupplyChecker +type ZetaSupplyCheckLogs struct { + Logger zerolog.Logger + AbortedTxAmounts sdkmath.Int `json:"aborted_tx_amounts"` + ZetaInTransit sdkmath.Int `json:"zeta_in_transit"` + ExternalChainTotalSupply sdkmath.Int `json:"external_chain_total_supply"` + ZetaTokenSupplyOnNode sdkmath.Int `json:"zeta_token_supply_on_node"` + EthLockedAmount sdkmath.Int `json:"eth_locked_amount"` + NodeAmounts sdkmath.Int `json:"node_amounts"` + LHS sdkmath.Int `json:"LHS"` + RHS sdkmath.Int `json:"RHS"` + SupplyCheckSuccess bool `json:"supply_check_success"` +} + +func (z ZetaSupplyCheckLogs) LogOutput() { + output, err := bitcoin.PrettyPrintStruct(z) + if err != nil { + z.Logger.Error().Err(err).Msgf("error pretty printing struct") + } + z.Logger.Info().Msgf(output) +} diff --git a/zetaclient/supplychecker/validate.go b/zetaclient/supplychecker/validate.go new file mode 100644 index 0000000000..089a34777e --- /dev/null +++ b/zetaclient/supplychecker/validate.go @@ -0,0 +1,30 @@ +package supplychecker + +import ( + sdkmath "cosmossdk.io/math" + "github.com/rs/zerolog" +) + +func ValidateZetaSupply(logger zerolog.Logger, abortedTxAmounts, zetaInTransit, genesisAmounts, externalChainTotalSupply, zetaTokenSupplyOnNode, ethLockedAmount sdkmath.Int) bool { + lhs := ethLockedAmount.Sub(abortedTxAmounts) + rhs := zetaTokenSupplyOnNode.Add(zetaInTransit).Add(externalChainTotalSupply).Sub(genesisAmounts) + + copyZetaTokenSupplyOnNode := zetaTokenSupplyOnNode + copyGenesisAmounts := genesisAmounts + nodeAmounts := copyZetaTokenSupplyOnNode.Sub(copyGenesisAmounts) + logs := ZetaSupplyCheckLogs{ + Logger: logger, + AbortedTxAmounts: abortedTxAmounts, + ZetaInTransit: zetaInTransit, + ExternalChainTotalSupply: externalChainTotalSupply, + NodeAmounts: nodeAmounts, + ZetaTokenSupplyOnNode: zetaTokenSupplyOnNode, + EthLockedAmount: ethLockedAmount, + LHS: lhs, + RHS: rhs, + } + defer logs.LogOutput() + + logs.SupplyCheckSuccess = lhs.Equal(rhs) + return logs.SupplyCheckSuccess +} diff --git a/zetaclient/supplychecker/zeta_supply_checker.go b/zetaclient/supplychecker/zeta_supply_checker.go index 14b4c056d2..7e628247d9 100644 --- a/zetaclient/supplychecker/zeta_supply_checker.go +++ b/zetaclient/supplychecker/zeta_supply_checker.go @@ -4,7 +4,6 @@ import ( "fmt" appcontext "github.com/zeta-chain/zetacore/zetaclient/app_context" - "github.com/zeta-chain/zetacore/zetaclient/bitcoin" "github.com/zeta-chain/zetacore/zetaclient/interfaces" "github.com/zeta-chain/zetacore/zetaclient/zetabridge" @@ -22,6 +21,7 @@ import ( clienttypes "github.com/zeta-chain/zetacore/zetaclient/types" ) +// ZetaSupplyChecker is a utility to check the total supply of Zeta tokens type ZetaSupplyChecker struct { coreContext *corecontext.ZetaCoreContext evmClient map[int64]*ethclient.Client @@ -34,7 +34,12 @@ type ZetaSupplyChecker struct { genesisSupply sdkmath.Int } -func NewZetaSupplyChecker(appContext *appcontext.AppContext, zetaClient *zetabridge.ZetaCoreBridge, logger zerolog.Logger) (ZetaSupplyChecker, error) { +// NewZetaSupplyChecker creates a new ZetaSupplyChecker +func NewZetaSupplyChecker( + appContext *appcontext.AppContext, + zetaClient *zetabridge.ZetaCoreBridge, + logger zerolog.Logger, +) (ZetaSupplyChecker, error) { dynamicTicker, err := clienttypes.NewDynamicTicker("ZETASupplyTicker", 15) if err != nil { return ZetaSupplyChecker{}, err @@ -50,6 +55,7 @@ func NewZetaSupplyChecker(appContext *appcontext.AppContext, zetaClient *zetabri coreContext: appContext.ZetaCoreContext(), zetaClient: zetaClient, } + for _, evmConfig := range appContext.Config().GetAllEVMConfigs() { if evmConfig.Chain.IsZetaChain() { continue @@ -70,10 +76,12 @@ func NewZetaSupplyChecker(appContext *appcontext.AppContext, zetaClient *zetabri zetaSupplyChecker.ethereumChain = *chain } } + balances, err := zetaSupplyChecker.zetaClient.GetGenesisSupply() if err != nil { return zetaSupplyChecker, err } + tokensMintedAtBeginBlock, ok := sdkmath.NewIntFromString("200000000000000000") if !ok { return zetaSupplyChecker, fmt.Errorf("error parsing tokens minted at begin block") @@ -84,6 +92,7 @@ func NewZetaSupplyChecker(appContext *appcontext.AppContext, zetaClient *zetabri return zetaSupplyChecker, nil } + func (zs *ZetaSupplyChecker) Start() { defer zs.ticker.Stop() for { @@ -119,15 +128,18 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { if err != nil { return err } + totalSupply, err := zetatokenNonEth.TotalSupply(nil) if err != nil { return err } + totalSupplyInt, ok := sdkmath.NewIntFromString(totalSupply.String()) if !ok { zs.logger.Error().Msgf("error parsing total supply for chain %d", chain.ChainId) continue } + externalChainTotalSupply = externalChainTotalSupply.Add(totalSupplyInt) } @@ -135,6 +147,7 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { if !ok { return fmt.Errorf("eth config not found for chain id %d", zs.ethereumChain.ChainId) } + ethConnectorAddressString := evmChainParams.ConnectorContractAddress ethConnectorAddress := ethcommon.HexToAddress(ethConnectorAddressString) ethConnectorContract, err := evm.FetchConnectorContractEth(ethConnectorAddress, zs.evmClient[zs.ethereumChain.ChainId]) @@ -146,6 +159,7 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { if err != nil { return err } + ethLockedAmountInt, ok := sdkmath.NewIntFromString(ethLockedAmount.String()) if !ok { return fmt.Errorf("error parsing eth locked amount") @@ -156,60 +170,15 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { if err != nil { return err } + abortedAmount, err := zs.AbortedTxAmount() if err != nil { return err } - ValidateZetaSupply(zs.logger, abortedAmount, zetaInTransit, zs.genesisSupply, externalChainTotalSupply, zetaTokenSupplyOnNode, ethLockedAmountInt) - return nil -} -type ZetaSupplyCheckLogs struct { - Logger zerolog.Logger - AbortedTxAmounts sdkmath.Int `json:"aborted_tx_amounts"` - ZetaInTransit sdkmath.Int `json:"zeta_in_transit"` - ExternalChainTotalSupply sdkmath.Int `json:"external_chain_total_supply"` - ZetaTokenSupplyOnNode sdkmath.Int `json:"zeta_token_supply_on_node"` - EthLockedAmount sdkmath.Int `json:"eth_locked_amount"` - NodeAmounts sdkmath.Int `json:"node_amounts"` - LHS sdkmath.Int `json:"LHS"` - RHS sdkmath.Int `json:"RHS"` - SupplyCheckSuccess bool `json:"supply_check_success"` -} - -func (z ZetaSupplyCheckLogs) LogOutput() { - output, err := bitcoin.PrettyPrintStruct(z) - if err != nil { - z.Logger.Error().Err(err).Msgf("error pretty printing struct") - } - z.Logger.Info().Msgf(output) -} + ValidateZetaSupply(zs.logger, abortedAmount, zetaInTransit, zs.genesisSupply, externalChainTotalSupply, zetaTokenSupplyOnNode, ethLockedAmountInt) -func ValidateZetaSupply(logger zerolog.Logger, abortedTxAmounts, zetaInTransit, genesisAmounts, externalChainTotalSupply, zetaTokenSupplyOnNode, ethLockedAmount sdkmath.Int) bool { - lhs := ethLockedAmount.Sub(abortedTxAmounts) - rhs := zetaTokenSupplyOnNode.Add(zetaInTransit).Add(externalChainTotalSupply).Sub(genesisAmounts) - - copyZetaTokenSupplyOnNode := zetaTokenSupplyOnNode - copyGenesisAmounts := genesisAmounts - nodeAmounts := copyZetaTokenSupplyOnNode.Sub(copyGenesisAmounts) - logs := ZetaSupplyCheckLogs{ - Logger: logger, - AbortedTxAmounts: abortedTxAmounts, - ZetaInTransit: zetaInTransit, - ExternalChainTotalSupply: externalChainTotalSupply, - NodeAmounts: nodeAmounts, - ZetaTokenSupplyOnNode: zetaTokenSupplyOnNode, - EthLockedAmount: ethLockedAmount, - LHS: lhs, - RHS: rhs, - } - defer logs.LogOutput() - if !lhs.Equal(rhs) { - logs.SupplyCheckSuccess = false - return false - } - logs.SupplyCheckSuccess = true - return true + return nil } func (zs *ZetaSupplyChecker) AbortedTxAmount() (sdkmath.Int, error) { @@ -229,6 +198,7 @@ func (zs *ZetaSupplyChecker) GetAmountOfZetaInTransit() sdkmath.Int { chainsToCheck = append(append(chainsToCheck, zs.externalEvmChain...), zs.ethereumChain) cctxs := zs.GetPendingCCTXInTransit(chainsToCheck) amount := sdkmath.ZeroUint() + for _, cctx := range cctxs { amount = amount.Add(cctx.GetCurrentOutTxParam().Amount) } @@ -236,8 +206,10 @@ func (zs *ZetaSupplyChecker) GetAmountOfZetaInTransit() sdkmath.Int { if !ok { panic("error parsing amount") } + return amountInt } + func (zs *ZetaSupplyChecker) GetPendingCCTXInTransit(receivingChains []chains.Chain) []*types.CrossChainTx { cctxInTransit := make([]*types.CrossChainTx, 0) for _, chain := range receivingChains { @@ -266,5 +238,6 @@ func (zs *ZetaSupplyChecker) GetPendingCCTXInTransit(receivingChains []chains.Ch } } } + return cctxInTransit } diff --git a/zetaclient/testutils/constant.go b/zetaclient/testutils/constant.go index 380c3ab501..ad8302577d 100644 --- a/zetaclient/testutils/constant.go +++ b/zetaclient/testutils/constant.go @@ -3,16 +3,20 @@ package testutils import ethcommon "github.com/ethereum/go-ethereum/common" const ( - // tss addresses + // TSSAddressEVMMainnet the EVM TSS address for test purposes + // Note: public key is zetapub1addwnpepqtadxdyt037h86z60nl98t6zk56mw5zpnm79tsmvspln3hgt5phdc79kvfc TSSAddressEVMMainnet = "0x70e967acFcC17c3941E87562161406d41676FD83" + + // TSSAddressBTCMainnet the BTC TSS address for test purposes TSSAddressBTCMainnet = "bc1qm24wp577nk8aacckv8np465z3dvmu7ry45el6y" - TssPubkeyEVMMainnet = "zetapub1addwnpepqtadxdyt037h86z60nl98t6zk56mw5zpnm79tsmvspln3hgt5phdc79kvfc" + // TSSAddressEVMAthens3 the EVM TSS address for test purposes + // Note: public key is zetapub1addwnpepq28c57cvcs0a2htsem5zxr6qnlvq9mzhmm76z3jncsnzz32rclangr2g35p TSSAddressEVMAthens3 = "0x8531a5aB847ff5B22D855633C25ED1DA3255247e" + + // TSSAddressBTCAthens3 the BTC TSS address for test purposes TSSAddressBTCAthens3 = "tb1qy9pqmk2pd9sv63g27jt8r657wy0d9ueeh0nqur" - TssPubkeyEVMAthens3 = "zetapub1addwnpepq28c57cvcs0a2htsem5zxr6qnlvq9mzhmm76z3jncsnzz32rclangr2g35p" - // some other addresses OtherAddress1 = "0x21248Decd0B7EcB0F30186297766b8AB6496265b" OtherAddress2 = "0x33A351C90aF486AebC35042Bb0544123cAed26AB" OtherAddress3 = "0x86B77E4fBd07CFdCc486cAe4F2787fB5C5a62cd3" @@ -27,8 +31,10 @@ const ( // ConnectorAddresses contains constants ERC20 connector addresses for testing var ConnectorAddresses = map[int64]ethcommon.Address{ - // mainnet - 1: ethcommon.HexToAddress("0x000007Cf399229b2f5A4D043F20E90C9C98B7C6a"), + // Connector address on Ethereum mainnet + 1: ethcommon.HexToAddress("0x000007Cf399229b2f5A4D043F20E90C9C98B7C6a"), + + // Connector address on Binance Smart Chain mainnet 56: ethcommon.HexToAddress("0x000063A6e758D9e2f438d430108377564cf4077D"), // testnet @@ -42,8 +48,10 @@ var ConnectorAddresses = map[int64]ethcommon.Address{ // CustodyAddresses contains constants ERC20 custody addresses for testing var CustodyAddresses = map[int64]ethcommon.Address{ - // mainnet - 1: ethcommon.HexToAddress("0x0000030Ec64DF25301d8414eE5a29588C4B0dE10"), + // ERC20 custody address on Ethereum mainnet + 1: ethcommon.HexToAddress("0x0000030Ec64DF25301d8414eE5a29588C4B0dE10"), + + // ERC20 custody address on Binance Smart Chain mainnet 56: ethcommon.HexToAddress("0x00000fF8fA992424957F97688015814e707A0115"), // testnet diff --git a/zetaclient/testutils/testdata.go b/zetaclient/testutils/testdata.go index 001ca2b07b..42be79028b 100644 --- a/zetaclient/testutils/testdata.go +++ b/zetaclient/testutils/testdata.go @@ -35,19 +35,6 @@ func cloneCctx(t *testing.T, cctx *crosschaintypes.CrossChainTx) *crosschaintype return cloned } -// SaveObjectToJSONFile saves an object to a file in JSON format -func SaveObjectToJSONFile(obj interface{}, filename string) error { - file, err := os.Create(filepath.Clean(filename)) - if err != nil { - return err - } - defer file.Close() - - // write the struct to the file - encoder := json.NewEncoder(file) - return encoder.Encode(obj) -} - // LoadObjectFromJSONFile loads an object from a file in JSON format func LoadObjectFromJSONFile(t *testing.T, obj interface{}, filename string) { file, err := os.Open(filepath.Clean(filename)) @@ -66,27 +53,6 @@ func ComplianceConfigTest() config.ComplianceConfig { } } -// SaveTrimedEVMBlockTrimTxInput trims tx input data from a block and saves it to a file -func SaveEVMBlockTrimTxInput(block *ethrpc.Block, filename string) error { - for i := range block.Transactions { - block.Transactions[i].Input = "0x" - } - return SaveObjectToJSONFile(block, filename) -} - -// SaveTrimedBTCBlockTrimTx trims tx data from a block and saves it to a file -func SaveBTCBlockTrimTx(blockVb *btcjson.GetBlockVerboseTxResult, filename string) error { - for i := range blockVb.Tx { - // reserve one coinbase tx and one non-coinbase tx - if i >= 2 { - blockVb.Tx[i].Hex = "" - blockVb.Tx[i].Vin = nil - blockVb.Tx[i].Vout = nil - } - } - return SaveObjectToJSONFile(blockVb, filename) -} - // LoadCctxByIntx loads archived cctx by intx func LoadCctxByIntx( t *testing.T, @@ -234,7 +200,7 @@ func LoadEVMIntxNReceiptDonation( return tx, receipt } -// LoadTxNReceiptNCctx loads archived intx, receipt and corresponding cctx from file +// LoadEVMIntxNReceiptNCctx loads archived intx, receipt and corresponding cctx from file func LoadEVMIntxNReceiptNCctx( t *testing.T, chainID int64, @@ -288,7 +254,7 @@ func LoadEVMOuttxNReceipt( return tx, receipt } -// LoadEVMOuttxNReceiptNEvent loads archived cctx, outtx and receipt from file +// LoadEVMCctxNOuttxNReceipt loads archived cctx, outtx and receipt from file func LoadEVMCctxNOuttxNReceipt( t *testing.T, chainID int64, @@ -301,3 +267,40 @@ func LoadEVMCctxNOuttxNReceipt( receipt := LoadEVMOuttxReceipt(t, chainID, txHash, coinType, eventName) return cctx, outtx, receipt } + +// SaveObjectToJSONFile saves an object to a file in JSON format +// NOTE: this function is not used in the tests but used when creating test data +func SaveObjectToJSONFile(obj interface{}, filename string) error { + file, err := os.Create(filepath.Clean(filename)) + if err != nil { + return err + } + defer file.Close() + + // write the struct to the file + encoder := json.NewEncoder(file) + return encoder.Encode(obj) +} + +// SaveEVMBlockTrimTxInput trims tx input data from a block and saves it to a file +// NOTE: this function is not used in the tests but used when creating test data +func SaveEVMBlockTrimTxInput(block *ethrpc.Block, filename string) error { + for i := range block.Transactions { + block.Transactions[i].Input = "0x" + } + return SaveObjectToJSONFile(block, filename) +} + +// SaveBTCBlockTrimTx trims tx data from a block and saves it to a file +// NOTE: this function is not used in the tests but used when creating test data +func SaveBTCBlockTrimTx(blockVb *btcjson.GetBlockVerboseTxResult, filename string) error { + for i := range blockVb.Tx { + // reserve one coinbase tx and one non-coinbase tx + if i >= 2 { + blockVb.Tx[i].Hex = "" + blockVb.Tx[i].Vin = nil + blockVb.Tx[i].Vout = nil + } + } + return SaveObjectToJSONFile(blockVb, filename) +} diff --git a/zetaclient/tss/tss_keysign_manager.go b/zetaclient/tss/concurrent_keysigns_tracker.go similarity index 100% rename from zetaclient/tss/tss_keysign_manager.go rename to zetaclient/tss/concurrent_keysigns_tracker.go diff --git a/zetaclient/tss/tss_keysign_manager_test.go b/zetaclient/tss/concurrent_keysigns_tracker_test.go similarity index 100% rename from zetaclient/tss/tss_keysign_manager_test.go rename to zetaclient/tss/concurrent_keysigns_tracker_test.go diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 3ff467c2dd..379d89c5f7 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -41,8 +41,8 @@ const ( ) type Key struct { - PubkeyInBytes []byte // FIXME: compressed pubkey? - PubkeyInBech32 string // FIXME: same above + PubkeyInBytes []byte + PubkeyInBech32 string AddressInHex string } @@ -55,12 +55,15 @@ func NewTSSKey(pk string) (*Key, error) { log.Error().Err(err).Msgf("GetPubKeyFromBech32 from %s", pk) return nil, fmt.Errorf("GetPubKeyFromBech32: %w", err) } + decompresspubkey, err := crypto.DecompressPubkey(pubkey.Bytes()) if err != nil { return nil, fmt.Errorf("NewTSS: DecompressPubkey error: %w", err) } + TSSKey.PubkeyInBytes = crypto.FromECDSAPub(decompresspubkey) TSSKey.AddressInHex = crypto.PubkeyToAddress(*decompresspubkey).Hex() + return TSSKey, nil } @@ -98,6 +101,7 @@ func NewTSS( if err != nil { return nil, fmt.Errorf("SetupTSSServer error: %w", err) } + newTss := TSS{ Server: server, Keys: make(map[string]*Key), @@ -112,14 +116,17 @@ func NewTSS( if err != nil { return nil, err } + _, pubkeyInBech32, err := keys.GetKeyringKeybase(appContext.Config(), hotkeyPassword) if err != nil { return nil, err } + err = newTss.VerifyKeysharesForPubkeys(tssHistoricalList, pubkeyInBech32) if err != nil { bridge.GetLogger().Error().Err(err).Msg("VerifyKeysharesForPubkeys fail") } + keygenRes, err := newTss.CoreBridge.GetKeyGen() if err != nil { return nil, err @@ -134,7 +141,13 @@ func NewTSS( return &newTss, nil } -func SetupTSSServer(peer p2p.AddrList, privkey tmcrypto.PrivKey, preParams *keygen.LocalPreParams, cfg config.Config, tssPassword string) (*tss.TssServer, error) { +func SetupTSSServer( + peer p2p.AddrList, + privkey tmcrypto.PrivKey, + preParams *keygen.LocalPreParams, + cfg config.Config, + tssPassword string, +) (*tss.TssServer, error) { bootstrapPeers := peer log.Info().Msgf("Peers AddrList %v", bootstrapPeers) @@ -149,10 +162,12 @@ func SetupTSSServer(peer p2p.AddrList, privkey tmcrypto.PrivKey, preParams *keyg tsspath = path.Join(homedir, ".Tss") log.Info().Msgf("create temporary TSSPATH: %s", tsspath) } + IP := cfg.PublicIP if len(IP) == 0 { log.Info().Msg("empty public IP in config") } + tssServer, err := tss.NewTss( bootstrapPeers, 6668, @@ -192,7 +207,6 @@ func SetupTSSServer(peer p2p.AddrList, privkey tmcrypto.PrivKey, preParams *keyg return tssServer, nil } -// FIXME: does it return pubkey in compressed form or uncompressed? func (tss *TSS) Pubkey() []byte { return tss.Keys[tss.CurrentPubkey].PubkeyInBytes } @@ -208,6 +222,7 @@ func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *chains.C if optionalPubKey != "" { tssPubkey = optionalPubKey } + // #nosec G701 always in range keysignReq := keysign.NewRequest(tssPubkey, []string{base64.StdEncoding.EncodeToString(H)}, int64(height), nil, "0.14.0") tss.KeysignsTracker.StartMsgSign() @@ -216,6 +231,7 @@ func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *chains.C if err != nil { log.Warn().Msg("keysign fail") } + if ksRes.Status == thorcommon.Fail { log.Warn().Msgf("keysign status FAIL posting blame to core, blaming node(s): %#v", ksRes.Blame.BlameNodes) @@ -246,21 +262,25 @@ func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *chains.C log.Warn().Err(err).Msgf("signature has length 0") return [65]byte{}, fmt.Errorf("keysign fail: %s", err) } + if !verifySignature(tssPubkey, signature, H) { log.Error().Err(err).Msgf("signature verification failure") return [65]byte{}, fmt.Errorf("signuature verification fail") } + var sigbyte [65]byte _, err = base64.StdEncoding.Decode(sigbyte[:32], []byte(signature[0].R)) if err != nil { log.Error().Err(err).Msg("decoding signature R") return [65]byte{}, fmt.Errorf("signuature verification fail") } + _, err = base64.StdEncoding.Decode(sigbyte[32:64], []byte(signature[0].S)) if err != nil { log.Error().Err(err).Msg("decoding signature S") return [65]byte{}, fmt.Errorf("signuature verification fail") } + _, err = base64.StdEncoding.Decode(sigbyte[64:65], []byte(signature[0].RecoveryID)) if err != nil { log.Error().Err(err).Msg("decoding signature RecoveryID") @@ -372,12 +392,15 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, nonce uint64, chain * func (tss *TSS) Validate() error { evmAddress := tss.EVMAddress() blankAddress := ethcommon.Address{} + if evmAddress == blankAddress { return fmt.Errorf("invalid evm address : %s", evmAddress.String()) } + if tss.BTCAddressWitnessPubkeyHash() == nil { return fmt.Errorf("invalid btc pub key hash : %s", tss.BTCAddress()) } + return nil } @@ -438,6 +461,7 @@ func (tss *TSS) VerifyKeysharesForPubkeys(tssList []observertypes.TSS, granteePu } return nil } + func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { files, err := os.ReadDir(tssPath) if err != nil { @@ -445,12 +469,14 @@ func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { return err } found := false + var sharefiles []os.DirEntry for _, file := range files { if !file.IsDir() && strings.HasPrefix(filepath.Base(file.Name()), "localstate") { sharefiles = append(sharefiles, file) } } + if len(sharefiles) > 0 { sort.SliceStable(sharefiles, func(i, j int) bool { fi, err := sharefiles[i].Info() @@ -480,6 +506,7 @@ func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { } } } + if !found { log.Info().Msg("TSS Keyshare file NOT found") } @@ -527,6 +554,7 @@ func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { if err != nil { log.Warn().Msg("keysign fail") } + signature := ksRes.Signatures // [{cyP8i/UuCVfQKDsLr1kpg09/CeIHje1FU6GhfmyMD5Q= D4jXTH3/CSgCg+9kLjhhfnNo3ggy9DTQSlloe3bbKAs= eY++Z2LwsuKG1JcghChrsEJ4u9grLloaaFZNtXI3Ujk= AA==}] // 32B msg hash, 32B R, 32B S, 1B RC @@ -536,13 +564,20 @@ func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { log.Info().Msgf("signature has length 0, skipping verify") return fmt.Errorf("signature has length 0") } + verifySignature(tssPubkey, signature, H.Bytes()) if verifySignature(tssPubkey, signature, H.Bytes()) { return nil } + return fmt.Errorf("verify signature fail") } +func IsEnvFlagEnabled(flag string) bool { + value := os.Getenv(flag) + return value == "true" || value == "1" +} + func verifySignature(tssPubkey string, signature []keysign.Signature, H []byte) bool { if len(signature) == 0 { log.Warn().Msg("verify_signature: empty signature array") @@ -552,6 +587,7 @@ func verifySignature(tssPubkey string, signature []keysign.Signature, H []byte) if err != nil { log.Error().Msg("get pubkey from bech32 fail") } + // verify the signature of msg. var sigbyte [65]byte _, err = base64.StdEncoding.Decode(sigbyte[:32], []byte(signature[0].R)) @@ -559,21 +595,25 @@ func verifySignature(tssPubkey string, signature []keysign.Signature, H []byte) log.Error().Err(err).Msg("decoding signature R") return false } + _, err = base64.StdEncoding.Decode(sigbyte[32:64], []byte(signature[0].S)) if err != nil { log.Error().Err(err).Msg("decoding signature S") return false } + _, err = base64.StdEncoding.Decode(sigbyte[64:65], []byte(signature[0].RecoveryID)) if err != nil { log.Error().Err(err).Msg("decoding signature RecoveryID") return false } + sigPublicKey, err := crypto.SigToPub(H, sigbyte[:]) if err != nil { log.Error().Err(err).Msg("SigToPub error in verify_signature") return false } + compressedPubkey := crypto.CompressPubkey(sigPublicKey) log.Info().Msgf("pubkey %s recovered pubkey %s", pubkey.String(), hex.EncodeToString(compressedPubkey)) return bytes.Equal(pubkey.Bytes(), compressedPubkey) @@ -611,8 +651,3 @@ func getKeyAddrBTCWitnessPubkeyHash(tssPubkey string, chainID int64) (*btcutil.A } return addr, nil } - -func IsEnvFlagEnabled(flag string) bool { - value := os.Getenv(flag) - return value == "true" || value == "1" -} diff --git a/zetaclient/tss/tss_signer_test.go b/zetaclient/tss/tss_signer_test.go index 4388fc5ef1..d19e2effcc 100644 --- a/zetaclient/tss/tss_signer_test.go +++ b/zetaclient/tss/tss_signer_test.go @@ -5,15 +5,26 @@ import ( "os" "testing" - "github.com/zeta-chain/zetacore/zetaclient/keys" - "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/rs/zerolog" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/cmd" "github.com/zeta-chain/zetacore/pkg/cosmos" "github.com/zeta-chain/zetacore/pkg/crypto" ) +func setupConfig() { + testConfig := sdk.GetConfig() + testConfig.SetBech32PrefixForAccount(cmd.Bech32PrefixAccAddr, cmd.Bech32PrefixAccPub) + testConfig.SetBech32PrefixForValidator(cmd.Bech32PrefixValAddr, cmd.Bech32PrefixValPub) + testConfig.SetBech32PrefixForConsensusNode(cmd.Bech32PrefixConsAddr, cmd.Bech32PrefixConsPub) + testConfig.SetFullFundraiserPath(cmd.ZetaChainHDPath) + sdk.SetCoinDenomRegex(func() string { + return cmd.DenomRegex + }) +} + func Test_LoadTssFilesFromDirectory(t *testing.T) { tt := []struct { @@ -52,7 +63,7 @@ func Test_LoadTssFilesFromDirectory(t *testing.T) { } func GenerateKeyshareFiles(n int, dir string) error { - keys.SetupConfigForTest() + setupConfig() err := os.Chdir(dir) if err != nil { return err diff --git a/zetaclient/types/account_resp.go b/zetaclient/types/account_resp.go deleted file mode 100644 index 41424907ad..0000000000 --- a/zetaclient/types/account_resp.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -// AccountResp the response from thorclient -type AccountResp struct { - Height string `json:"height"` - Result struct { - Value struct { - AccountNumber uint64 `json:"account_number,string"` - Sequence uint64 `json:"sequence,string"` - } `json:"value"` - } `json:"result"` -} diff --git a/zetaclient/types/ethish_test.go b/zetaclient/types/ethish_test.go deleted file mode 100644 index d932b46501..0000000000 --- a/zetaclient/types/ethish_test.go +++ /dev/null @@ -1 +0,0 @@ -package types_test diff --git a/zetaclient/zetabridge/block_height.go b/zetaclient/zetabridge/block_height.go deleted file mode 100644 index 30fcce82b4..0000000000 --- a/zetaclient/zetabridge/block_height.go +++ /dev/null @@ -1,24 +0,0 @@ -package zetabridge - -import ( - "context" - "fmt" - - "github.com/zeta-chain/zetacore/x/crosschain/types" -) - -// GetBlockHeight returns the current height for metachain blocks -// FIXME: deprecate this in favor of tendermint RPC? -func (b *ZetaCoreBridge) GetBlockHeight() (int64, error) { - client := types.NewQueryClient(b.grpcConn) - height, err := client.LastZetaHeight( - context.Background(), - &types.QueryLastZetaHeightRequest{}, - ) - if err != nil { - return 0, err - } - - fmt.Printf("block height: %d\n", height.Height) - return height.Height, nil -} diff --git a/zetaclient/zetabridge/query_test.go b/zetaclient/zetabridge/query_test.go index ea76fa78fd..556bb83101 100644 --- a/zetaclient/zetabridge/query_test.go +++ b/zetaclient/zetabridge/query_test.go @@ -438,12 +438,6 @@ func TestZetaCoreBridge_GetZetaBlockHeight(t *testing.T) { require.NoError(t, err) require.Equal(t, expectedOutput.Height, resp) }) - - t.Run("get block height success", func(t *testing.T) { - resp, err := zetabridge.GetBlockHeight() - require.NoError(t, err) - require.Equal(t, expectedOutput.Height, resp) - }) } func TestZetaCoreBridge_GetBaseGasPrice(t *testing.T) { diff --git a/zetaclient/zetabridge/zetacore_bridge.go b/zetaclient/zetabridge/zetacore_bridge.go index 3899d51d82..5da5b592f1 100644 --- a/zetaclient/zetabridge/zetacore_bridge.go +++ b/zetaclient/zetabridge/zetacore_bridge.go @@ -5,18 +5,13 @@ import ( "sync" "time" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp/params" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/rs/zerolog" "github.com/rs/zerolog/log" rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/zeta-chain/zetacore/app" "github.com/zeta-chain/zetacore/pkg/authz" "github.com/zeta-chain/zetacore/pkg/chains" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/config" corecontext "github.com/zeta-chain/zetacore/zetaclient/core_context" @@ -110,16 +105,6 @@ func NewZetaCoreBridge( }, nil } -// MakeLegacyCodec creates codec -func MakeLegacyCodec() *codec.LegacyAmino { - cdc := codec.NewLegacyAmino() - banktypes.RegisterLegacyAminoCodec(cdc) - authtypes.RegisterLegacyAminoCodec(cdc) - sdk.RegisterLegacyAminoCodec(cdc) - crosschaintypes.RegisterCodec(cdc) - return cdc -} - func (b *ZetaCoreBridge) GetLogger() *zerolog.Logger { return &b.logger } diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index c66f15f50a..5f187caed7 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -89,6 +89,61 @@ func (co *CoreObserver) MonitorCore(appContext *appcontext.AppContext) { }() } +// GetUpdatedSigner returns signer with updated chain parameters +func (co *CoreObserver) GetUpdatedSigner(coreContext *corecontext.ZetaCoreContext, chainID int64) (interfaces.ChainSigner, error) { + signer, found := co.signerMap[chainID] + if !found { + return nil, fmt.Errorf("signer not found for chainID %d", chainID) + } + // update EVM signer parameters only. BTC signer doesn't use chain parameters for now. + if chains.IsEVMChain(chainID) { + evmParams, found := coreContext.GetEVMChainParams(chainID) + if found { + // update zeta connector and ERC20 custody addresses + zetaConnectorAddress := ethcommon.HexToAddress(evmParams.GetConnectorContractAddress()) + erc20CustodyAddress := ethcommon.HexToAddress(evmParams.GetErc20CustodyContractAddress()) + if zetaConnectorAddress != signer.GetZetaConnectorAddress() { + signer.SetZetaConnectorAddress(zetaConnectorAddress) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated zeta connector address for chainID %d, new address: %s", chainID, zetaConnectorAddress) + } + if erc20CustodyAddress != signer.GetERC20CustodyAddress() { + signer.SetERC20CustodyAddress(erc20CustodyAddress) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated ERC20 custody address for chainID %d, new address: %s", chainID, erc20CustodyAddress) + } + } + } + return signer, nil +} + +// GetUpdatedChainClient returns chain client object with updated chain parameters +func (co *CoreObserver) GetUpdatedChainClient(coreContext *corecontext.ZetaCoreContext, chainID int64) (interfaces.ChainClient, error) { + chainOb, found := co.clientMap[chainID] + if !found { + return nil, fmt.Errorf("chain client not found for chainID %d", chainID) + } + // update chain client chain parameters + curParams := chainOb.GetChainParams() + if chains.IsEVMChain(chainID) { + evmParams, found := coreContext.GetEVMChainParams(chainID) + if found && !observertypes.ChainParamsEqual(curParams, *evmParams) { + chainOb.SetChainParams(*evmParams) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated chain params for chainID %d, new params: %v", chainID, *evmParams) + } + } else if chains.IsBitcoinChain(chainID) { + _, btcParams, found := coreContext.GetBTCChainParams() + + if found && !observertypes.ChainParamsEqual(curParams, *btcParams) { + chainOb.SetChainParams(*btcParams) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated chain params for Bitcoin, new params: %v", *btcParams) + } + } + return chainOb, nil +} + // startCctxScheduler schedules keysigns for cctxs on each ZetaChain block (the ticker) func (co *CoreObserver) startCctxScheduler(appContext *appcontext.AppContext) { outTxMan := outtxprocessor.NewOutTxProcessorManager(co.logger.ChainLogger) @@ -219,7 +274,8 @@ func (co *CoreObserver) scheduleCctxEVM( chainID int64, cctxList []*types.CrossChainTx, ob interfaces.ChainClient, - signer interfaces.ChainSigner) { + signer interfaces.ChainSigner, +) { res, err := co.bridge.GetAllOutTxTrackerByChain(chainID, interfaces.Ascending) if err != nil { co.logger.ZetaChainWatcher.Warn().Err(err).Msgf("scheduleCctxEVM: GetAllOutTxTrackerByChain failed for chain %d", chainID) @@ -305,7 +361,8 @@ func (co *CoreObserver) scheduleCctxBTC( chainID int64, cctxList []*types.CrossChainTx, ob interfaces.ChainClient, - signer interfaces.ChainSigner) { + signer interfaces.ChainSigner, +) { btcClient, ok := ob.(*bitcoin.BTCChainClient) if !ok { // should never happen co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxBTC: chain client is not a bitcoin client") @@ -353,58 +410,3 @@ func (co *CoreObserver) scheduleCctxBTC( } } } - -// GetUpdatedSigner returns signer with updated chain parameters -func (co *CoreObserver) GetUpdatedSigner(coreContext *corecontext.ZetaCoreContext, chainID int64) (interfaces.ChainSigner, error) { - signer, found := co.signerMap[chainID] - if !found { - return nil, fmt.Errorf("signer not found for chainID %d", chainID) - } - // update EVM signer parameters only. BTC signer doesn't use chain parameters for now. - if chains.IsEVMChain(chainID) { - evmParams, found := coreContext.GetEVMChainParams(chainID) - if found { - // update zeta connector and ERC20 custody addresses - zetaConnectorAddress := ethcommon.HexToAddress(evmParams.GetConnectorContractAddress()) - erc20CustodyAddress := ethcommon.HexToAddress(evmParams.GetErc20CustodyContractAddress()) - if zetaConnectorAddress != signer.GetZetaConnectorAddress() { - signer.SetZetaConnectorAddress(zetaConnectorAddress) - co.logger.ZetaChainWatcher.Info().Msgf( - "updated zeta connector address for chainID %d, new address: %s", chainID, zetaConnectorAddress) - } - if erc20CustodyAddress != signer.GetERC20CustodyAddress() { - signer.SetERC20CustodyAddress(erc20CustodyAddress) - co.logger.ZetaChainWatcher.Info().Msgf( - "updated ERC20 custody address for chainID %d, new address: %s", chainID, erc20CustodyAddress) - } - } - } - return signer, nil -} - -// GetUpdatedChainClient returns chain client object with updated chain parameters -func (co *CoreObserver) GetUpdatedChainClient(coreContext *corecontext.ZetaCoreContext, chainID int64) (interfaces.ChainClient, error) { - chainOb, found := co.clientMap[chainID] - if !found { - return nil, fmt.Errorf("chain client not found for chainID %d", chainID) - } - // update chain client chain parameters - curParams := chainOb.GetChainParams() - if chains.IsEVMChain(chainID) { - evmParams, found := coreContext.GetEVMChainParams(chainID) - if found && !observertypes.ChainParamsEqual(curParams, *evmParams) { - chainOb.SetChainParams(*evmParams) - co.logger.ZetaChainWatcher.Info().Msgf( - "updated chain params for chainID %d, new params: %v", chainID, *evmParams) - } - } else if chains.IsBitcoinChain(chainID) { - _, btcParams, found := coreContext.GetBTCChainParams() - - if found && !observertypes.ChainParamsEqual(curParams, *btcParams) { - chainOb.SetChainParams(*btcParams) - co.logger.ZetaChainWatcher.Info().Msgf( - "updated chain params for Bitcoin, new params: %v", *btcParams) - } - } - return chainOb, nil -} From 379a05687b5e8bcc0f211c6ae3fcddb4fef2a0be Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 29 Apr 2024 12:57:43 -0400 Subject: [PATCH 2/5] refactor: add chain static info to chain struct (#2071) --- changelog.md | 4 +- cmd/zetaclientd/keygen_tss.go | 6 +- cmd/zetacored/parsers_test.go | 1 - docs/openapi/openapi.swagger.yaml | 57 ++- e2e/e2etests/test_bitcoin_withdraw.go | 8 +- e2e/e2etests/test_migrate_chain_support.go | 4 +- e2e/e2etests/test_zeta_withdraw.go | 2 +- e2e/runner/bitcoin.go | 2 +- e2e/runner/evm.go | 2 +- e2e/runner/setup_zeta.go | 4 +- e2e/txserver/zeta_tx_server.go | 6 +- pkg/chains/address_test.go | 58 +-- pkg/chains/bitcoin.go | 10 +- pkg/chains/bitcoin_test.go | 18 +- pkg/chains/chain.go | 64 +-- pkg/chains/chain_test.go | 112 ++--- pkg/chains/chains.go | 409 +++++++++------- pkg/chains/chains.pb.go | 438 ++++++++++++++++-- pkg/chains/chains_test.go | 261 +++++++++-- pkg/chains/status.go | 4 +- pkg/chains/status_test.go | 4 +- pkg/crypto/pubkey_test.go | 8 +- proto/observer/observer.proto | 1 + proto/pkg/chains/chains.proto | 57 ++- testutil/keeper/crosschain.go | 4 +- testutil/network/genesis_state.go | 5 +- testutil/sample/crosschain.go | 4 +- testutil/sample/fungible.go | 4 +- testutil/sample/lightclient.go | 2 +- testutil/sample/observer.go | 2 +- typescript/observer/observer_pb.d.ts | 2 + typescript/pkg/chains/chains_pb.d.ts | 142 +++++- x/crosschain/keeper/abci_test.go | 16 +- x/crosschain/keeper/evm_hooks_test.go | 58 +-- x/crosschain/keeper/gas_payment_test.go | 16 +- .../msg_server_add_to_intx_tracker_test.go | 8 +- .../msg_server_vote_outbound_tx_test.go | 12 +- x/crosschain/keeper/process_inbound_test.go | 18 +- x/crosschain/keeper/process_outbound_test.go | 26 +- .../keeper/rate_limiter_flags_test.go | 2 +- x/crosschain/keeper/utils_test.go | 10 +- x/crosschain/migrations/v4/migrate_test.go | 28 +- x/crosschain/migrations/v5/migrate.go | 8 +- x/crosschain/migrations/v5/migrate_test.go | 22 +- x/crosschain/types/cctx_test.go | 8 +- x/crosschain/types/inbound_params_test.go | 4 +- .../message_add_to_in_tx_tracker_test.go | 20 +- .../message_vote_on_observed_outbound_tx.go | 4 +- ...ssage_vote_on_observed_outbound_tx_test.go | 10 +- x/crosschain/types/tx.pb.go | 2 +- .../types/tx_body_verification_test.go | 46 +- x/crosschain/types/validate_test.go | 38 +- x/lightclient/genesis_test.go | 6 +- x/lightclient/keeper/block_header_test.go | 6 +- x/lightclient/keeper/proof_test.go | 10 +- .../keeper/verification_flags_test.go | 8 +- x/lightclient/types/genesis_test.go | 12 +- .../keeper/grpc_query_chain_params_test.go | 6 +- x/observer/keeper/grpc_query_tss_test.go | 8 +- .../msg_server_reset_chain_nonces_test.go | 8 +- .../msg_server_vote_block_header_test.go | 26 +- x/observer/keeper/msg_server_vote_tss.go | 2 +- x/observer/keeper/msg_server_vote_tss_test.go | 20 +- x/observer/keeper/utils_test.go | 4 +- x/observer/keeper/vote_inbound_test.go | 14 +- x/observer/keeper/vote_outbound_test.go | 16 +- x/observer/types/chain_params.go | 20 +- x/observer/types/message_vote_tss.go | 2 +- x/observer/types/message_vote_tss_test.go | 20 +- x/observer/types/observer.pb.go | 1 + x/observer/types/observer_set.go | 4 +- x/observer/types/observer_set_test.go | 6 +- x/observer/types/params.go | 6 +- x/observer/types/parsers.go | 4 +- x/observer/types/parsers_test.go | 6 +- x/observer/types/tx.pb.go | 2 +- zetaclient/bitcoin/bitcoin_client.go | 2 +- .../bitcoin/bitcoin_client_live_test.go | 4 +- zetaclient/bitcoin/bitcoin_client_test.go | 18 +- zetaclient/bitcoin/bitcoin_signer_test.go | 2 +- zetaclient/bitcoin/fee_test.go | 2 +- zetaclient/bitcoin/tx_script_test.go | 28 +- zetaclient/compliance/compliance_test.go | 2 +- zetaclient/config/config_chain.go | 28 +- .../core_context/zeta_core_context_test.go | 6 +- zetaclient/evm/evm_client.go | 22 +- zetaclient/evm/evm_client_test.go | 2 +- zetaclient/evm/evm_signer.go | 2 +- zetaclient/evm/evm_signer_test.go | 6 +- zetaclient/evm/inbounds_test.go | 14 +- .../evm/outbound_transaction_data_test.go | 4 +- zetaclient/evm/outbounds.go | 14 +- zetaclient/evm/outbounds_test.go | 36 +- zetaclient/testutils/stub/tss_signer.go | 4 +- zetaclient/zetabridge/broadcast_test.go | 4 +- zetaclient/zetabridge/query_test.go | 42 +- zetaclient/zetabridge/tx.go | 2 +- zetaclient/zetabridge/tx_test.go | 45 +- zetaclient/zetacore_observer_test.go | 14 +- 99 files changed, 1726 insertions(+), 855 deletions(-) diff --git a/changelog.md b/changelog.md index 80054959a8..8497cfcd8e 100644 --- a/changelog.md +++ b/changelog.md @@ -50,6 +50,7 @@ * [1989](https://github.com/zeta-chain/node/pull/1989) - simplify `IsSendOutTxProcessed` method and add unit tests * [2013](https://github.com/zeta-chain/node/pull/2013) - rename `GasPriceVoter` message to `VoteGasPrice` * [2059](https://github.com/zeta-chain/node/pull/2059) - Remove unused params from all functions in zetanode +* [2071](https://github.com/zeta-chain/node/pull/2071) - Modify chains struct to add all chain related information ### Features @@ -117,8 +118,7 @@ ## Version: v15.0.0 ### Features - -*[1912](https://github.com/zeta-chain/node/pull/1912) - add reset chain nonces msg +* [1912](https://github.com/zeta-chain/node/pull/1912) - add reset chain nonces msg ## Version: v14.0.1 diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 72c7946da3..cc33f17cbd 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -37,7 +37,7 @@ func GenerateTss( // Bitcoin chain ID is currently used for using the correct signature format // TODO: remove this once we have a better way to determine the signature format // https://github.com/zeta-chain/node/issues/1397 - bitcoinChainID := chains.BtcRegtestChain().ChainId + bitcoinChainID := chains.BtcRegtestChain.ChainId btcChain, _, btcEnabled := appContext.GetBTCChainAndConfig() if btcEnabled { bitcoinChainID = btcChain.ChainId @@ -109,7 +109,7 @@ func GenerateTss( err = keygenTss(keyGen, tss, keygenLogger) if err != nil { keygenLogger.Error().Err(err).Msg("keygenTss error") - tssFailedVoteHash, err := zetaBridge.SetTSS("", keyGen.BlockNumber, chains.ReceiveStatus_Failed) + tssFailedVoteHash, err := zetaBridge.SetTSS("", keyGen.BlockNumber, chains.ReceiveStatus_failed) if err != nil { keygenLogger.Error().Err(err).Msg("Failed to broadcast Failed TSS Vote to zetacore") return nil, err @@ -127,7 +127,7 @@ func GenerateTss( } // If TSS is successful , broadcast the vote to zetacore and set Pubkey - tssSuccessVoteHash, err := zetaBridge.SetTSS(newTss.CurrentPubkey, keyGen.BlockNumber, chains.ReceiveStatus_Success) + tssSuccessVoteHash, err := zetaBridge.SetTSS(newTss.CurrentPubkey, keyGen.BlockNumber, chains.ReceiveStatus_success) if err != nil { keygenLogger.Error().Err(err).Msg("TSS successful but unable to broadcast vote to zeta-core") return nil, err diff --git a/cmd/zetacored/parsers_test.go b/cmd/zetacored/parsers_test.go index 06f0346903..9905af6ded 100644 --- a/cmd/zetacored/parsers_test.go +++ b/cmd/zetacored/parsers_test.go @@ -31,7 +31,6 @@ func TestParsefileToObserverMapper(t *testing.T) { func createObserverList(fp string) { var listReader []ObserverInfoReader - //listChainID := []int64{common.GoerliLocalNetChain().ChainId, common.BtcRegtestChain().ChainId, common.ZetaChain().ChainId} commonGrantAddress := sdk.AccAddress(crypto.AddressHash([]byte("ObserverGranteeAddress"))) observerAddress := sdk.AccAddress(crypto.AddressHash([]byte("ObserverAddress"))) validatorAddress := sdk.ValAddress(crypto.AddressHash([]byte("ValidatorAddress"))) diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 1eb8fe4593..2bcfa77836 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -53592,6 +53592,18 @@ definitions: chain_id: type: string format: int64 + network: + $ref: '#/definitions/chainsNetwork' + network_type: + $ref: '#/definitions/chainsNetworkType' + vm: + $ref: '#/definitions/chainsVm' + consensus: + $ref: '#/definitions/chainsConsensus' + is_external: + type: boolean + is_header_supported: + type: boolean chainsChainName: type: string enum: @@ -53613,14 +53625,49 @@ definitions: - btc_regtest - amoy_testnet default: empty + title: ChainName represents the name of the chain + chainsConsensus: + type: string + enum: + - ethereum + - tendermint + - bitcoin + default: ethereum + title: Consensus represents the consensus algorithm used by the chain + chainsNetwork: + type: string + enum: + - eth + - zeta + - btc + - polygon + - bsc + default: eth + title: Network represents the network type of the chain + chainsNetworkType: + type: string + enum: + - mainnet + - testnet + - privnet + - devnet + default: mainnet + title: NetworkType represents the network type of the chain chainsReceiveStatus: type: string enum: - - Created - - Success - - Failed - default: Created - title: '- Created: some observer sees inbound tx' + - created + - success + - failed + default: created + title: '- created: some observer sees inbound tx' + chainsVm: + type: string + enum: + - no_vm + - evm + default: no_vm + title: Vm represents the virtual machine type of the chain to support smart contracts coinCoinType: type: string enum: diff --git a/e2e/e2etests/test_bitcoin_withdraw.go b/e2e/e2etests/test_bitcoin_withdraw.go index cfb43eb72d..18efc44a40 100644 --- a/e2e/e2etests/test_bitcoin_withdraw.go +++ b/e2e/e2etests/test_bitcoin_withdraw.go @@ -132,12 +132,12 @@ func parseBitcoinWithdrawArgs(args []string, defaultReceiver string) (btcutil.Ad var receiver btcutil.Address if args[0] == "" { // use the default receiver - receiver, err = chains.DecodeBtcAddress(defaultReceiver, chains.BtcRegtestChain().ChainId) + receiver, err = chains.DecodeBtcAddress(defaultReceiver, chains.BtcRegtestChain.ChainId) if err != nil { panic("Invalid default receiver address specified for TestBitcoinWithdraw.") } } else { - receiver, err = chains.DecodeBtcAddress(args[0], chains.BtcRegtestChain().ChainId) + receiver, err = chains.DecodeBtcAddress(args[0], chains.BtcRegtestChain.ChainId) if err != nil { panic("Invalid receiver address specified for TestBitcoinWithdraw.") } @@ -224,7 +224,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) func withdrawBitcoinRestricted(r *runner.E2ERunner, amount *big.Int) { // use restricted BTC P2WPKH address - addressRestricted, err := chains.DecodeBtcAddress(testutils.RestrictedBtcAddressTest, chains.BtcRegtestChain().ChainId) + addressRestricted, err := chains.DecodeBtcAddress(testutils.RestrictedBtcAddressTest, chains.BtcRegtestChain.ChainId) if err != nil { panic(err) } @@ -246,7 +246,7 @@ func withdrawBitcoinRestricted(r *runner.E2ERunner, amount *big.Int) { // amount := big.NewInt(int64(0.1 * 1e8 / float64(repeat))) // // // check if the deposit is successful -// BTCZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.BtcRegtestChain().ChainId)) +// BTCZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.BtcRegtestChain.ChainId)) // if err != nil { // panic(err) // } diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 75bdb29d0e..48fc90be73 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -30,7 +30,7 @@ const EVM2RPCURL = "http://eth2:8545" // EVM2ChainID is the chain ID for the additional EVM localnet // We set Sepolia testnet although the value is not important, only used to differentiate -var EVM2ChainID = chains.SepoliaChain().ChainId +var EVM2ChainID = chains.SepoliaChain.ChainId func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // deposit most of the ZETA supply on ZetaChain @@ -170,7 +170,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { res, err := newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, crosschaintypes.NewMsgWhitelistERC20( adminAddr, newRunner.ERC20Addr.Hex(), - chains.SepoliaChain().ChainId, + chains.SepoliaChain.ChainId, "USDT", "USDT", 18, diff --git a/e2e/e2etests/test_zeta_withdraw.go b/e2e/e2etests/test_zeta_withdraw.go index 6dfc664813..add49af587 100644 --- a/e2e/e2etests/test_zeta_withdraw.go +++ b/e2e/e2etests/test_zeta_withdraw.go @@ -134,7 +134,7 @@ func TestZetaWithdrawBTCRevert(r *runner.E2ERunner, args []string) { lessThanAmount := amount.Div(amount, big.NewInt(10)) // 1/10 of amount tx, err = r.ConnectorZEVM.Send(r.ZEVMAuth, connectorzevm.ZetaInterfacesSendInput{ - DestinationChainId: big.NewInt(chains.BtcRegtestChain().ChainId), + DestinationChainId: big.NewInt(chains.BtcRegtestChain.ChainId), DestinationAddress: r.DeployerAddress.Bytes(), DestinationGasLimit: big.NewInt(400_000), Message: nil, diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 4bb8d5e46c..5f9895023f 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -393,7 +393,7 @@ func (runner *E2ERunner) ProveBTCTransaction(txHash *chainhash.Hash) { // verify merkle proof through RPC res, err := runner.LightclientClient.Prove(runner.Ctx, &lightclienttypes.QueryProveRequest{ - ChainId: chains.BtcRegtestChain().ChainId, + ChainId: chains.BtcRegtestChain.ChainId, TxHash: txHash.String(), BlockHash: blockHash.String(), Proof: proofs.NewBitcoinProof(txBytes, path, index), diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index 0bc6d77070..afe5222eb7 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -248,7 +248,7 @@ func (runner *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { TxIndex: int64(txIndex), TxHash: txHash.Hex(), Proof: proofs.NewEthereumProof(txProof), - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, }) if err != nil { panic(err) diff --git a/e2e/runner/setup_zeta.go b/e2e/runner/setup_zeta.go index e332f98af9..4213173ed7 100644 --- a/e2e/runner/setup_zeta.go +++ b/e2e/runner/setup_zeta.go @@ -184,7 +184,7 @@ func (runner *E2ERunner) SetZEVMContracts() { // SetupETHZRC20 sets up the ETH ZRC20 in the runner from the values queried from the chain func (runner *E2ERunner) SetupETHZRC20() { - ethZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chains.GoerliLocalnetChain().ChainId)) + ethZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chains.GoerliLocalnetChain.ChainId)) if err != nil { panic(err) } @@ -201,7 +201,7 @@ func (runner *E2ERunner) SetupETHZRC20() { // SetupBTCZRC20 sets up the BTC ZRC20 in the runner from the values queried from the chain func (runner *E2ERunner) SetupBTCZRC20() { - BTCZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chains.BtcRegtestChain().ChainId)) + BTCZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(chains.BtcRegtestChain.ChainId)) if err != nil { panic(err) } diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index d6d804c81e..8014bd2b48 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -327,7 +327,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) _, err = zts.BroadcastTx(account, fungibletypes.NewMsgDeployFungibleCoinZRC20( addr.String(), "", - chains.GoerliLocalnetChain().ChainId, + chains.GoerliLocalnetChain.ChainId, 18, "ETH", "gETH", @@ -342,7 +342,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) _, err = zts.BroadcastTx(account, fungibletypes.NewMsgDeployFungibleCoinZRC20( addr.String(), "", - chains.BtcRegtestChain().ChainId, + chains.BtcRegtestChain.ChainId, 8, "BTC", "tBTC", @@ -357,7 +357,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, erc20Addr string) res, err = zts.BroadcastTx(account, fungibletypes.NewMsgDeployFungibleCoinZRC20( addr.String(), erc20Addr, - chains.GoerliLocalnetChain().ChainId, + chains.GoerliLocalnetChain.ChainId, 6, "USDT", "USDT", diff --git a/pkg/chains/address_test.go b/pkg/chains/address_test.go index bc9e8d8171..c4535e07db 100644 --- a/pkg/chains/address_test.go +++ b/pkg/chains/address_test.go @@ -35,7 +35,7 @@ func TestAddress(t *testing.T) { func TestDecodeBtcAddress(t *testing.T) { t.Run("invalid string", func(t *testing.T) { - _, err := DecodeBtcAddress("�U�ڷ���i߭����꿚�l", BtcTestNetChain().ChainId) + _, err := DecodeBtcAddress("�U�ڷ���i߭����꿚�l", BtcTestNetChain.ChainId) require.ErrorContains(t, err, "runtime error: index out of range") }) t.Run("invalid chain", func(t *testing.T) { @@ -43,42 +43,42 @@ func TestDecodeBtcAddress(t *testing.T) { require.ErrorContains(t, err, "is not a bitcoin chain") }) t.Run("invalid checksum", func(t *testing.T) { - _, err := DecodeBtcAddress("tb1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcTestNetChain().ChainId) + _, err := DecodeBtcAddress("tb1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcTestNetChain.ChainId) require.ErrorContains(t, err, "invalid checksum") }) t.Run("valid legacy main-net address address incorrect params TestNet", func(t *testing.T) { - _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcTestNetChain().ChainId) + _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcTestNetChain.ChainId) require.ErrorContains(t, err, "decode address failed") }) t.Run("valid legacy main-net address address incorrect params RegTestNet", func(t *testing.T) { - _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcRegtestChain().ChainId) + _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcRegtestChain.ChainId) require.ErrorContains(t, err, "decode address failed") }) t.Run("valid legacy main-net address address correct params", func(t *testing.T) { - _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcMainnetChain().ChainId) + _, err := DecodeBtcAddress("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", BtcMainnetChain.ChainId) require.NoError(t, err) }) t.Run("valid legacy testnet address with correct params", func(t *testing.T) { - _, err := DecodeBtcAddress("n2TCLD16i8SNjwPCcgGBkTEeG6CQAcYTN1", BtcTestNetChain().ChainId) + _, err := DecodeBtcAddress("n2TCLD16i8SNjwPCcgGBkTEeG6CQAcYTN1", BtcTestNetChain.ChainId) require.NoError(t, err) }) t.Run("non legacy valid address with incorrect params", func(t *testing.T) { - _, err := DecodeBtcAddress("bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcMainnetChain().ChainId) + _, err := DecodeBtcAddress("bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcMainnetChain.ChainId) require.ErrorContains(t, err, "not for network mainnet") }) t.Run("non legacy valid address with correct params", func(t *testing.T) { - _, err := DecodeBtcAddress("bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcRegtestChain().ChainId) + _, err := DecodeBtcAddress("bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", BtcRegtestChain.ChainId) require.NoError(t, err) }) t.Run("taproot address with correct params", func(t *testing.T) { - _, err := DecodeBtcAddress("bc1p4ur084x8y63mj5hj7eydscuc4awals7ly749x8vhyquc0twcmvhquspa5c", BtcMainnetChain().ChainId) + _, err := DecodeBtcAddress("bc1p4ur084x8y63mj5hj7eydscuc4awals7ly749x8vhyquc0twcmvhquspa5c", BtcMainnetChain.ChainId) require.NoError(t, err) }) t.Run("taproot address with incorrect params", func(t *testing.T) { - _, err := DecodeBtcAddress("bc1p4ur084x8y63mj5hj7eydscuc4awals7ly749x8vhyquc0twcmvhquspa5c", BtcTestNetChain().ChainId) + _, err := DecodeBtcAddress("bc1p4ur084x8y63mj5hj7eydscuc4awals7ly749x8vhyquc0twcmvhquspa5c", BtcTestNetChain.ChainId) require.ErrorContains(t, err, "not for network testnet") }) } @@ -94,20 +94,20 @@ func Test_IsBtcAddressSupported_P2TR(t *testing.T) { // https://mempool.space/tx/259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7 name: "mainnet taproot address", addr: "bc1p4scddlkkuw9486579autxumxmkvuphm5pz4jvf7f6pdh50p2uzqstawjt9", - chainId: BtcMainnetChain().ChainId, + chainId: BtcMainnetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/24991bd2fdc4f744bf7bbd915d4915925eecebdae249f81e057c0a6ffb700ab9 name: "testnet taproot address", addr: "tb1p7qqaucx69xtwkx7vwmhz03xjmzxxpy3hk29y7q06mt3k6a8sehhsu5lacw", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { name: "regtest taproot address", addr: "bcrt1pqqqsyqcyq5rqwzqfpg9scrgwpugpzysnzs23v9ccrydpk8qarc0sj9hjuh", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, } @@ -138,20 +138,20 @@ func Test_IsBtcAddressSupported_P2WSH(t *testing.T) { // https://mempool.space/tx/791bb9d16f7ab05f70a116d18eaf3552faf77b9d5688699a480261424b4f7e53 name: "mainnet P2WSH address", addr: "bc1qqv6pwn470vu0tssdfha4zdk89v3c8ch5lsnyy855k9hcrcv3evequdmjmc", - chainId: BtcMainnetChain().ChainId, + chainId: BtcMainnetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/78fac3f0d4c0174c88d21c4bb1e23a8f007e890c6d2cfa64c97389ead16c51ed name: "testnet P2WSH address", addr: "tb1quhassyrlj43qar0mn0k5sufyp6mazmh2q85lr6ex8ehqfhxpzsksllwrsu", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { name: "regtest P2WSH address", addr: "bcrt1qm9mzhyky4w853ft2ms6dtqdyyu3z2tmrq8jg8xglhyuv0dsxzmgs2f0sqy", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, } @@ -181,20 +181,20 @@ func Test_IsBtcAddressSupported_P2WPKH(t *testing.T) { // https://mempool.space/tx/5d09d232bfe41c7cb831bf53fc2e4029ab33a99087fd5328a2331b52ff2ebe5b name: "mainnet P2WPKH address", addr: "bc1qaxf82vyzy8y80v000e7t64gpten7gawewzu42y", - chainId: BtcMainnetChain().ChainId, + chainId: BtcMainnetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/508b4d723c754bad001eae9b7f3c12377d3307bd5b595c27fd8a90089094f0e9 name: "testnet P2WPKH address", addr: "tb1q6rufg6myrxurdn0h57d2qhtm9zfmjw2mzcm05q", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { name: "regtest P2WPKH address", addr: "bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, } @@ -224,33 +224,33 @@ func Test_IsBtcAddressSupported_P2SH(t *testing.T) { // https://mempool.space/tx/fd68c8b4478686ca6f5ae4c28eaab055490650dbdaa6c2c8e380a7e075958a21 name: "mainnet P2SH address", addr: "327z4GyFM8Y8DiYfasGKQWhRK4MvyMSEgE", - chainId: BtcMainnetChain().ChainId, + chainId: BtcMainnetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/0c8c8f94817e0288a5273f5c971adaa3cee18a895c3ec8544785dddcd96f3848 name: "testnet P2SH address 1", addr: "2N6AoUj3KPS7wNGZXuCckh8YEWcSYNsGbqd", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/b5e074c5e021fcbd91ea14b1db29dfe5d14e1a6e046039467bf6ada7f8cc01b3 name: "testnet P2SH address 2", addr: "2MwbFpRpZWv4zREjbdLB9jVW3Q8xonpVeyE", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { name: "testnet P2SH address 1 should also be supported in regtest", addr: "2N6AoUj3KPS7wNGZXuCckh8YEWcSYNsGbqd", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, { name: "testnet P2SH address 2 should also be supported in regtest", addr: "2MwbFpRpZWv4zREjbdLB9jVW3Q8xonpVeyE", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, } @@ -280,33 +280,33 @@ func Test_IsBtcAddressSupported_P2PKH(t *testing.T) { // https://mempool.space/tx/9c741de6e17382b7a9113fc811e3558981a35a360e3d1262a6675892c91322ca name: "mainnet P2PKH address 1", addr: "1FueivsE338W2LgifJ25HhTcVJ7CRT8kte", - chainId: BtcMainnetChain().ChainId, + chainId: BtcMainnetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/1e3974386f071de7f65cabb57346c1a22ec9b3e211a96928a98149673f681237 name: "testnet P2PKH address 1", addr: "mxpYha3UJKUgSwsAz2qYRqaDSwAkKZ3YEY", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { // https://mempool.space/testnet/tx/e48459f372727f2253b0ea8c71ded83e8270873b8a044feb3435fc7a799a648f name: "testnet P2PKH address 2", addr: "n1gXcqxmzwqHmqmgobe1XXuJaweSu69tZz", - chainId: BtcTestNetChain().ChainId, + chainId: BtcTestNetChain.ChainId, supported: true, }, { name: "testnet P2PKH address should also be supported in regtest", addr: "mxpYha3UJKUgSwsAz2qYRqaDSwAkKZ3YEY", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, { name: "testnet P2PKH address should also be supported in regtest", addr: "n1gXcqxmzwqHmqmgobe1XXuJaweSu69tZz", - chainId: BtcRegtestChain().ChainId, + chainId: BtcRegtestChain.ChainId, supported: true, }, } diff --git a/pkg/chains/bitcoin.go b/pkg/chains/bitcoin.go index 42f5ee7db2..0492a5cd32 100644 --- a/pkg/chains/bitcoin.go +++ b/pkg/chains/bitcoin.go @@ -15,11 +15,11 @@ var ( // BitcoinNetParamsFromChainID returns the bitcoin net params to be used from the chain id func BitcoinNetParamsFromChainID(chainID int64) (*chaincfg.Params, error) { switch chainID { - case BtcRegtestChain().ChainId: + case BtcRegtestChain.ChainId: return BitcoinRegnetParams, nil - case BtcMainnetChain().ChainId: + case BtcMainnetChain.ChainId: return BitcoinMainnetParams, nil - case BtcTestNetChain().ChainId: + case BtcTestNetChain.ChainId: return BitcoinTestnetParams, nil default: return nil, fmt.Errorf("no Bitcoin net params for chain ID: %d", chainID) @@ -28,10 +28,10 @@ func BitcoinNetParamsFromChainID(chainID int64) (*chaincfg.Params, error) { // IsBitcoinRegnet returns true if the chain id is for the regnet func IsBitcoinRegnet(chainID int64) bool { - return chainID == BtcRegtestChain().ChainId + return chainID == BtcRegtestChain.ChainId } // IsBitcoinMainnet returns true if the chain id is for the mainnet func IsBitcoinMainnet(chainID int64) bool { - return chainID == BtcMainnetChain().ChainId + return chainID == BtcMainnetChain.ChainId } diff --git a/pkg/chains/bitcoin_test.go b/pkg/chains/bitcoin_test.go index 042cc6acaa..c1c1ff2852 100644 --- a/pkg/chains/bitcoin_test.go +++ b/pkg/chains/bitcoin_test.go @@ -14,9 +14,9 @@ func TestBitcoinNetParamsFromChainID(t *testing.T) { expected *chaincfg.Params wantErr bool }{ - {"Regnet", BtcRegtestChain().ChainId, BitcoinRegnetParams, false}, - {"Mainnet", BtcMainnetChain().ChainId, BitcoinMainnetParams, false}, - {"Testnet", BtcTestNetChain().ChainId, BitcoinTestnetParams, false}, + {"Regnet", BtcRegtestChain.ChainId, BitcoinRegnetParams, false}, + {"Mainnet", BtcMainnetChain.ChainId, BitcoinMainnetParams, false}, + {"Testnet", BtcTestNetChain.ChainId, BitcoinTestnetParams, false}, {"Unknown", -1, nil, true}, } @@ -34,13 +34,13 @@ func TestBitcoinNetParamsFromChainID(t *testing.T) { } func TestIsBitcoinRegnet(t *testing.T) { - require.True(t, IsBitcoinRegnet(BtcRegtestChain().ChainId)) - require.False(t, IsBitcoinRegnet(BtcMainnetChain().ChainId)) - require.False(t, IsBitcoinRegnet(BtcTestNetChain().ChainId)) + require.True(t, IsBitcoinRegnet(BtcRegtestChain.ChainId)) + require.False(t, IsBitcoinRegnet(BtcMainnetChain.ChainId)) + require.False(t, IsBitcoinRegnet(BtcTestNetChain.ChainId)) } func TestIsBitcoinMainnet(t *testing.T) { - require.True(t, IsBitcoinMainnet(BtcMainnetChain().ChainId)) - require.False(t, IsBitcoinMainnet(BtcRegtestChain().ChainId)) - require.False(t, IsBitcoinMainnet(BtcTestNetChain().ChainId)) + require.True(t, IsBitcoinMainnet(BtcMainnetChain.ChainId)) + require.False(t, IsBitcoinMainnet(BtcRegtestChain.ChainId)) + require.False(t, IsBitcoinMainnet(BtcTestNetChain.ChainId)) } diff --git a/pkg/chains/chain.go b/pkg/chains/chain.go index b86d54a176..77adc70119 100644 --- a/pkg/chains/chain.go +++ b/pkg/chains/chain.go @@ -20,10 +20,10 @@ func (chain Chain) IsEqual(c Chain) bool { } func (chain Chain) IsZetaChain() bool { - return chain.InChainList(ZetaChainList()) + return chain.Network == Network_zeta } func (chain Chain) IsExternalChain() bool { - return !chain.InChainList(ZetaChainList()) + return chain.IsExternal } // EncodeAddress bytes representations of address @@ -81,36 +81,29 @@ func DecodeAddressFromChainID(chainID int64, addr string) ([]byte, error) { return nil, fmt.Errorf("chain (%d) not supported", chainID) } -func IsZetaChain(chainID int64) bool { - return ChainIDInChainList(chainID, ZetaChainList()) +// IsEVMChain returns true if the chain is an EVM chain or uses the ethereum consensus mechanism for block finality +func IsEVMChain(chainID int64) bool { + return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_ethereum)) } -// IsEVMChain returns true if the chain is an EVM chain -// TODO: put this information directly in chain object -// https://github.com/zeta-chain/node-private/issues/63 -func IsEVMChain(chainID int64) bool { - return chainID == 5 || // Goerli - chainID == AmoyChain().ChainId || - chainID == SepoliaChain().ChainId || // Sepolia - chainID == 80001 || // Polygon mumbai - chainID == 97 || // BSC testnet - chainID == 1001 || // klaytn baobab - chainID == 1337 || // eth privnet - chainID == 1 || // eth mainnet - chainID == 56 || // bsc mainnet - chainID == 137 // polygon mainnet +// IsBitcoinChain returns true if the chain is a Bitcoin-based chain or uses the bitcoin consensus mechanism for block finality +func IsBitcoinChain(chainID int64) bool { + return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_bitcoin)) +} + +// IsEthereumChain returns true if the chain is an Ethereum chain +func IsEthereumChain(chainID int64) bool { + return ChainIDInChainList(chainID, ChainListByNetwork(Network_eth)) +} + +// IsZetaChain returns true if the chain is a Zeta chain +func IsZetaChain(chainID int64) bool { + return ChainIDInChainList(chainID, ChainListByNetwork(Network_zeta)) } // IsHeaderSupportedEvmChain returns true if the chain is an EVM chain supporting block header-based verification -// TODO: put this information directly in chain object -// https://github.com/zeta-chain/node-private/issues/63 func IsHeaderSupportedEvmChain(chainID int64) bool { - return chainID == 5 || // Goerli - chainID == SepoliaChain().ChainId || // Sepolia - chainID == 97 || // BSC testnet - chainID == 1337 || // eth privnet - chainID == 1 || // eth mainnet - chainID == 56 // bsc mainnet + return ChainIDInChainList(chainID, ChainListForHeaderSupport()) } // SupportMerkleProof returns true if the chain supports block header-based verification @@ -118,25 +111,6 @@ func (chain Chain) SupportMerkleProof() bool { return IsEVMChain(chain.ChainId) || IsBitcoinChain(chain.ChainId) } -// IsBitcoinChain returns true if the chain is a Bitcoin chain -// TODO: put this information directly in chain object -// https://github.com/zeta-chain/node-private/issues/63 -func IsBitcoinChain(chainID int64) bool { - return chainID == 18444 || // regtest - chainID == 18332 || //testnet - chainID == 8332 // mainnet -} - -// IsEthereumChain returns true if the chain is an Ethereum chain -// TODO: put this information directly in chain object -// https://github.com/zeta-chain/node-private/issues/63 -func IsEthereumChain(chainID int64) bool { - return chainID == 1 || // eth mainnet - chainID == 5 || // Goerli - chainID == SepoliaChain().ChainId || // Sepolia - chainID == 1337 // eth privnet -} - // IsEmpty is to determinate whether the chain is empty func (chain Chain) IsEmpty() bool { return strings.TrimSpace(chain.String()) == "" diff --git a/pkg/chains/chain_test.go b/pkg/chains/chain_test.go index 8d491d1780..69cc5418db 100644 --- a/pkg/chains/chain_test.go +++ b/pkg/chains/chain_test.go @@ -138,11 +138,11 @@ func TestChain_DecodeAddress(t *testing.T) { } func TestChain_InChainList(t *testing.T) { - require.True(t, ZetaChainMainnet().InChainList(ZetaChainList())) - require.True(t, ZetaMocknetChain().InChainList(ZetaChainList())) - require.True(t, ZetaPrivnetChain().InChainList(ZetaChainList())) - require.True(t, ZetaTestnetChain().InChainList(ZetaChainList())) - require.False(t, EthChain().InChainList(ZetaChainList())) + require.True(t, ZetaChainMainnet.InChainList(ChainListByNetwork(Network_zeta))) + require.True(t, ZetaMocknetChain.InChainList(ChainListByNetwork(Network_zeta))) + require.True(t, ZetaPrivnetChain.InChainList(ChainListByNetwork(Network_zeta))) + require.True(t, ZetaTestnetChain.InChainList(ChainListByNetwork(Network_zeta))) + require.False(t, EthChain.InChainList(ChainListByNetwork(Network_zeta))) } func TestIsZetaChain(t *testing.T) { @@ -151,11 +151,11 @@ func TestIsZetaChain(t *testing.T) { chainID int64 want bool }{ - {"Zeta Mainnet", ZetaChainMainnet().ChainId, true}, - {"Zeta Testnet", ZetaTestnetChain().ChainId, true}, - {"Zeta Mocknet", ZetaMocknetChain().ChainId, true}, - {"Zeta Privnet", ZetaPrivnetChain().ChainId, true}, - {"Non-Zeta", EthChain().ChainId, false}, + {"Zeta Mainnet", ZetaChainMainnet.ChainId, true}, + {"Zeta Testnet", ZetaTestnetChain.ChainId, true}, + {"Zeta Mocknet", ZetaMocknetChain.ChainId, true}, + {"Zeta Privnet", ZetaPrivnetChain.ChainId, true}, + {"Non-Zeta", EthChain.ChainId, false}, } for _, tt := range tests { @@ -171,11 +171,11 @@ func TestIsEVMChain(t *testing.T) { chainID int64 want bool }{ - {"Ethereum Mainnet", EthChain().ChainId, true}, - {"Goerli Testnet", GoerliChain().ChainId, true}, - {"Sepolia Testnet", SepoliaChain().ChainId, true}, - {"Non-EVM", BtcMainnetChain().ChainId, false}, - {"Zeta Mainnet", ZetaChainMainnet().ChainId, false}, + {"Ethereum Mainnet", EthChain.ChainId, true}, + {"Goerli Testnet", GoerliChain.ChainId, true}, + {"Sepolia Testnet", SepoliaChain.ChainId, true}, + {"Non-EVM", BtcMainnetChain.ChainId, false}, + {"Zeta Mainnet", ZetaChainMainnet.ChainId, false}, } for _, tt := range tests { @@ -191,14 +191,14 @@ func TestIsHeaderSupportedEVMChain(t *testing.T) { chainID int64 want bool }{ - {"Ethereum Mainnet", EthChain().ChainId, true}, - {"Goerli Testnet", GoerliChain().ChainId, true}, - {"Goerli Localnet", GoerliLocalnetChain().ChainId, true}, - {"Sepolia Testnet", SepoliaChain().ChainId, true}, - {"BSC Testnet", BscTestnetChain().ChainId, true}, - {"BSC Mainnet", BscMainnetChain().ChainId, true}, - {"Non-EVM", BtcMainnetChain().ChainId, false}, - {"Zeta Mainnet", ZetaChainMainnet().ChainId, false}, + {"Ethereum Mainnet", EthChain.ChainId, true}, + {"Goerli Testnet", GoerliChain.ChainId, true}, + {"Goerli Localnet", GoerliLocalnetChain.ChainId, true}, + {"Sepolia Testnet", SepoliaChain.ChainId, true}, + {"BSC Testnet", BscTestnetChain.ChainId, true}, + {"BSC Mainnet", BscMainnetChain.ChainId, true}, + {"Non-EVM", BtcMainnetChain.ChainId, false}, + {"Zeta Mainnet", ZetaChainMainnet.ChainId, false}, } for _, tt := range tests { @@ -214,11 +214,11 @@ func TestSupportMerkleProof(t *testing.T) { chain Chain want bool }{ - {"Ethereum Mainnet", EthChain(), true}, - {"BSC Testnet", BscTestnetChain(), true}, - {"BSC Mainnet", BscMainnetChain(), true}, - {"Non-EVM", BtcMainnetChain(), true}, - {"Zeta Mainnet", ZetaChainMainnet(), false}, + {"Ethereum Mainnet", EthChain, true}, + {"BSC Testnet", BscTestnetChain, true}, + {"BSC Mainnet", BscMainnetChain, true}, + {"Non-EVM", BtcMainnetChain, true}, + {"Zeta Mainnet", ZetaChainMainnet, false}, } for _, tt := range tests { @@ -234,11 +234,11 @@ func TestIsBitcoinChain(t *testing.T) { chainID int64 want bool }{ - {"Bitcoin Mainnet", BtcMainnetChain().ChainId, true}, - {"Bitcoin Testnet", BtcTestNetChain().ChainId, true}, - {"Bitcoin Regtest", BtcRegtestChain().ChainId, true}, - {"Non-Bitcoin", EthChain().ChainId, false}, - {"Zeta Mainnet", ZetaChainMainnet().ChainId, false}, + {"Bitcoin Mainnet", BtcMainnetChain.ChainId, true}, + {"Bitcoin Testnet", BtcTestNetChain.ChainId, true}, + {"Bitcoin Regtest", BtcRegtestChain.ChainId, true}, + {"Non-Bitcoin", EthChain.ChainId, false}, + {"Zeta Mainnet", ZetaChainMainnet.ChainId, false}, } for _, tt := range tests { @@ -254,11 +254,11 @@ func TestIsEthereumChain(t *testing.T) { chainID int64 want bool }{ - {"Ethereum Mainnet", EthChain().ChainId, true}, - {"Goerli Testnet", GoerliChain().ChainId, true}, - {"Sepolia Testnet", SepoliaChain().ChainId, true}, - {"Non-Ethereum", BtcMainnetChain().ChainId, false}, - {"Zeta Mainnet", ZetaChainMainnet().ChainId, false}, + {"Ethereum Mainnet", EthChain.ChainId, true}, + {"Goerli Testnet", GoerliChain.ChainId, true}, + {"Sepolia Testnet", SepoliaChain.ChainId, true}, + {"Non-Ethereum", BtcMainnetChain.ChainId, false}, + {"Zeta Mainnet", ZetaChainMainnet.ChainId, false}, } for _, tt := range tests { @@ -269,18 +269,18 @@ func TestIsEthereumChain(t *testing.T) { } func TestChain_IsExternalChain(t *testing.T) { - require.False(t, ZetaChainMainnet().IsExternalChain()) - require.True(t, EthChain().IsExternalChain()) + require.False(t, ZetaChainMainnet.IsExternalChain()) + require.True(t, EthChain.IsExternalChain()) } func TestChain_IsZetaChain(t *testing.T) { - require.True(t, ZetaChainMainnet().IsZetaChain()) - require.False(t, EthChain().IsZetaChain()) + require.True(t, ZetaChainMainnet.IsZetaChain()) + require.False(t, EthChain.IsZetaChain()) } func TestChain_IsEmpty(t *testing.T) { require.True(t, Chain{}.IsEmpty()) - require.False(t, ZetaChainMainnet().IsEmpty()) + require.False(t, ZetaChainMainnet.IsEmpty()) } func TestChain_WitnessProgram(t *testing.T) { @@ -296,7 +296,7 @@ func TestChain_WitnessProgram(t *testing.T) { addr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.RegressionNetParams) require.NoError(t, err) - chain := BtcTestNetChain() + chain := BtcTestNetChain _, err = chain.BTCAddressFromWitnessProgram(addr.WitnessProgram()) require.NoError(t, err) }) @@ -307,7 +307,7 @@ func TestChain_WitnessProgram(t *testing.T) { addr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.RegressionNetParams) require.NoError(t, err) - chain := GoerliChain() + chain := GoerliChain _, err = chain.BTCAddressFromWitnessProgram(addr.WitnessProgram()) require.Error(t, err) }) @@ -318,39 +318,39 @@ func TestChain_WitnessProgram(t *testing.T) { addr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, &chaincfg.RegressionNetParams) require.NoError(t, err) - chain := BtcTestNetChain() + chain := BtcTestNetChain _, err = chain.BTCAddressFromWitnessProgram(addr.WitnessProgram()[0:19]) require.Error(t, err) }) } func TestChains_Has(t *testing.T) { - chains := Chains{ZetaChainMainnet(), ZetaTestnetChain()} - require.True(t, chains.Has(ZetaChainMainnet())) - require.False(t, chains.Has(EthChain())) + chains := Chains{ZetaChainMainnet, ZetaTestnetChain} + require.True(t, chains.Has(ZetaChainMainnet)) + require.False(t, chains.Has(EthChain)) } func TestChains_Distinct(t *testing.T) { - chains := Chains{ZetaChainMainnet(), ZetaChainMainnet(), ZetaTestnetChain()} + chains := Chains{ZetaChainMainnet, ZetaChainMainnet, ZetaTestnetChain} distinctChains := chains.Distinct() require.Len(t, distinctChains, 2) } func TestChains_Strings(t *testing.T) { - chains := Chains{ZetaChainMainnet(), ZetaTestnetChain()} + chains := Chains{ZetaChainMainnet, ZetaTestnetChain} strings := chains.Strings() expected := []string{chains[0].String(), chains[1].String()} require.Equal(t, expected, strings) } func TestGetChainFromChainID(t *testing.T) { - chain := GetChainFromChainID(ZetaChainMainnet().ChainId) - require.Equal(t, ZetaChainMainnet(), *chain) + chain := GetChainFromChainID(ZetaChainMainnet.ChainId) + require.Equal(t, ZetaChainMainnet, *chain) require.Nil(t, GetChainFromChainID(9999)) } func TestGetBTCChainParams(t *testing.T) { - params, err := GetBTCChainParams(BtcMainnetChain().ChainId) + params, err := GetBTCChainParams(BtcMainnetChain.ChainId) require.NoError(t, err) require.Equal(t, &chaincfg.MainNetParams, params) @@ -376,6 +376,6 @@ func TestGetBTCChainIDFromChainParams(t *testing.T) { } func TestChainIDInChainList(t *testing.T) { - require.True(t, ChainIDInChainList(ZetaChainMainnet().ChainId, ZetaChainList())) - require.False(t, ChainIDInChainList(EthChain().ChainId, ZetaChainList())) + require.True(t, ChainIDInChainList(ZetaChainMainnet.ChainId, ChainListByNetwork(Network_zeta))) + require.False(t, ChainIDInChainList(EthChain.ChainId, ChainListByNetwork(Network_zeta))) } diff --git a/pkg/chains/chains.go b/pkg/chains/chains.go index 651051da3c..8a69e3ebf0 100644 --- a/pkg/chains/chains.go +++ b/pkg/chains/chains.go @@ -2,125 +2,193 @@ package chains import "fmt" -// Zeta chains +/* + Chain represents a blockchain network with its unique chain ID + ChainName is the name of the chain + ChainId is the unique identifier of the chain + Network is the network type of the chain , this can be ZETA, ETH, BSC, BTC, POLYGON + NetworkType is the network type of the chain, this can be MAINNET, TESTNET, DEVNET, PRIVNET + Vm is the virtual machine type of the chain to support smart contracts, this can be EVM, NO_VM + Consensus is the consensus algorithm used by the chain, this can be Tendermint, Ethereum, Bitcoin + IsExternal is a boolean value to determine if the chain is external to Zeta + IsHeaderSupported is a boolean value to determine if the chain supports headers -func ZetaChainMainnet() Chain { - return Chain{ - ChainName: ChainName_zeta_mainnet, - ChainId: 7000, - } -} + Note ChainName is normally NetworkName + NetworkType,but in some cases the value of NetworkName + NetworkType is not unique.This is true for chains which have been deprecated or have been renamed. + Such as GoerliChain and MumbaiChain which have been replaced by SepoliaChain and AmoyChain respectively. +*/ -func ZetaTestnetChain() Chain { - return Chain{ - ChainName: ChainName_zeta_testnet, - ChainId: 7001, - } -} +var ( -func ZetaMocknetChain() Chain { - return Chain{ - ChainName: ChainName_zeta_mainnet, - ChainId: 70000, + // Mainnet chains + ZetaChainMainnet = Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 7000, + Network: Network_zeta, + NetworkType: NetworkType_mainnet, + Vm: Vm_evm, + Consensus: Consensus_tendermint, + IsExternal: false, + IsHeaderSupported: false, } -} - -func ZetaPrivnetChain() Chain { - return Chain{ - ChainName: ChainName_zeta_mainnet, - ChainId: 101, + EthChain = Chain{ + ChainName: ChainName_eth_mainnet, + ChainId: 1, + Network: Network_eth, + NetworkType: NetworkType_mainnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} - -// Mainnet chains - -func EthChain() Chain { - return Chain{ - ChainName: ChainName_eth_mainnet, - ChainId: 1, + BscMainnetChain = Chain{ + ChainName: ChainName_bsc_mainnet, + ChainId: 56, + Network: Network_bsc, + NetworkType: NetworkType_mainnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} - -func BscMainnetChain() Chain { - return Chain{ - ChainName: ChainName_bsc_mainnet, - ChainId: 56, + BtcMainnetChain = Chain{ + ChainName: ChainName_btc_mainnet, + ChainId: 8332, + Network: Network_btc, + NetworkType: NetworkType_mainnet, + Vm: Vm_no_vm, + Consensus: Consensus_bitcoin, + IsExternal: true, + IsHeaderSupported: false, } -} - -func BtcMainnetChain() Chain { - return Chain{ - ChainName: ChainName_btc_mainnet, - ChainId: 8332, + PolygonChain = Chain{ + ChainName: ChainName_polygon_mainnet, + ChainId: 137, + Network: Network_polygon, + NetworkType: NetworkType_mainnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: false, } -} - -func PolygonChain() Chain { - return Chain{ - ChainName: ChainName_polygon_mainnet, - ChainId: 137, + // Testnet chains + ZetaTestnetChain = Chain{ + ChainName: ChainName_zeta_testnet, + ChainId: 7001, + Network: Network_zeta, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_tendermint, + IsExternal: false, + IsHeaderSupported: false, } -} - -// Testnet chains - -func SepoliaChain() Chain { - return Chain{ - ChainName: ChainName_sepolia_testnet, - ChainId: 11155111, + SepoliaChain = Chain{ + ChainName: ChainName_sepolia_testnet, + ChainId: 11155111, + Network: Network_eth, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} - -func GoerliChain() Chain { - return Chain{ - ChainName: ChainName_goerli_testnet, - ChainId: 5, + BscTestnetChain = Chain{ + ChainName: ChainName_bsc_testnet, + ChainId: 97, + Network: Network_bsc, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} - -func BscTestnetChain() Chain { - return Chain{ - ChainName: ChainName_bsc_testnet, - ChainId: 97, + BtcTestNetChain = Chain{ + ChainName: ChainName_btc_testnet, + ChainId: 18332, + Network: Network_btc, + NetworkType: NetworkType_testnet, + Vm: Vm_no_vm, + Consensus: Consensus_bitcoin, + IsExternal: true, + IsHeaderSupported: false, } -} -func BtcTestNetChain() Chain { - return Chain{ - ChainName: ChainName_btc_testnet, - ChainId: 18332, + AmoyChain = Chain{ + ChainName: ChainName_amoy_testnet, + ChainId: 80002, + Network: Network_polygon, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: false, } -} - -func MumbaiChain() Chain { - return Chain{ - ChainName: ChainName_mumbai_testnet, - ChainId: 80001, + // Devnet chains + ZetaMocknetChain = Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 70000, + Network: Network_zeta, + NetworkType: NetworkType_devnet, + Vm: Vm_evm, + Consensus: Consensus_tendermint, + IsExternal: false, + IsHeaderSupported: false, } -} - -func AmoyChain() Chain { - return Chain{ - ChainName: ChainName_amoy_testnet, - ChainId: 80002, + // Privnet chains + ZetaPrivnetChain = Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 101, + Network: Network_zeta, + NetworkType: NetworkType_privnet, + Vm: Vm_evm, + Consensus: Consensus_tendermint, + IsExternal: false, + IsHeaderSupported: false, } -} -// Privnet chains + BtcRegtestChain = Chain{ + ChainName: ChainName_btc_regtest, + ChainId: 18444, + Network: Network_btc, + NetworkType: NetworkType_privnet, + Vm: Vm_no_vm, + Consensus: Consensus_bitcoin, + IsExternal: true, + IsHeaderSupported: false, + } -func BtcRegtestChain() Chain { - return Chain{ - ChainName: ChainName_btc_regtest, - ChainId: 18444, + GoerliLocalnetChain = Chain{ + ChainName: ChainName_goerli_localnet, + ChainId: 1337, + Network: Network_eth, + NetworkType: NetworkType_privnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} -func GoerliLocalnetChain() Chain { - return Chain{ - ChainName: ChainName_goerli_localnet, - ChainId: 1337, + // Deprecated testnet chains + GoerliChain = Chain{ + ChainName: ChainName_goerli_testnet, + ChainId: 5, + Network: Network_eth, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: true, } -} + MumbaiChain = Chain{ + ChainName: ChainName_mumbai_testnet, + ChainId: 80001, + Network: Network_polygon, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_ethereum, + IsExternal: true, + IsHeaderSupported: false, + } +) func BtcDustOffset() int64 { return 2000 @@ -129,84 +197,81 @@ func BtcDustOffset() int64 { // DefaultChainsList returns a list of default chains func DefaultChainsList() []*Chain { return chainListPointers([]Chain{ - BtcMainnetChain(), - BscMainnetChain(), - EthChain(), - BtcTestNetChain(), - MumbaiChain(), - AmoyChain(), - BscTestnetChain(), - GoerliChain(), - SepoliaChain(), - BtcRegtestChain(), - GoerliLocalnetChain(), - ZetaChainMainnet(), - ZetaTestnetChain(), - ZetaMocknetChain(), - ZetaPrivnetChain(), + BtcMainnetChain, + BscMainnetChain, + EthChain, + BtcTestNetChain, + MumbaiChain, + AmoyChain, + BscTestnetChain, + GoerliChain, + SepoliaChain, + BtcRegtestChain, + GoerliLocalnetChain, + ZetaChainMainnet, + ZetaTestnetChain, + ZetaMocknetChain, + ZetaPrivnetChain, + PolygonChain, }) } -// MainnetChainList returns a list of mainnet chains -func MainnetChainList() []*Chain { - return chainListPointers([]Chain{ - ZetaChainMainnet(), - BtcMainnetChain(), - BscMainnetChain(), - EthChain(), - }) -} - -// TestnetChainList returns a list of testnet chains -func TestnetChainList() []*Chain { - return chainListPointers([]Chain{ - ZetaTestnetChain(), - BtcTestNetChain(), - MumbaiChain(), - AmoyChain(), - BscTestnetChain(), - GoerliChain(), - SepoliaChain(), - }) +// ChainListByNetworkType returns a list of chains by network type +func ChainListByNetworkType(networkType NetworkType) []*Chain { + var chainList []*Chain + for _, chain := range DefaultChainsList() { + if chain.NetworkType == networkType { + chainList = append(chainList, chain) + } + } + return chainList } -// PrivnetChainList returns a list of privnet chains -func PrivnetChainList() []*Chain { - return chainListPointers([]Chain{ - ZetaPrivnetChain(), - BtcRegtestChain(), - GoerliLocalnetChain(), - }) +// ChainListByNetwork returns a list of chains by network +func ChainListByNetwork(network Network) []*Chain { + var chainList []*Chain + for _, chain := range DefaultChainsList() { + if chain.Network == network { + chainList = append(chainList, chain) + } + } + return chainList } // ExternalChainList returns a list chains that are not Zeta func ExternalChainList() []*Chain { - return chainListPointers([]Chain{ - BtcMainnetChain(), - BscMainnetChain(), - EthChain(), - BtcTestNetChain(), - MumbaiChain(), - AmoyChain(), - BscTestnetChain(), - GoerliChain(), - SepoliaChain(), - BtcRegtestChain(), - GoerliLocalnetChain(), - }) + var chainList []*Chain + for _, chain := range DefaultChainsList() { + if chain.IsExternal { + chainList = append(chainList, chain) + } + } + return chainList } -// ZetaChainList returns a list of Zeta chains -func ZetaChainList() []*Chain { - return chainListPointers([]Chain{ - ZetaChainMainnet(), - ZetaTestnetChain(), - ZetaMocknetChain(), - ZetaPrivnetChain(), - }) +// ChainListByConsensus returns a list of chains by consensus +func ChainListByConsensus(consensus Consensus) []*Chain { + var chainList []*Chain + for _, chain := range DefaultChainsList() { + if chain.Consensus == consensus { + chainList = append(chainList, chain) + } + } + return chainList +} + +// ChainListForHeaderSupport returns a list of chains that support headers +func ChainListForHeaderSupport() []*Chain { + var chainList []*Chain + for _, chain := range DefaultChainsList() { + if chain.IsHeaderSupported { + chainList = append(chainList, chain) + } + } + return chainList } -// ZetaChainFromChainID returns a ZetaChain chainobject from a Cosmos chain ID +// ZetaChainFromChainID returns a ZetaChain chain object from a Cosmos chain ID func ZetaChainFromChainID(chainID string) (Chain, error) { ethChainID, err := CosmosToEthChainID(chainID) if err != nil { @@ -214,19 +279,21 @@ func ZetaChainFromChainID(chainID string) (Chain, error) { } switch ethChainID { - case ZetaPrivnetChain().ChainId: - return ZetaPrivnetChain(), nil - case ZetaChainMainnet().ChainId: - return ZetaChainMainnet(), nil - case ZetaTestnetChain().ChainId: - return ZetaTestnetChain(), nil - case ZetaMocknetChain().ChainId: - return ZetaMocknetChain(), nil + case ZetaPrivnetChain.ChainId: + return ZetaPrivnetChain, nil + case ZetaChainMainnet.ChainId: + return ZetaChainMainnet, nil + case ZetaTestnetChain.ChainId: + return ZetaTestnetChain, nil + case ZetaMocknetChain.ChainId: + return ZetaMocknetChain, nil default: return Chain{}, fmt.Errorf("chain %d not found", ethChainID) } } +// TODO : https://github.com/zeta-chain/node/issues/2080 +// remove the usage of this function // chainListPointers returns a list of chain pointers func chainListPointers(chains []Chain) []*Chain { var c []*Chain diff --git a/pkg/chains/chains.pb.go b/pkg/chains/chains.pb.go index 27e8736dac..899548b4be 100644 --- a/pkg/chains/chains.pb.go +++ b/pkg/chains/chains.pb.go @@ -27,21 +27,21 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type ReceiveStatus int32 const ( - ReceiveStatus_Created ReceiveStatus = 0 - ReceiveStatus_Success ReceiveStatus = 1 - ReceiveStatus_Failed ReceiveStatus = 2 + ReceiveStatus_created ReceiveStatus = 0 + ReceiveStatus_success ReceiveStatus = 1 + ReceiveStatus_failed ReceiveStatus = 2 ) var ReceiveStatus_name = map[int32]string{ - 0: "Created", - 1: "Success", - 2: "Failed", + 0: "created", + 1: "success", + 2: "failed", } var ReceiveStatus_value = map[string]int32{ - "Created": 0, - "Success": 1, - "Failed": 2, + "created": 0, + "success": 1, + "failed": 2, } func (x ReceiveStatus) String() string { @@ -52,6 +52,7 @@ func (ReceiveStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor_37ad35e0488e8bbc, []int{0} } +// ChainName represents the name of the chain type ChainName int32 const ( @@ -122,9 +123,137 @@ func (ChainName) EnumDescriptor() ([]byte, []int) { return fileDescriptor_37ad35e0488e8bbc, []int{1} } +// Network represents the network type of the chain +type Network int32 + +const ( + Network_eth Network = 0 + Network_zeta Network = 1 + Network_btc Network = 2 + Network_polygon Network = 3 + Network_bsc Network = 4 +) + +var Network_name = map[int32]string{ + 0: "eth", + 1: "zeta", + 2: "btc", + 3: "polygon", + 4: "bsc", +} + +var Network_value = map[string]int32{ + "eth": 0, + "zeta": 1, + "btc": 2, + "polygon": 3, + "bsc": 4, +} + +func (x Network) String() string { + return proto.EnumName(Network_name, int32(x)) +} + +func (Network) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_37ad35e0488e8bbc, []int{2} +} + +// NetworkType represents the network type of the chain +type NetworkType int32 + +const ( + NetworkType_mainnet NetworkType = 0 + NetworkType_testnet NetworkType = 1 + NetworkType_privnet NetworkType = 2 + NetworkType_devnet NetworkType = 3 +) + +var NetworkType_name = map[int32]string{ + 0: "mainnet", + 1: "testnet", + 2: "privnet", + 3: "devnet", +} + +var NetworkType_value = map[string]int32{ + "mainnet": 0, + "testnet": 1, + "privnet": 2, + "devnet": 3, +} + +func (x NetworkType) String() string { + return proto.EnumName(NetworkType_name, int32(x)) +} + +func (NetworkType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_37ad35e0488e8bbc, []int{3} +} + +// Vm represents the virtual machine type of the chain to support smart contracts +type Vm int32 + +const ( + Vm_no_vm Vm = 0 + Vm_evm Vm = 1 +) + +var Vm_name = map[int32]string{ + 0: "no_vm", + 1: "evm", +} + +var Vm_value = map[string]int32{ + "no_vm": 0, + "evm": 1, +} + +func (x Vm) String() string { + return proto.EnumName(Vm_name, int32(x)) +} + +func (Vm) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_37ad35e0488e8bbc, []int{4} +} + +// Consensus represents the consensus algorithm used by the chain +type Consensus int32 + +const ( + Consensus_ethereum Consensus = 0 + Consensus_tendermint Consensus = 1 + Consensus_bitcoin Consensus = 2 +) + +var Consensus_name = map[int32]string{ + 0: "ethereum", + 1: "tendermint", + 2: "bitcoin", +} + +var Consensus_value = map[string]int32{ + "ethereum": 0, + "tendermint": 1, + "bitcoin": 2, +} + +func (x Consensus) String() string { + return proto.EnumName(Consensus_name, int32(x)) +} + +func (Consensus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_37ad35e0488e8bbc, []int{5} +} + type Chain struct { - ChainName ChainName `protobuf:"varint,1,opt,name=chain_name,json=chainName,proto3,enum=chains.ChainName" json:"chain_name,omitempty"` - ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ChainName ChainName `protobuf:"varint,1,opt,name=chain_name,json=chainName,proto3,enum=chains.ChainName" json:"chain_name,omitempty"` + ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Network Network `protobuf:"varint,3,opt,name=network,proto3,enum=chains.Network" json:"network,omitempty"` + NetworkType NetworkType `protobuf:"varint,4,opt,name=network_type,json=networkType,proto3,enum=chains.NetworkType" json:"network_type,omitempty"` + Vm Vm `protobuf:"varint,5,opt,name=vm,proto3,enum=chains.Vm" json:"vm,omitempty"` + Consensus Consensus `protobuf:"varint,6,opt,name=consensus,proto3,enum=chains.Consensus" json:"consensus,omitempty"` + IsExternal bool `protobuf:"varint,7,opt,name=is_external,json=isExternal,proto3" json:"is_external,omitempty"` + IsHeaderSupported bool `protobuf:"varint,8,opt,name=is_header_supported,json=isHeaderSupported,proto3" json:"is_header_supported,omitempty"` } func (m *Chain) Reset() { *m = Chain{} } @@ -174,41 +303,102 @@ func (m *Chain) GetChainId() int64 { return 0 } +func (m *Chain) GetNetwork() Network { + if m != nil { + return m.Network + } + return Network_eth +} + +func (m *Chain) GetNetworkType() NetworkType { + if m != nil { + return m.NetworkType + } + return NetworkType_mainnet +} + +func (m *Chain) GetVm() Vm { + if m != nil { + return m.Vm + } + return Vm_no_vm +} + +func (m *Chain) GetConsensus() Consensus { + if m != nil { + return m.Consensus + } + return Consensus_ethereum +} + +func (m *Chain) GetIsExternal() bool { + if m != nil { + return m.IsExternal + } + return false +} + +func (m *Chain) GetIsHeaderSupported() bool { + if m != nil { + return m.IsHeaderSupported + } + return false +} + func init() { proto.RegisterEnum("chains.ReceiveStatus", ReceiveStatus_name, ReceiveStatus_value) proto.RegisterEnum("chains.ChainName", ChainName_name, ChainName_value) + proto.RegisterEnum("chains.Network", Network_name, Network_value) + proto.RegisterEnum("chains.NetworkType", NetworkType_name, NetworkType_value) + proto.RegisterEnum("chains.Vm", Vm_name, Vm_value) + proto.RegisterEnum("chains.Consensus", Consensus_name, Consensus_value) proto.RegisterType((*Chain)(nil), "chains.Chain") } func init() { proto.RegisterFile("pkg/chains/chains.proto", fileDescriptor_37ad35e0488e8bbc) } var fileDescriptor_37ad35e0488e8bbc = []byte{ - // 396 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x92, 0x4f, 0x6f, 0xd3, 0x30, - 0x14, 0xc0, 0xe3, 0x6e, 0x6d, 0x97, 0xd7, 0xad, 0x35, 0x06, 0x89, 0xb1, 0x43, 0x34, 0x71, 0x1a, - 0x93, 0x68, 0x10, 0x1c, 0xb9, 0x51, 0x09, 0x89, 0x0b, 0x87, 0x8e, 0x13, 0x97, 0xca, 0x71, 0x9e, - 0x1c, 0x8b, 0x38, 0x8e, 0x12, 0x07, 0xa9, 0x7c, 0x0a, 0x3e, 0x04, 0x07, 0x3e, 0xca, 0x8e, 0x3b, - 0x72, 0x44, 0xed, 0x17, 0x99, 0xec, 0x2c, 0xce, 0x29, 0xef, 0xfd, 0xfc, 0x7b, 0x7f, 0x14, 0x1b, - 0x5e, 0xd6, 0x3f, 0x64, 0x2a, 0x0a, 0xae, 0xaa, 0xf6, 0xe9, 0xb3, 0xae, 0x1b, 0x63, 0x0d, 0x9b, - 0xf5, 0xd9, 0xd5, 0x0b, 0x69, 0xa4, 0xf1, 0x28, 0x75, 0x51, 0x7f, 0xfa, 0xfa, 0x1b, 0x4c, 0x37, - 0xee, 0x9c, 0xbd, 0x03, 0xf0, 0xe2, 0xae, 0xe2, 0x1a, 0x2f, 0xc9, 0x35, 0xb9, 0x59, 0xbe, 0x7f, - 0xb6, 0x7e, 0xea, 0xe4, 0x95, 0xaf, 0x5c, 0xe3, 0x36, 0x16, 0x43, 0xc8, 0x5e, 0xc1, 0x59, 0x5f, - 0xa1, 0xf2, 0xcb, 0xc9, 0x35, 0xb9, 0x39, 0xd9, 0xce, 0x7d, 0xfe, 0x25, 0xbf, 0xfd, 0x08, 0x17, - 0x5b, 0x14, 0xa8, 0x7e, 0xe2, 0x9d, 0xe5, 0xb6, 0x6b, 0xd9, 0x02, 0xe6, 0x9b, 0x06, 0xb9, 0xc5, - 0x9c, 0x46, 0x2e, 0xb9, 0xeb, 0x84, 0xc0, 0xb6, 0xa5, 0x84, 0x01, 0xcc, 0x3e, 0x73, 0x55, 0x62, - 0x4e, 0x27, 0x57, 0xa7, 0x7f, 0xff, 0x24, 0xe4, 0xf6, 0x7e, 0x02, 0x71, 0x18, 0xc8, 0x62, 0x98, - 0xa2, 0xae, 0xed, 0x9e, 0x46, 0x6c, 0x05, 0x0b, 0xb4, 0xc5, 0x4e, 0x73, 0x55, 0x55, 0x68, 0x29, - 0x61, 0x14, 0xce, 0x7f, 0xa1, 0xe5, 0x81, 0x4c, 0x9c, 0x92, 0x59, 0x11, 0xc0, 0x09, 0x7b, 0x0e, - 0xab, 0xda, 0x94, 0x7b, 0x69, 0xaa, 0x00, 0x4f, 0xbd, 0xd5, 0x8e, 0xd6, 0x94, 0x31, 0x58, 0x4a, - 0x83, 0x4d, 0xa9, 0x76, 0x16, 0x5b, 0xeb, 0xd8, 0xcc, 0x31, 0xdd, 0xe9, 0x8c, 0x8f, 0x6c, 0xee, - 0xba, 0x49, 0x5e, 0x71, 0x51, 0x60, 0x80, 0x67, 0x4e, 0xcc, 0xb8, 0xc9, 0x78, 0x16, 0x58, 0x3c, - 0x4c, 0x18, 0x00, 0x84, 0x55, 0x07, 0xb2, 0x18, 0x56, 0x1d, 0xc0, 0xb9, 0x6b, 0xde, 0x62, 0x6d, - 0x4a, 0x35, 0x5a, 0x17, 0x7e, 0x62, 0xbf, 0x59, 0x69, 0x04, 0x2f, 0x1d, 0x5c, 0x0e, 0xa5, 0x0d, - 0x4a, 0x27, 0xd2, 0x95, 0xeb, 0xce, 0xb5, 0xd9, 0x87, 0x3a, 0xda, 0xff, 0xca, 0x4f, 0x9b, 0xfb, - 0x43, 0x42, 0x1e, 0x0e, 0x09, 0xf9, 0x7f, 0x48, 0xc8, 0xef, 0x63, 0x12, 0x3d, 0x1c, 0x93, 0xe8, - 0xdf, 0x31, 0x89, 0xbe, 0xbf, 0x91, 0xca, 0x16, 0x5d, 0xb6, 0x16, 0x46, 0xa7, 0x6e, 0xb1, 0xb7, - 0xfe, 0xea, 0x7c, 0x28, 0x4c, 0x83, 0xe9, 0xf8, 0x9a, 0xb2, 0x99, 0x7f, 0x29, 0x1f, 0x1e, 0x03, - 0x00, 0x00, 0xff, 0xff, 0xda, 0x8f, 0xd7, 0xf3, 0x62, 0x02, 0x00, 0x00, + // 634 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x14, 0xc0, 0x9b, 0xf4, 0xff, 0x6b, 0xd7, 0x66, 0x1e, 0x12, 0x61, 0x87, 0x30, 0x71, 0xda, 0x26, + 0xd1, 0x22, 0x90, 0xb8, 0xc0, 0x05, 0x26, 0x10, 0x5c, 0x76, 0xc8, 0xd0, 0x0e, 0x5c, 0x22, 0x27, + 0x79, 0xa4, 0xd6, 0x6a, 0x3b, 0x8a, 0xdd, 0x42, 0xf9, 0x14, 0x7c, 0x08, 0x0e, 0x7c, 0x94, 0x1d, + 0x77, 0x41, 0xe2, 0x88, 0xb6, 0x2f, 0x82, 0xec, 0xc6, 0x29, 0xda, 0xa9, 0xcf, 0xbf, 0xf7, 0xf3, + 0xf3, 0x8b, 0xed, 0x1a, 0x1e, 0x96, 0x57, 0xc5, 0x3c, 0x5b, 0x50, 0x26, 0x54, 0xfd, 0x33, 0x2b, + 0x2b, 0xa9, 0x25, 0xe9, 0x6d, 0x47, 0x87, 0x0f, 0x0a, 0x59, 0x48, 0x8b, 0xe6, 0x26, 0xda, 0x66, + 0x9f, 0xfc, 0xf6, 0xa1, 0x7b, 0x66, 0x04, 0xf2, 0x0c, 0xc0, 0x9a, 0x89, 0xa0, 0x1c, 0x43, 0xef, + 0xc8, 0x3b, 0x9e, 0x3c, 0xdf, 0x9f, 0xd5, 0xa5, 0xac, 0x72, 0x4e, 0x39, 0xc6, 0xc3, 0xcc, 0x85, + 0xe4, 0x11, 0x0c, 0xb6, 0x33, 0x58, 0x1e, 0xfa, 0x47, 0xde, 0x71, 0x3b, 0xee, 0xdb, 0xf1, 0xc7, + 0x9c, 0x9c, 0x40, 0x5f, 0xa0, 0xfe, 0x2a, 0xab, 0xab, 0xb0, 0x6d, 0x2b, 0x4d, 0x5d, 0xa5, 0xf3, + 0x2d, 0x8e, 0x5d, 0x9e, 0xbc, 0x84, 0x71, 0x1d, 0x26, 0x7a, 0x53, 0x62, 0xd8, 0xb1, 0xfe, 0xc1, + 0x3d, 0xff, 0xd3, 0xa6, 0xc4, 0x78, 0x24, 0x76, 0x03, 0x72, 0x08, 0xfe, 0x9a, 0x87, 0x5d, 0x6b, + 0x83, 0xb3, 0x2f, 0x79, 0xec, 0xaf, 0x39, 0x99, 0xc3, 0x30, 0x93, 0x42, 0xa1, 0x50, 0x2b, 0x15, + 0xf6, 0xee, 0x7d, 0x8a, 0x4b, 0xc4, 0x3b, 0x87, 0x3c, 0x86, 0x11, 0x53, 0x09, 0x7e, 0xd3, 0x58, + 0x09, 0xba, 0x0c, 0xfb, 0x47, 0xde, 0xf1, 0x20, 0x06, 0xa6, 0xde, 0xd5, 0x84, 0xcc, 0xe0, 0x80, + 0xa9, 0x64, 0x81, 0x34, 0xc7, 0x2a, 0x51, 0xab, 0xb2, 0x94, 0x95, 0xc6, 0x3c, 0x1c, 0x58, 0x71, + 0x9f, 0xa9, 0x0f, 0x36, 0x73, 0xe1, 0x12, 0xa7, 0xaf, 0x60, 0x2f, 0xc6, 0x0c, 0xd9, 0x1a, 0x2f, + 0x34, 0xd5, 0x2b, 0x45, 0x46, 0xd0, 0xcf, 0x2a, 0xa4, 0x1a, 0xf3, 0xa0, 0x65, 0x06, 0x6a, 0x95, + 0x65, 0xa8, 0x54, 0xe0, 0x11, 0x80, 0xde, 0x17, 0xca, 0x96, 0x98, 0x07, 0xfe, 0x61, 0xe7, 0xd7, + 0xcf, 0xc8, 0x3b, 0xbd, 0xf6, 0x61, 0xd8, 0xec, 0x38, 0x19, 0x42, 0x17, 0x79, 0xa9, 0x37, 0x41, + 0x8b, 0x4c, 0x61, 0x84, 0x7a, 0x91, 0x70, 0xca, 0x84, 0x40, 0x1d, 0x78, 0x24, 0x80, 0xf1, 0x77, + 0xd4, 0xb4, 0x21, 0xbe, 0x51, 0x52, 0x9d, 0x35, 0xa0, 0x4d, 0x0e, 0x60, 0x5a, 0xca, 0xe5, 0xa6, + 0x90, 0xa2, 0x81, 0x1d, 0x6b, 0xa9, 0x9d, 0xd5, 0x25, 0x04, 0x26, 0x85, 0xc4, 0x6a, 0xc9, 0x12, + 0x8d, 0x4a, 0x1b, 0xd6, 0x33, 0x8c, 0xaf, 0x78, 0x4a, 0x77, 0xac, 0x6f, 0xaa, 0x15, 0x54, 0xd0, + 0x6c, 0x81, 0x0d, 0x1c, 0x18, 0x31, 0xa5, 0x32, 0xa5, 0x69, 0xc3, 0x86, 0x6e, 0x05, 0x07, 0xa0, + 0x69, 0xd5, 0x91, 0x91, 0x6b, 0xd5, 0x81, 0xb1, 0x29, 0xae, 0xb0, 0x94, 0x4b, 0xb6, 0xb3, 0xf6, + 0xec, 0x8a, 0xdb, 0xce, 0x96, 0x32, 0xa3, 0x4b, 0x03, 0x27, 0x6e, 0x6a, 0x85, 0x85, 0x11, 0x83, + 0xa9, 0xa9, 0x4e, 0xb9, 0xdc, 0x34, 0xf3, 0x82, 0x7a, 0x2b, 0xdf, 0x40, 0xbf, 0xbe, 0x41, 0xa4, + 0x0f, 0x6d, 0xd4, 0x8b, 0xa0, 0x45, 0x06, 0xd0, 0x31, 0x9d, 0x04, 0x9e, 0x41, 0xa9, 0xce, 0x02, + 0xdf, 0x1c, 0x48, 0xbd, 0x49, 0x41, 0xdb, 0x52, 0x95, 0x05, 0x9d, 0xba, 0xc4, 0x7b, 0x18, 0xfd, + 0x77, 0x09, 0x8d, 0xea, 0xb6, 0xcd, 0x1e, 0xa4, 0x5b, 0xd1, 0xb3, 0x45, 0x2a, 0xb6, 0xde, 0x9e, + 0x03, 0x40, 0x2f, 0x47, 0x1b, 0xb7, 0xeb, 0x3a, 0x11, 0xf8, 0x97, 0xdc, 0x9c, 0xa6, 0x90, 0xc9, + 0x9a, 0x07, 0x2d, 0xdb, 0xd0, 0x9a, 0x07, 0x5e, 0x9d, 0x7f, 0x0d, 0xc3, 0xe6, 0x6e, 0x92, 0x31, + 0x0c, 0x50, 0x2f, 0xb0, 0xc2, 0x95, 0x31, 0x27, 0x00, 0x1a, 0x45, 0x8e, 0x15, 0x67, 0xa2, 0x5e, + 0x29, 0x65, 0x3a, 0x93, 0x4c, 0xb8, 0x3b, 0xf3, 0xf6, 0xec, 0xfa, 0x36, 0xf2, 0x6e, 0x6e, 0x23, + 0xef, 0xef, 0x6d, 0xe4, 0xfd, 0xb8, 0x8b, 0x5a, 0x37, 0x77, 0x51, 0xeb, 0xcf, 0x5d, 0xd4, 0xfa, + 0x7c, 0x52, 0x30, 0xbd, 0x58, 0xa5, 0xb3, 0x4c, 0xf2, 0xb9, 0xf9, 0xee, 0xa7, 0xf6, 0x8f, 0x60, + 0xc3, 0x4c, 0x56, 0x38, 0xdf, 0x3d, 0x1c, 0x69, 0xcf, 0x3e, 0x0a, 0x2f, 0xfe, 0x05, 0x00, 0x00, + 0xff, 0xff, 0x2a, 0xc3, 0x74, 0x63, 0x4d, 0x04, 0x00, 0x00, } func (m *Chain) Marshal() (dAtA []byte, err error) { @@ -231,6 +421,46 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IsHeaderSupported { + i-- + if m.IsHeaderSupported { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if m.IsExternal { + i-- + if m.IsExternal { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + if m.Consensus != 0 { + i = encodeVarintChains(dAtA, i, uint64(m.Consensus)) + i-- + dAtA[i] = 0x30 + } + if m.Vm != 0 { + i = encodeVarintChains(dAtA, i, uint64(m.Vm)) + i-- + dAtA[i] = 0x28 + } + if m.NetworkType != 0 { + i = encodeVarintChains(dAtA, i, uint64(m.NetworkType)) + i-- + dAtA[i] = 0x20 + } + if m.Network != 0 { + i = encodeVarintChains(dAtA, i, uint64(m.Network)) + i-- + dAtA[i] = 0x18 + } if m.ChainId != 0 { i = encodeVarintChains(dAtA, i, uint64(m.ChainId)) i-- @@ -267,6 +497,24 @@ func (m *Chain) Size() (n int) { if m.ChainId != 0 { n += 1 + sovChains(uint64(m.ChainId)) } + if m.Network != 0 { + n += 1 + sovChains(uint64(m.Network)) + } + if m.NetworkType != 0 { + n += 1 + sovChains(uint64(m.NetworkType)) + } + if m.Vm != 0 { + n += 1 + sovChains(uint64(m.Vm)) + } + if m.Consensus != 0 { + n += 1 + sovChains(uint64(m.Consensus)) + } + if m.IsExternal { + n += 2 + } + if m.IsHeaderSupported { + n += 2 + } return n } @@ -343,6 +591,122 @@ func (m *Chain) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) + } + m.Network = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Network |= Network(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NetworkType", wireType) + } + m.NetworkType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NetworkType |= NetworkType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Vm", wireType) + } + m.Vm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Vm |= Vm(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Consensus", wireType) + } + m.Consensus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Consensus |= Consensus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsExternal", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsExternal = bool(v != 0) + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsHeaderSupported", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsHeaderSupported = bool(v != 0) default: iNdEx = preIndex skippy, err := skipChains(dAtA[iNdEx:]) diff --git a/pkg/chains/chains_test.go b/pkg/chains/chains_test.go index 51e22e85fd..9e1358ad48 100644 --- a/pkg/chains/chains_test.go +++ b/pkg/chains/chains_test.go @@ -1,6 +1,7 @@ package chains import ( + "sort" "testing" "github.com/stretchr/testify/require" @@ -9,53 +10,257 @@ import ( func TestChainRetrievalFunctions(t *testing.T) { tests := []struct { name string - function func() Chain + chain Chain expected Chain }{ - {"ZetaChainMainnet", ZetaChainMainnet, Chain{ChainName: ChainName_zeta_mainnet, ChainId: 7000}}, - {"ZetaTestnetChain", ZetaTestnetChain, Chain{ChainName: ChainName_zeta_testnet, ChainId: 7001}}, - {"ZetaMocknetChain", ZetaMocknetChain, Chain{ChainName: ChainName_zeta_mainnet, ChainId: 70000}}, - {"ZetaPrivnetChain", ZetaPrivnetChain, Chain{ChainName: ChainName_zeta_mainnet, ChainId: 101}}, - {"EthChain", EthChain, Chain{ChainName: ChainName_eth_mainnet, ChainId: 1}}, - {"BscMainnetChain", BscMainnetChain, Chain{ChainName: ChainName_bsc_mainnet, ChainId: 56}}, - {"BtcMainnetChain", BtcMainnetChain, Chain{ChainName: ChainName_btc_mainnet, ChainId: 8332}}, - {"PolygonChain", PolygonChain, Chain{ChainName: ChainName_polygon_mainnet, ChainId: 137}}, - {"SepoliaChain", SepoliaChain, Chain{ChainName: ChainName_sepolia_testnet, ChainId: 11155111}}, - {"GoerliChain", GoerliChain, Chain{ChainName: ChainName_goerli_testnet, ChainId: 5}}, - {"BscTestnetChain", BscTestnetChain, Chain{ChainName: ChainName_bsc_testnet, ChainId: 97}}, - {"BtcTestNetChain", BtcTestNetChain, Chain{ChainName: ChainName_btc_testnet, ChainId: 18332}}, - {"MumbaiChain", MumbaiChain, Chain{ChainName: ChainName_mumbai_testnet, ChainId: 80001}}, - {"AmoyChain", AmoyChain, Chain{ChainName: ChainName_amoy_testnet, ChainId: 80002}}, - {"BtcRegtestChain", BtcRegtestChain, Chain{ChainName: ChainName_btc_regtest, ChainId: 18444}}, - {"GoerliLocalnetChain", GoerliLocalnetChain, Chain{ChainName: ChainName_goerli_localnet, ChainId: 1337}}, + {"ZetaChainMainnet", ZetaChainMainnet, Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 7000, + Network: Network_zeta, + NetworkType: NetworkType_mainnet, + IsExternal: false, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_tendermint, + }, + }, + {"ZetaTestnetChain", ZetaTestnetChain, Chain{ + ChainName: ChainName_zeta_testnet, + ChainId: 7001, + Network: Network_zeta, + NetworkType: NetworkType_testnet, + IsExternal: false, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_tendermint, + }, + }, + {"ZetaMocknetChain", ZetaMocknetChain, Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 70000, + Network: Network_zeta, + NetworkType: NetworkType_devnet, + IsExternal: false, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_tendermint, + }}, + {"ZetaPrivnetChain", ZetaPrivnetChain, Chain{ + ChainName: ChainName_zeta_mainnet, + ChainId: 101, + Network: Network_zeta, + NetworkType: NetworkType_privnet, + IsExternal: false, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_tendermint, + }}, + {"EthChain", EthChain, Chain{ + ChainName: ChainName_eth_mainnet, + ChainId: 1, + Network: Network_eth, + NetworkType: NetworkType_mainnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, + {"BscMainnetChain", BscMainnetChain, Chain{ + ChainName: ChainName_bsc_mainnet, + ChainId: 56, + Network: Network_bsc, + NetworkType: NetworkType_mainnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, + {"BtcMainnetChain", BtcMainnetChain, Chain{ + ChainName: ChainName_btc_mainnet, + ChainId: 8332, + Network: Network_btc, + NetworkType: NetworkType_mainnet, + IsExternal: true, + Vm: Vm_no_vm, + IsHeaderSupported: false, + Consensus: Consensus_bitcoin, + }}, + {"PolygonChain", PolygonChain, Chain{ + ChainName: ChainName_polygon_mainnet, + ChainId: 137, + Network: Network_polygon, + NetworkType: NetworkType_mainnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_ethereum, + }}, + {"SepoliaChain", SepoliaChain, Chain{ + ChainName: ChainName_sepolia_testnet, + ChainId: 11155111, + Network: Network_eth, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, + {"GoerliChain", GoerliChain, Chain{ + ChainName: ChainName_goerli_testnet, + ChainId: 5, + Network: Network_eth, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, + {"AmoyChain", AmoyChain, Chain{ + ChainName: ChainName_amoy_testnet, + ChainId: 80002, + Network: Network_polygon, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_ethereum, + }}, + {"BscTestnetChain", BscTestnetChain, Chain{ + ChainName: ChainName_bsc_testnet, + ChainId: 97, + Network: Network_bsc, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, + {"MumbaiChain", MumbaiChain, Chain{ + ChainName: ChainName_mumbai_testnet, + ChainId: 80001, + Network: Network_polygon, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: false, + Consensus: Consensus_ethereum, + }}, + {"BtcTestNetChain", BtcTestNetChain, Chain{ + ChainName: ChainName_btc_testnet, + ChainId: 18332, + Network: Network_btc, + NetworkType: NetworkType_testnet, + IsExternal: true, + Vm: Vm_no_vm, + IsHeaderSupported: false, + Consensus: Consensus_bitcoin, + }}, + {"BtcRegtestChain", BtcRegtestChain, Chain{ + ChainName: ChainName_btc_regtest, + ChainId: 18444, + Network: Network_btc, + NetworkType: NetworkType_privnet, + IsExternal: true, + Vm: Vm_no_vm, + IsHeaderSupported: false, + Consensus: Consensus_bitcoin, + }}, + {"GoerliLocalnetChain", GoerliLocalnetChain, Chain{ + ChainName: ChainName_goerli_localnet, + ChainId: 1337, + Network: Network_eth, + NetworkType: NetworkType_privnet, + IsExternal: true, + Vm: Vm_evm, + IsHeaderSupported: true, + Consensus: Consensus_ethereum, + }}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - chain := tc.function() + chain := tc.chain require.Equal(t, tc.expected, chain) }) } } +func TestChainListByNetworkType(t *testing.T) { + listTests := []struct { + name string + networkType NetworkType + expected []Chain + }{ + {"MainnetChainList", NetworkType_mainnet, []Chain{ZetaChainMainnet, BtcMainnetChain, BscMainnetChain, EthChain, PolygonChain}}, + {"TestnetChainList", NetworkType_testnet, []Chain{ZetaTestnetChain, BtcTestNetChain, MumbaiChain, AmoyChain, BscTestnetChain, GoerliChain, SepoliaChain}}, + {"PrivnetChainList", NetworkType_privnet, []Chain{ZetaPrivnetChain, BtcRegtestChain, GoerliLocalnetChain}}, + } + + for _, lt := range listTests { + t.Run(lt.name, func(t *testing.T) { + chains := ChainListByNetworkType(lt.networkType) + require.Equal(t, len(lt.expected), len(chains)) + sort.Slice(chains, func(i, j int) bool { + return chains[i].ChainId < chains[j].ChainId + }) + sort.Slice(lt.expected, func(i, j int) bool { + return lt.expected[i].ChainId < lt.expected[j].ChainId + }) + for i, expectedChain := range lt.expected { + require.Equal(t, &expectedChain, chains[i]) + } + }) + } +} + +func TestChainListByNetwork(t *testing.T) { + listTests := []struct { + name string + network Network + expected []Chain + }{ + {"Zeta", Network_zeta, []Chain{ZetaChainMainnet, ZetaMocknetChain, ZetaPrivnetChain, ZetaTestnetChain}}, + {"Btc", Network_btc, []Chain{BtcMainnetChain, BtcTestNetChain, BtcRegtestChain}}, + {"Eth", Network_eth, []Chain{EthChain, GoerliChain, SepoliaChain, GoerliLocalnetChain}}, + {"Bsc", Network_bsc, []Chain{BscMainnetChain, BscTestnetChain}}, + {"Polygon", Network_polygon, []Chain{PolygonChain, MumbaiChain, AmoyChain}}, + } + for _, lt := range listTests { + t.Run(lt.name, func(t *testing.T) { + chains := ChainListByNetwork(lt.network) + require.Equal(t, len(lt.expected), len(chains)) + sort.Slice(chains, func(i, j int) bool { + return chains[i].ChainId < chains[j].ChainId + }) + sort.Slice(lt.expected, func(i, j int) bool { + return lt.expected[i].ChainId < lt.expected[j].ChainId + }) + for i, expectedChain := range lt.expected { + require.Equal(t, &expectedChain, chains[i]) + } + }) + } +} func TestChainListFunctions(t *testing.T) { listTests := []struct { name string function func() []*Chain expected []Chain }{ - {"DefaultChainsList", DefaultChainsList, []Chain{BtcMainnetChain(), BscMainnetChain(), EthChain(), BtcTestNetChain(), MumbaiChain(), AmoyChain(), BscTestnetChain(), GoerliChain(), SepoliaChain(), BtcRegtestChain(), GoerliLocalnetChain(), ZetaChainMainnet(), ZetaTestnetChain(), ZetaMocknetChain(), ZetaPrivnetChain()}}, - {"MainnetChainList", MainnetChainList, []Chain{ZetaChainMainnet(), BtcMainnetChain(), BscMainnetChain(), EthChain()}}, - {"TestnetChainList", TestnetChainList, []Chain{ZetaTestnetChain(), BtcTestNetChain(), MumbaiChain(), AmoyChain(), BscTestnetChain(), GoerliChain(), SepoliaChain()}}, - {"PrivnetChainList", PrivnetChainList, []Chain{ZetaPrivnetChain(), BtcRegtestChain(), GoerliLocalnetChain()}}, - {"ExternalChainList", ExternalChainList, []Chain{BtcMainnetChain(), BscMainnetChain(), EthChain(), BtcTestNetChain(), MumbaiChain(), AmoyChain(), BscTestnetChain(), GoerliChain(), SepoliaChain(), BtcRegtestChain(), GoerliLocalnetChain()}}, - {"ZetaChainList", ZetaChainList, []Chain{ZetaChainMainnet(), ZetaTestnetChain(), ZetaMocknetChain(), ZetaPrivnetChain()}}, + {"DefaultChainsList", DefaultChainsList, []Chain{BtcMainnetChain, BscMainnetChain, EthChain, BtcTestNetChain, MumbaiChain, AmoyChain, BscTestnetChain, GoerliChain, SepoliaChain, BtcRegtestChain, GoerliLocalnetChain, ZetaChainMainnet, ZetaTestnetChain, ZetaMocknetChain, ZetaPrivnetChain, PolygonChain}}, + {"ExternalChainList", ExternalChainList, []Chain{BtcMainnetChain, BscMainnetChain, EthChain, BtcTestNetChain, MumbaiChain, AmoyChain, BscTestnetChain, GoerliChain, SepoliaChain, BtcRegtestChain, GoerliLocalnetChain, PolygonChain}}, } for _, lt := range listTests { t.Run(lt.name, func(t *testing.T) { chains := lt.function() require.Equal(t, len(lt.expected), len(chains)) + sort.Slice(chains, func(i, j int) bool { + return chains[i].ChainId < chains[j].ChainId + }) + sort.Slice(lt.expected, func(i, j int) bool { + return lt.expected[i].ChainId < lt.expected[j].ChainId + }) for i, expectedChain := range lt.expected { require.Equal(t, &expectedChain, chains[i]) } @@ -73,25 +278,25 @@ func TestZetaChainFromChainID(t *testing.T) { { name: "ZetaChainMainnet", chainID: "cosmoshub_7000-1", - expected: ZetaChainMainnet(), + expected: ZetaChainMainnet, wantErr: false, }, { name: "ZetaTestnetChain", chainID: "cosmoshub_7001-1", - expected: ZetaTestnetChain(), + expected: ZetaTestnetChain, wantErr: false, }, { name: "ZetaMocknetChain", chainID: "cosmoshub_70000-1", - expected: ZetaMocknetChain(), + expected: ZetaMocknetChain, wantErr: false, }, { name: "ZetaPrivnetChain", chainID: "cosmoshub_101-1", - expected: ZetaPrivnetChain(), + expected: ZetaPrivnetChain, wantErr: false, }, { diff --git a/pkg/chains/status.go b/pkg/chains/status.go index 25140267f7..c74bcb2780 100644 --- a/pkg/chains/status.go +++ b/pkg/chains/status.go @@ -9,9 +9,9 @@ import "errors" func ReceiveStatusFromString(str string) (ReceiveStatus, error) { switch str { case "0": - return ReceiveStatus_Success, nil + return ReceiveStatus_success, nil case "1": - return ReceiveStatus_Failed, nil + return ReceiveStatus_failed, nil default: return ReceiveStatus(0), errors.New("wrong status, must be 0 for success or 1 for failed") } diff --git a/pkg/chains/status_test.go b/pkg/chains/status_test.go index 65f5e7e319..a26170f97c 100644 --- a/pkg/chains/status_test.go +++ b/pkg/chains/status_test.go @@ -17,13 +17,13 @@ func TestReceiveStatusFromString(t *testing.T) { { name: "success", str: "0", - want: chains.ReceiveStatus_Success, + want: chains.ReceiveStatus_success, wantErr: false, }, { name: "failed", str: "1", - want: chains.ReceiveStatus_Failed, + want: chains.ReceiveStatus_failed, wantErr: false, }, { diff --git a/pkg/crypto/pubkey_test.go b/pkg/crypto/pubkey_test.go index f86f07fcc0..c0b5a40e2c 100644 --- a/pkg/crypto/pubkey_test.go +++ b/pkg/crypto/pubkey_test.go @@ -132,21 +132,21 @@ func (s *PubKeyTestSuite) TestPubKeyGetAddress(c *C) { c.Assert(err, IsNil) c.Assert(os.Setenv("NET", "mainnet"), IsNil) - addrETH, err := pk.GetAddress(chains.GoerliChain()) + addrETH, err := pk.GetAddress(chains.GoerliChain) c.Assert(err, IsNil) c.Assert(addrETH.String(), Equals, d.addrETH.mainnet) c.Assert(os.Setenv("NET", "testnet"), IsNil) - addrETH, err = pk.GetAddress(chains.GoerliChain()) + addrETH, err = pk.GetAddress(chains.GoerliChain) c.Assert(err, IsNil) c.Assert(addrETH.String(), Equals, d.addrETH.testnet) c.Assert(os.Setenv("NET", "mocknet"), IsNil) - addrETH, err = pk.GetAddress(chains.GoerliChain()) + addrETH, err = pk.GetAddress(chains.GoerliChain) c.Assert(err, IsNil) c.Assert(addrETH.String(), Equals, d.addrETH.mocknet) - addrETH, err = pk.GetAddress(chains.BtcRegtestChain()) + addrETH, err = pk.GetAddress(chains.BtcRegtestChain) c.Assert(err, IsNil) c.Assert(addrETH, Equals, chains.NoAddress) } diff --git a/proto/observer/observer.proto b/proto/observer/observer.proto index 575eea04f1..b796a6705b 100644 --- a/proto/observer/observer.proto +++ b/proto/observer/observer.proto @@ -22,6 +22,7 @@ enum ObserverUpdateReason { AdminUpdate = 2; } +// Deprecated: Use ObserverSet instead to get the list of observers message ObserverMapper { string index = 1; chains.Chain observer_chain = 2; diff --git a/proto/pkg/chains/chains.proto b/proto/pkg/chains/chains.proto index 49305d4f16..1a11f504e1 100644 --- a/proto/pkg/chains/chains.proto +++ b/proto/pkg/chains/chains.proto @@ -7,11 +7,12 @@ option go_package = "github.com/zeta-chain/zetacore/pkg/chains"; enum ReceiveStatus { option (gogoproto.goproto_enum_stringer) = true; - Created = 0; // some observer sees inbound tx - Success = 1; - Failed = 2; + created = 0; // some observer sees inbound tx + success = 1; + failed = 2; } +// ChainName represents the name of the chain enum ChainName { option (gogoproto.goproto_enum_stringer) = true; empty = 0; @@ -34,7 +35,57 @@ enum ChainName { amoy_testnet = 16; } +// Network represents the network type of the chain +enum Network { + option (gogoproto.goproto_enum_stringer) = true; + eth = 0; + zeta = 1; + btc = 2; + polygon = 3; + bsc = 4; +} + +// NetworkType represents the network type of the chain +enum NetworkType { + option (gogoproto.goproto_enum_stringer) = true; + mainnet = 0; + testnet = 1; + privnet = 2; + devnet = 3; +} + +// Vm represents the virtual machine type of the chain to support smart contracts +enum Vm { + option (gogoproto.goproto_enum_stringer) = true; + no_vm = 0; + evm = 1; +} + +// Consensus represents the consensus algorithm used by the chain +enum Consensus { + option (gogoproto.goproto_enum_stringer) = true; + ethereum = 0; + tendermint = 1; + bitcoin = 2; +} + +// Chain represents a blockchain network with its unique chain ID +// ChainName is the name of the chain +// ChainId is the unique identifier of the chain +// Network is the network type of the chain , this can be ZETA, ETH, BSC, BTC, POLYGON +// NetworkType is the network type of the chain, this can be MAINNET, TESTNET, DEVNET, PRIVNET +// Vm is the virtual machine type of the chain to support smart contracts, this can be EVM, NO_VM +// Consensus is the consensus algorithm used by the chain, this can be Tendermint, Ethereum, Bitcoin +// IsExternal is a boolean value to determine if the chain is external to Zeta +// IsHeaderSupported is a boolean value to determine if the chain supports headers + message Chain { ChainName chain_name = 1; int64 chain_id = 2; + Network network = 3; + NetworkType network_type = 4; + Vm vm = 5; + Consensus consensus = 6; + bool is_external = 7; + bool is_header_supported = 8; } diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index 531af3c7b1..a2fd745edc 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -286,12 +286,12 @@ func MockRevertForHandleEVMDeposit(m *crosschainmocks.CrosschainFungibleKeeper, } func MockVoteOnOutboundSuccessBallot(m *crosschainmocks.CrosschainObserverKeeper, ctx sdk.Context, cctx *types.CrossChainTx, senderChain chains.Chain, observer string) { - m.On("VoteOnOutboundBallot", ctx, mock.Anything, cctx.GetCurrentOutTxParam().ReceiverChainId, chains.ReceiveStatus_Success, observer). + m.On("VoteOnOutboundBallot", ctx, mock.Anything, cctx.GetCurrentOutTxParam().ReceiverChainId, chains.ReceiveStatus_success, observer). Return(true, true, observertypes.Ballot{BallotStatus: observertypes.BallotStatus_BallotFinalized_SuccessObservation}, senderChain.ChainName.String(), nil).Once() } func MockVoteOnOutboundFailedBallot(m *crosschainmocks.CrosschainObserverKeeper, ctx sdk.Context, cctx *types.CrossChainTx, senderChain chains.Chain, observer string) { - m.On("VoteOnOutboundBallot", ctx, mock.Anything, cctx.GetCurrentOutTxParam().ReceiverChainId, chains.ReceiveStatus_Failed, observer). + m.On("VoteOnOutboundBallot", ctx, mock.Anything, cctx.GetCurrentOutTxParam().ReceiverChainId, chains.ReceiveStatus_failed, observer). Return(true, true, observertypes.Ballot{BallotStatus: observertypes.BallotStatus_BallotFinalized_FailureObservation}, senderChain.ChainName.String(), nil).Once() } diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index dfa3364cfe..4fb7f054bf 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -61,8 +61,9 @@ func SetupZetaGenesisState(t *testing.T, genesisState map[string]json.RawMessage } if setupChainNonces { - chainNonceList := make([]observertypes.ChainNonces, len(chains.PrivnetChainList())) - for i, chain := range chains.PrivnetChainList() { + privatenetChains := chains.ChainListByNetworkType(chains.NetworkType_privnet) + chainNonceList := make([]observertypes.ChainNonces, len(privatenetChains)) + for i, chain := range privatenetChains { chainNonceList[i] = observertypes.ChainNonces{ Index: chain.ChainName.String(), ChainId: chain.ChainId, diff --git a/testutil/sample/crosschain.go b/testutil/sample/crosschain.go index 5a0d8aafdb..03727a1b03 100644 --- a/testutil/sample/crosschain.go +++ b/testutil/sample/crosschain.go @@ -101,7 +101,7 @@ func InboundTxParams(r *rand.Rand) *types.InboundTxParams { func InboundTxParamsValidChainID(r *rand.Rand) *types.InboundTxParams { return &types.InboundTxParams{ Sender: EthAddress().String(), - SenderChainId: chains.GoerliChain().ChainId, + SenderChainId: chains.GoerliChain.ChainId, TxOrigin: EthAddress().String(), Asset: StringRandom(r, 32), Amount: math.NewUint(uint64(r.Int63())), @@ -132,7 +132,7 @@ func OutboundTxParams(r *rand.Rand) *types.OutboundTxParams { func OutboundTxParamsValidChainID(r *rand.Rand) *types.OutboundTxParams { return &types.OutboundTxParams{ Receiver: EthAddress().String(), - ReceiverChainId: chains.GoerliChain().ChainId, + ReceiverChainId: chains.GoerliChain.ChainId, Amount: math.NewUint(uint64(r.Int63())), OutboundTxTssNonce: r.Uint64(), OutboundTxGasLimit: r.Uint64(), diff --git a/testutil/sample/fungible.go b/testutil/sample/fungible.go index 3be91d06a3..0d1cd09673 100644 --- a/testutil/sample/fungible.go +++ b/testutil/sample/fungible.go @@ -25,8 +25,8 @@ func ForeignCoins(t *testing.T, address string) types.ForeignCoins { func ForeignCoinList(t *testing.T, zrc20ETH, zrc20BTC, zrc20ERC20, erc20Asset string) []types.ForeignCoins { // eth and btc chain id - ethChainID := chains.GoerliLocalnetChain().ChainId - btcChainID := chains.BtcRegtestChain().ChainId + ethChainID := chains.GoerliLocalnetChain.ChainId + btcChainID := chains.BtcRegtestChain.ChainId // add zrc20 ETH fcGas := ForeignCoins(t, zrc20ETH) diff --git a/testutil/sample/lightclient.go b/testutil/sample/lightclient.go index 6bb69f32d6..b8ab40eba2 100644 --- a/testutil/sample/lightclient.go +++ b/testutil/sample/lightclient.go @@ -61,7 +61,7 @@ func Proof(t *testing.T) (*proofs.Proof, proofs.BlockHeader, string, int64, int6 proof, err := txsTree.GenerateProof(txIndex) require.NoError(t, err) - chainID := chains.SepoliaChain().ChainId + chainID := chains.SepoliaChain.ChainId ethProof := proofs.NewEthereumProof(proof) ethHeader := proofs.NewEthereumHeader(b) blockHeader := proofs.BlockHeader{ diff --git a/testutil/sample/observer.go b/testutil/sample/observer.go index a05c4ecf52..ea906c6e57 100644 --- a/testutil/sample/observer.go +++ b/testutil/sample/observer.go @@ -110,7 +110,7 @@ func ChainParamsSupported(chainID int64) *types.ChainParams { } func ChainParamsList() (cpl types.ChainParamsList) { - chainList := chains.PrivnetChainList() + chainList := chains.ChainListByNetworkType(chains.NetworkType_privnet) for _, chain := range chainList { cpl.ChainParams = append(cpl.ChainParams, ChainParams(chain.ChainId)) diff --git a/typescript/observer/observer_pb.d.ts b/typescript/observer/observer_pb.d.ts index 79bd712ab5..cb1ed1d0bb 100644 --- a/typescript/observer/observer_pb.d.ts +++ b/typescript/observer/observer_pb.d.ts @@ -58,6 +58,8 @@ export declare enum ObserverUpdateReason { } /** + * Deprecated: Use ObserverSet instead to get the list of observers + * * @generated from message zetachain.zetacore.observer.ObserverMapper */ export declare class ObserverMapper extends Message { diff --git a/typescript/pkg/chains/chains_pb.d.ts b/typescript/pkg/chains/chains_pb.d.ts index 4a2efde10d..9b1262b8ed 100644 --- a/typescript/pkg/chains/chains_pb.d.ts +++ b/typescript/pkg/chains/chains_pb.d.ts @@ -13,22 +13,24 @@ export declare enum ReceiveStatus { /** * some observer sees inbound tx * - * @generated from enum value: Created = 0; + * @generated from enum value: created = 0; */ - Created = 0, + created = 0, /** - * @generated from enum value: Success = 1; + * @generated from enum value: success = 1; */ - Success = 1, + success = 1, /** - * @generated from enum value: Failed = 2; + * @generated from enum value: failed = 2; */ - Failed = 2, + failed = 2, } /** + * ChainName represents the name of the chain + * * @generated from enum chains.ChainName */ export declare enum ChainName { @@ -118,6 +120,104 @@ export declare enum ChainName { amoy_testnet = 16, } +/** + * Network represents the network type of the chain + * + * @generated from enum chains.Network + */ +export declare enum Network { + /** + * @generated from enum value: eth = 0; + */ + eth = 0, + + /** + * @generated from enum value: zeta = 1; + */ + zeta = 1, + + /** + * @generated from enum value: btc = 2; + */ + btc = 2, + + /** + * @generated from enum value: polygon = 3; + */ + polygon = 3, + + /** + * @generated from enum value: bsc = 4; + */ + bsc = 4, +} + +/** + * NetworkType represents the network type of the chain + * + * @generated from enum chains.NetworkType + */ +export declare enum NetworkType { + /** + * @generated from enum value: mainnet = 0; + */ + mainnet = 0, + + /** + * @generated from enum value: testnet = 1; + */ + testnet = 1, + + /** + * @generated from enum value: privnet = 2; + */ + privnet = 2, + + /** + * @generated from enum value: devnet = 3; + */ + devnet = 3, +} + +/** + * Vm represents the virtual machine type of the chain to support smart contracts + * + * @generated from enum chains.Vm + */ +export declare enum Vm { + /** + * @generated from enum value: no_vm = 0; + */ + no_vm = 0, + + /** + * @generated from enum value: evm = 1; + */ + evm = 1, +} + +/** + * Consensus represents the consensus algorithm used by the chain + * + * @generated from enum chains.Consensus + */ +export declare enum Consensus { + /** + * @generated from enum value: ethereum = 0; + */ + ethereum = 0, + + /** + * @generated from enum value: tendermint = 1; + */ + tendermint = 1, + + /** + * @generated from enum value: bitcoin = 2; + */ + bitcoin = 2, +} + /** * @generated from message chains.Chain */ @@ -132,6 +232,36 @@ export declare class Chain extends Message { */ chainId: bigint; + /** + * @generated from field: chains.Network network = 3; + */ + network: Network; + + /** + * @generated from field: chains.NetworkType network_type = 4; + */ + networkType: NetworkType; + + /** + * @generated from field: chains.Vm vm = 5; + */ + vm: Vm; + + /** + * @generated from field: chains.Consensus consensus = 6; + */ + consensus: Consensus; + + /** + * @generated from field: bool is_external = 7; + */ + isExternal: boolean; + + /** + * @generated from field: bool is_header_supported = 8; + */ + isHeaderSupported: boolean; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/x/crosschain/keeper/abci_test.go b/x/crosschain/keeper/abci_test.go index c8ef411f4b..7f89e36c08 100644 --- a/x/crosschain/keeper/abci_test.go +++ b/x/crosschain/keeper/abci_test.go @@ -43,19 +43,19 @@ func TestKeeper_IterateAndUpdateCctxGasPrice(t *testing.T) { // add some evm and non-evm chains supportedChains := []*chains.Chain{ - {ChainId: chains.EthChain().ChainId}, - {ChainId: chains.BtcMainnetChain().ChainId}, - {ChainId: chains.BscMainnetChain().ChainId}, - {ChainId: chains.ZetaChainMainnet().ChainId}, + {ChainId: chains.EthChain.ChainId}, + {ChainId: chains.BtcMainnetChain.ChainId}, + {ChainId: chains.BscMainnetChain.ChainId}, + {ChainId: chains.ZetaChainMainnet.ChainId}, } // set pending cctx tss := sample.Tss() zk.ObserverKeeper.SetTSS(ctx, tss) - createCctxWithNonceRange(t, ctx, *k, 10, 15, chains.EthChain().ChainId, tss, zk) - createCctxWithNonceRange(t, ctx, *k, 20, 25, chains.BtcMainnetChain().ChainId, tss, zk) - createCctxWithNonceRange(t, ctx, *k, 30, 35, chains.BscMainnetChain().ChainId, tss, zk) - createCctxWithNonceRange(t, ctx, *k, 40, 45, chains.ZetaChainMainnet().ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 10, 15, chains.EthChain.ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 20, 25, chains.BtcMainnetChain.ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 30, 35, chains.BscMainnetChain.ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 40, 45, chains.ZetaChainMainnet.ChainId, tss, zk) // set a cctx where the update function should fail to test that the next cctx are not updated but the next chains are failMap[sample.GetCctxIndexFromString("1-12")] = struct{}{} diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index bd22eab38c..21352d9dc0 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -142,7 +142,7 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { t.Run("successfully validate a valid event", func(t *testing.T) { btcMainNetWithdrawalEvent, err := crosschainkeeper.ParseZRC20WithdrawalEvent(*sample.GetValidZRC20WithdrawToBTC(t).Logs[3]) require.NoError(t, err) - err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain().ChainId) + err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain.ChainId) require.NoError(t, err) }) @@ -150,14 +150,14 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { btcMainNetWithdrawalEvent, err := crosschainkeeper.ParseZRC20WithdrawalEvent(*sample.GetValidZRC20WithdrawToBTC(t).Logs[3]) require.NoError(t, err) btcMainNetWithdrawalEvent.Value = big.NewInt(0) - err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain().ChainId) + err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain.ChainId) require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid amount") }) t.Run("unable to validate a event with an invalid chain ID", func(t *testing.T) { btcMainNetWithdrawalEvent, err := crosschainkeeper.ParseZRC20WithdrawalEvent(*sample.GetValidZRC20WithdrawToBTC(t).Logs[3]) require.NoError(t, err) - err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcTestNetChain().ChainId) + err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcTestNetChain.ChainId) require.ErrorContains(t, err, "invalid address") }) @@ -166,7 +166,7 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { require.NoError(t, err) btcMainNetWithdrawalEvent.To = []byte("04b2891ba8cb491828db3ebc8a780d43b169e7b3974114e6e50f9bab6ec" + "63c2f20f6d31b2025377d05c2a704d3bd799d0d56f3a8543d79a01ab6084a1cb204f260") - err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain().ChainId) + err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BtcMainnetChain.ChainId) require.ErrorContains(t, err, "unsupported address") }) } @@ -176,7 +176,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -202,7 +202,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -228,7 +228,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -249,7 +249,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -270,7 +270,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -293,7 +293,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -319,7 +319,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -344,7 +344,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -367,7 +367,7 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -402,7 +402,7 @@ func TestKeeper_ParseZetaSentEvent(t *testing.T) { require.Nil(t, event) continue } - require.Equal(t, chains.EthChain().ChainId, event.DestinationChainId.Int64()) + require.Equal(t, chains.EthChain.ChainId, event.DestinationChainId.Int64()) require.Equal(t, "70000000000000000000", event.ZetaValueAndGas.String()) require.Equal(t, "0x60983881bdf302dcfa96603A58274D15D5966209", event.SourceTxOriginAddress.String()) require.Equal(t, "0xF0a3F93Ed1B126142E61423F9546bf1323Ff82DF", event.ZetaTxSenderAddress.String()) @@ -440,7 +440,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) @@ -464,7 +464,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { cctxList := k.GetAllCrossChainTx(ctx) require.Len(t, cctxList, 1) require.Equal(t, strings.Compare("0x60983881bdf302dcfa96603a58274d15d5966209", cctxList[0].GetCurrentOutTxParam().Receiver), 0) - require.Equal(t, chains.EthChain().ChainId, cctxList[0].GetCurrentOutTxParam().ReceiverChainId) + require.Equal(t, chains.EthChain.ChainId, cctxList[0].GetCurrentOutTxParam().ReceiverChainId) require.Equal(t, emittingContract.Hex(), cctxList[0].InboundTxParams.Sender) require.Equal(t, txOrigin.Hex(), cctxList[0].InboundTxParams.TxOrigin) }) @@ -473,7 +473,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -494,7 +494,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) admin := keepertest.SetAdminPolices(ctx, zk.AuthorityKeeper) SetupStateForProcessLogsZetaSent(t, ctx, k, zk, sdkk, chain, admin) @@ -517,7 +517,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -543,7 +543,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -566,7 +566,7 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) @@ -599,7 +599,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -625,7 +625,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -650,7 +650,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { cctxList := k.GetAllCrossChainTx(ctx) require.Len(t, cctxList, 1) require.Equal(t, strings.Compare("0x60983881bdf302dcfa96603a58274d15d5966209", cctxList[0].GetCurrentOutTxParam().Receiver), 0) - require.Equal(t, chains.EthChain().ChainId, cctxList[0].GetCurrentOutTxParam().ReceiverChainId) + require.Equal(t, chains.EthChain.ChainId, cctxList[0].GetCurrentOutTxParam().ReceiverChainId) require.Equal(t, emittingContract.Hex(), cctxList[0].InboundTxParams.Sender) require.Equal(t, txOrigin.Hex(), cctxList[0].InboundTxParams.TxOrigin) }) @@ -669,7 +669,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -690,7 +690,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { t.Run("no cctx created for logs containing proper event but not emitted from a known ZRC20 contract", func(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -711,7 +711,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -736,7 +736,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) // use the wrong (testnet) chain ID to make the btc address parsing fail - chain := chains.BtcTestNetChain() + chain := chains.BtcTestNetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) @@ -757,7 +757,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId setSupportedChain(ctx, zk, chainID) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go index 8079c3c67a..e315c1221a 100644 --- a/x/crosschain/keeper/gas_payment_test.go +++ b/x/crosschain/keeper/gas_payment_test.go @@ -52,7 +52,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, CoinType: coin.CoinType_Gas, }, { @@ -110,7 +110,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -149,7 +149,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -212,7 +212,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -274,7 +274,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -316,7 +316,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -368,7 +368,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, @@ -426,7 +426,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { }, OutboundTxParams: []*types.OutboundTxParams{ { - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }, { ReceiverChainId: chainID, diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go index 9c0547e9fb..281692318e 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go @@ -228,7 +228,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(sample.Bytes(), nil) - observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain.ChainId), true) observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(nil, errors.New("error")) txHash := "string" @@ -263,7 +263,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) - observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain.ChainId), true) observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ Eth: sample.EthAddress().Hex(), }, nil) @@ -297,7 +297,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { admin := sample.AccAddress() - chainID := chains.EthChain().ChainId + chainID := chains.EthChain.ChainId tssAddress := sample.EthAddress() ethTx, ethTxBytes := sample.EthTx(t, chainID, tssAddress, 42) txHash := ethTx.Hash().Hex() @@ -309,7 +309,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) - observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain.ChainId), true) observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ Eth: tssAddress.Hex(), }, nil) diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go index 11ea50a514..606f450afc 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go @@ -154,7 +154,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, Creator: observer, ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, @@ -210,7 +210,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Failed, + Status: chains.ReceiveStatus_failed, Creator: observer, ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, @@ -270,7 +270,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Failed, + Status: chains.ReceiveStatus_failed, Creator: observer, ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, @@ -332,7 +332,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Failed, + Status: chains.ReceiveStatus_failed, Creator: observer, ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, @@ -376,7 +376,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, Creator: accAddress.String(), ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, @@ -422,7 +422,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { CctxHash: cctx.Index, OutTxTssNonce: cctx.GetCurrentOutTxParam().OutboundTxTssNonce, OutTxChain: cctx.GetCurrentOutTxParam().ReceiverChainId, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, Creator: accAddress.String(), ObservedOutTxHash: sample.Hash().String(), ValueReceived: cctx.GetCurrentOutTxParam().Amount, diff --git a/x/crosschain/keeper/process_inbound_test.go b/x/crosschain/keeper/process_inbound_test.go index 3e86cd68c5..28577e797f 100644 --- a/x/crosschain/keeper/process_inbound_test.go +++ b/x/crosschain/keeper/process_inbound_test.go @@ -37,7 +37,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { cctx := sample.CrossChainTx(t, "test") cctx.CctxStatus = &types.Status{Status: types.CctxStatus_PendingInbound} cctx.GetCurrentOutTxParam().Receiver = receiver.String() - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId cctx.GetInboundTxParams().Amount = sdkmath.NewUintFromBigInt(amount) cctx.InboundTxParams.CoinType = coin.CoinType_Zeta cctx.GetInboundTxParams().SenderChainId = 0 @@ -63,7 +63,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { cctx := sample.CrossChainTx(t, "test") cctx.CctxStatus = &types.Status{Status: types.CctxStatus_PendingInbound} cctx.GetCurrentOutTxParam().Receiver = receiver.String() - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId cctx.GetInboundTxParams().Amount = sdkmath.NewUintFromBigInt(amount) cctx.InboundTxParams.CoinType = coin.CoinType_Zeta cctx.GetInboundTxParams().SenderChainId = 0 @@ -96,7 +96,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, "", amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("invalid sender chain id %d", cctx.InboundTxParams.SenderChainId), cctx.CctxStatus.StatusMessage) @@ -129,7 +129,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("revert gas limit error: %s", types.ErrForeignCoinNotFound), cctx.CctxStatus.StatusMessage) @@ -166,7 +166,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("deposit revert message: %s err : %s", errDeposit, observertypes.ErrSupportedChains), cctx.CctxStatus.StatusMessage) @@ -203,7 +203,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("deposit revert message: %s err : %s", errDeposit, observertypes.ErrSupportedChains), cctx.CctxStatus.StatusMessage) @@ -243,7 +243,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Contains(t, cctx.CctxStatus.StatusMessage, "cannot find receiver chain nonce") @@ -281,7 +281,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_PendingRevert, cctx.CctxStatus.Status) require.Equal(t, errDeposit.Error(), cctx.CctxStatus.StatusMessage) @@ -315,7 +315,7 @@ func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain.ChainId cctx.OutboundTxParams = append(cctx.OutboundTxParams, cctx.GetCurrentOutTxParam()) k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) diff --git a/x/crosschain/keeper/process_outbound_test.go b/x/crosschain/keeper/process_outbound_test.go index b4dbbef200..7d1e412db4 100644 --- a/x/crosschain/keeper/process_outbound_test.go +++ b/x/crosschain/keeper/process_outbound_test.go @@ -49,10 +49,10 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { t.Run("successfully process failed outbound if original sender is a address", func(t *testing.T) { k, ctx, sdkk, _ := keepertest.CrosschainKeeper(t) receiver := sample.EthAddress() - cctx := GetERC20Cctx(t, receiver, chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, receiver, chains.GoerliChain, "", big.NewInt(42)) err := sdkk.EvmKeeper.SetAccount(ctx, ethcommon.HexToAddress(cctx.InboundTxParams.Sender), *statedb.NewEmptyAccount()) require.NoError(t, err) - cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId + cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet.ChainId err = k.ProcessFailedOutbound(ctx, cctx, sample.String()) require.NoError(t, err) require.Equal(t, types.CctxStatus_Reverted, cctx.CctxStatus.Status) @@ -61,9 +61,9 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { t.Run("unable to process failed outbound if GetCCTXIndexBytes fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) receiver := sample.EthAddress() - cctx := GetERC20Cctx(t, receiver, chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, receiver, chains.GoerliChain, "", big.NewInt(42)) cctx.Index = "" - cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId + cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet.ChainId err := k.ProcessFailedOutbound(ctx, cctx, sample.String()) require.ErrorContains(t, err, "failed reverting GetCCTXIndexBytes") }) @@ -71,7 +71,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { t.Run("unable to process failed outbound if Adding Revert fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") - cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId + cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet.ChainId err := k.ProcessFailedOutbound(ctx, cctx, sample.String()) require.ErrorContains(t, err, "failed AddRevertOutbound") }) @@ -79,8 +79,8 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { t.Run("unable to process failed outbound if ZETARevertAndCallContract fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) receiver := sample.EthAddress() - cctx := GetERC20Cctx(t, receiver, chains.GoerliChain(), "", big.NewInt(42)) - cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId + cctx := GetERC20Cctx(t, receiver, chains.GoerliChain, "", big.NewInt(42)) + cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet.ChainId err := k.ProcessFailedOutbound(ctx, cctx, sample.String()) require.ErrorContains(t, err, "failed ZETARevertAndCallContract") }) @@ -89,7 +89,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) _ = zk.FungibleKeeper.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) - cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain, "", big.NewInt(42)) cctx.RelayedMessage = base64.StdEncoding.EncodeToString([]byte("sample message")) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) @@ -97,7 +97,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { require.NoError(t, err) assertContractDeployment(t, sdkk.EvmKeeper, ctx, dAppContract) cctx.InboundTxParams.Sender = dAppContract.String() - cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId + cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet.ChainId err = k.ProcessFailedOutbound(ctx, cctx, sample.String()) require.NoError(t, err) @@ -278,7 +278,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { func TestKeeper_ProcessOutbound(t *testing.T) { t.Run("successfully process outbound with ballot finalized to success", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain, "", big.NewInt(42)) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotFinalized_SuccessObservation, sample.String()) require.NoError(t, err) @@ -287,7 +287,7 @@ func TestKeeper_ProcessOutbound(t *testing.T) { t.Run("successfully process outbound with ballot finalized to failed and old status is Pending Revert", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain, "", big.NewInt(42)) cctx.CctxStatus.Status = types.CctxStatus_PendingRevert err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String()) require.NoError(t, err) @@ -297,7 +297,7 @@ func TestKeeper_ProcessOutbound(t *testing.T) { t.Run("successfully process outbound with ballot finalized to failed and coin-type is CMD", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain, "", big.NewInt(42)) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound cctx.InboundTxParams.CoinType = coin.CoinType_Cmd err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String()) @@ -308,7 +308,7 @@ func TestKeeper_ProcessOutbound(t *testing.T) { t.Run("do not process if cctx invalid", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain, "", big.NewInt(42)) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound cctx.InboundTxParams = nil err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotInProgress, sample.String()) diff --git a/x/crosschain/keeper/rate_limiter_flags_test.go b/x/crosschain/keeper/rate_limiter_flags_test.go index 0b8010031d..de134ee4f7 100644 --- a/x/crosschain/keeper/rate_limiter_flags_test.go +++ b/x/crosschain/keeper/rate_limiter_flags_test.go @@ -53,7 +53,7 @@ func TestKeeper_GetRateLimiterRates(t *testing.T) { }, } - chainID := chains.GoerliLocalnetChain().ChainId + chainID := chains.GoerliLocalnetChain.ChainId // add gas coin fcGas := sample.ForeignCoins(t, zrc20GasAddr) diff --git a/x/crosschain/keeper/utils_test.go b/x/crosschain/keeper/utils_test.go index 3b3ab6967c..a8d63f17d1 100644 --- a/x/crosschain/keeper/utils_test.go +++ b/x/crosschain/keeper/utils_test.go @@ -26,14 +26,14 @@ func getValidEthChainID() int64 { return getValidEthChain().ChainId } -// getValidEthChain get a valid eth chain +// getValidEthChain() get a valid eth chain func getValidEthChain() *chains.Chain { - goerli := chains.GoerliLocalnetChain() + goerli := chains.GoerliLocalnetChain return &goerli } func getValidBTCChain() *chains.Chain { - btcRegNet := chains.BtcRegtestChain() + btcRegNet := chains.BtcRegtestChain return &btcRegNet } @@ -45,9 +45,9 @@ func getValidBtcChainID() int64 { func getValidEthChainIDWithIndex(t *testing.T, index int) int64 { switch index { case 0: - return chains.GoerliLocalnetChain().ChainId + return chains.GoerliLocalnetChain.ChainId case 1: - return chains.GoerliChain().ChainId + return chains.GoerliChain.ChainId default: require.Fail(t, "invalid index") } diff --git a/x/crosschain/migrations/v4/migrate_test.go b/x/crosschain/migrations/v4/migrate_test.go index 4ba61e399a..8d4cb30833 100644 --- a/x/crosschain/migrations/v4/migrate_test.go +++ b/x/crosschain/migrations/v4/migrate_test.go @@ -97,49 +97,49 @@ func TestSetBitcoinFinalizedInbound(t *testing.T) { k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "0", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.GoerliChain().ChainId, + SenderChainId: chains.GoerliChain.ChainId, InboundTxObservedHash: "0xaaa", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "1", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.BtcMainnetChain().ChainId, + SenderChainId: chains.BtcMainnetChain.ChainId, InboundTxObservedHash: "0x111", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "2", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.EthChain().ChainId, + SenderChainId: chains.EthChain.ChainId, InboundTxObservedHash: "0xbbb", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "3", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.BtcTestNetChain().ChainId, + SenderChainId: chains.BtcTestNetChain.ChainId, InboundTxObservedHash: "0x222", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "4", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.BtcTestNetChain().ChainId, + SenderChainId: chains.BtcTestNetChain.ChainId, InboundTxObservedHash: "0x333", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "5", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.MumbaiChain().ChainId, + SenderChainId: chains.MumbaiChain.ChainId, InboundTxObservedHash: "0xccc", }, }) k.SetCrossChainTx(ctx, types.CrossChainTx{ Index: "6", InboundTxParams: &types.InboundTxParams{ - SenderChainId: chains.BtcRegtestChain().ChainId, + SenderChainId: chains.BtcRegtestChain.ChainId, InboundTxObservedHash: "0x444", }, }) @@ -148,13 +148,13 @@ func TestSetBitcoinFinalizedInbound(t *testing.T) { v4.SetBitcoinFinalizedInbound(ctx, k) // check finalized inbound - require.False(t, k.IsFinalizedInbound(ctx, "0xaaa", chains.GoerliChain().ChainId, 0)) - require.False(t, k.IsFinalizedInbound(ctx, "0xbbb", chains.EthChain().ChainId, 0)) - require.False(t, k.IsFinalizedInbound(ctx, "0xccc", chains.MumbaiChain().ChainId, 0)) - require.True(t, k.IsFinalizedInbound(ctx, "0x111", chains.BtcMainnetChain().ChainId, 0)) - require.True(t, k.IsFinalizedInbound(ctx, "0x222", chains.BtcTestNetChain().ChainId, 0)) - require.True(t, k.IsFinalizedInbound(ctx, "0x333", chains.BtcTestNetChain().ChainId, 0)) - require.True(t, k.IsFinalizedInbound(ctx, "0x444", chains.BtcRegtestChain().ChainId, 0)) + require.False(t, k.IsFinalizedInbound(ctx, "0xaaa", chains.GoerliChain.ChainId, 0)) + require.False(t, k.IsFinalizedInbound(ctx, "0xbbb", chains.EthChain.ChainId, 0)) + require.False(t, k.IsFinalizedInbound(ctx, "0xccc", chains.MumbaiChain.ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x111", chains.BtcMainnetChain.ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x222", chains.BtcTestNetChain.ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x333", chains.BtcTestNetChain.ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x444", chains.BtcRegtestChain.ChainId, 0)) }) } diff --git a/x/crosschain/migrations/v5/migrate.go b/x/crosschain/migrations/v5/migrate.go index 98fee02256..194ddfe96b 100644 --- a/x/crosschain/migrations/v5/migrate.go +++ b/x/crosschain/migrations/v5/migrate.go @@ -77,10 +77,10 @@ type TestnetNonce struct { func CurrentTestnetChains() []TestnetNonce { return []TestnetNonce{ - {chain: chains.GoerliChain(), nonceHigh: 226841, nonceLow: 226841}, - {chain: chains.MumbaiChain(), nonceHigh: 200599, nonceLow: 200599}, - {chain: chains.BscTestnetChain(), nonceHigh: 110454, nonceLow: 110454}, - {chain: chains.BtcTestNetChain(), nonceHigh: 4881, nonceLow: 4881}, + {chain: chains.GoerliChain, nonceHigh: 226841, nonceLow: 226841}, + {chain: chains.MumbaiChain, nonceHigh: 200599, nonceLow: 200599}, + {chain: chains.BscTestnetChain, nonceHigh: 110454, nonceLow: 110454}, + {chain: chains.BtcTestNetChain, nonceHigh: 4881, nonceLow: 4881}, } } diff --git a/x/crosschain/migrations/v5/migrate_test.go b/x/crosschain/migrations/v5/migrate_test.go index 3bed70bcb1..912fb0c483 100644 --- a/x/crosschain/migrations/v5/migrate_test.go +++ b/x/crosschain/migrations/v5/migrate_test.go @@ -67,8 +67,8 @@ func TestMigrateStore(t *testing.T) { func TestResetTestnetNonce(t *testing.T) { t.Run("reset only testnet nonce without changing mainnet chains", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) - testnetChains := []chains.Chain{chains.GoerliChain(), chains.MumbaiChain(), chains.BscTestnetChain(), chains.BtcTestNetChain()} - mainnetChains := []chains.Chain{chains.EthChain(), chains.BscMainnetChain(), chains.BtcMainnetChain()} + testnetChains := []chains.Chain{chains.GoerliChain, chains.MumbaiChain, chains.BscTestnetChain, chains.BtcTestNetChain} + mainnetChains := []chains.Chain{chains.EthChain, chains.BscMainnetChain, chains.BtcMainnetChain} nonceLow := int64(1) nonceHigh := int64(10) tss := sample.Tss() @@ -102,10 +102,10 @@ func TestResetTestnetNonce(t *testing.T) { err := v5.MigrateStore(ctx, k, zk.ObserverKeeper) require.NoError(t, err) assertValues := map[chains.Chain]int64{ - chains.GoerliChain(): 226841, - chains.MumbaiChain(): 200599, - chains.BscTestnetChain(): 110454, - chains.BtcTestNetChain(): 4881, + chains.GoerliChain: 226841, + chains.MumbaiChain: 200599, + chains.BscTestnetChain: 110454, + chains.BtcTestNetChain: 4881, } for _, chain := range testnetChains { @@ -130,7 +130,7 @@ func TestResetTestnetNonce(t *testing.T) { t.Run("reset nonce even if some chain values are missing", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) - testnetChains := []chains.Chain{chains.GoerliChain()} + testnetChains := []chains.Chain{chains.GoerliChain} nonceLow := int64(1) nonceHigh := int64(10) tss := sample.Tss() @@ -151,9 +151,9 @@ func TestResetTestnetNonce(t *testing.T) { err := v5.MigrateStore(ctx, k, zk.ObserverKeeper) require.NoError(t, err) assertValuesSet := map[chains.Chain]int64{ - chains.GoerliChain(): 226841, + chains.GoerliChain: 226841, } - assertValuesNotSet := []chains.Chain{chains.MumbaiChain(), chains.BscTestnetChain(), chains.BtcTestNetChain()} + assertValuesNotSet := []chains.Chain{chains.MumbaiChain, chains.BscTestnetChain, chains.BtcTestNetChain} for _, chain := range testnetChains { pn, found := zk.ObserverKeeper.GetPendingNonces(ctx, tss.TssPubkey, chain.ChainId) @@ -218,7 +218,7 @@ func CrossChainTxList(count int) []crosschaintypes.CrossChainTx { OutboundTxParams: []*crosschaintypes.OutboundTxParams{{ Amount: math.ZeroUint(), CoinType: coin.CoinType_ERC20, - ReceiverChainId: chains.ZetaPrivnetChain().ChainId, + ReceiverChainId: chains.ZetaPrivnetChain.ChainId, }}, } } @@ -234,7 +234,7 @@ func CrossChainTxList(count int) []crosschaintypes.CrossChainTx { OutboundTxParams: []*crosschaintypes.OutboundTxParams{{ Amount: math.ZeroUint(), CoinType: coin.CoinType_ERC20, - ReceiverChainId: chains.GoerliLocalnetChain().ChainId, + ReceiverChainId: chains.GoerliLocalnetChain.ChainId, }}, } } diff --git a/x/crosschain/types/cctx_test.go b/x/crosschain/types/cctx_test.go index 0b7f267d2d..477552ed36 100644 --- a/x/crosschain/types/cctx_test.go +++ b/x/crosschain/types/cctx_test.go @@ -25,9 +25,9 @@ func TestCrossChainTx_GetCCTXIndexBytes(t *testing.T) { func Test_InitializeCCTX(t *testing.T) { t.Run("should return a cctx with correct values", func(t *testing.T) { _, ctx, _, _ := keepertest.CrosschainKeeper(t) - senderChain := chains.GoerliChain() + senderChain := chains.GoerliChain sender := sample.EthAddress() - receiverChain := chains.GoerliChain() + receiverChain := chains.GoerliChain receiver := sample.EthAddress() creator := sample.AccAddress() amount := sdkmath.NewUint(42) @@ -75,9 +75,9 @@ func Test_InitializeCCTX(t *testing.T) { }) t.Run("should return an error if the cctx is invalid", func(t *testing.T) { _, ctx, _, _ := keepertest.CrosschainKeeper(t) - senderChain := chains.GoerliChain() + senderChain := chains.GoerliChain sender := sample.EthAddress() - receiverChain := chains.GoerliChain() + receiverChain := chains.GoerliChain receiver := sample.EthAddress() creator := sample.AccAddress() amount := sdkmath.NewUint(42) diff --git a/x/crosschain/types/inbound_params_test.go b/x/crosschain/types/inbound_params_test.go index 6b6cdf2293..b3803498d6 100644 --- a/x/crosschain/types/inbound_params_test.go +++ b/x/crosschain/types/inbound_params_test.go @@ -19,11 +19,11 @@ func TestInboundTxParams_Validate(t *testing.T) { inTxParams.SenderChainId = 1000 require.ErrorContains(t, inTxParams.Validate(), "invalid sender chain id 1000") inTxParams = sample.InboundTxParamsValidChainID(r) - inTxParams.SenderChainId = chains.GoerliChain().ChainId + inTxParams.SenderChainId = chains.GoerliChain.ChainId inTxParams.Sender = "0x123" require.ErrorContains(t, inTxParams.Validate(), "invalid address 0x123") inTxParams = sample.InboundTxParamsValidChainID(r) - inTxParams.SenderChainId = chains.GoerliChain().ChainId + inTxParams.SenderChainId = chains.GoerliChain.ChainId inTxParams.TxOrigin = "0x123" require.ErrorContains(t, inTxParams.Validate(), "invalid address 0x123") inTxParams = sample.InboundTxParamsValidChainID(r) diff --git a/x/crosschain/types/message_add_to_in_tx_tracker_test.go b/x/crosschain/types/message_add_to_in_tx_tracker_test.go index b145737eaa..20d9545d42 100644 --- a/x/crosschain/types/message_add_to_in_tx_tracker_test.go +++ b/x/crosschain/types/message_add_to_in_tx_tracker_test.go @@ -24,7 +24,7 @@ func TestMsgAddToInTxTracker_ValidateBasic(t *testing.T) { name: "invalid address", msg: types.NewMsgAddToInTxTracker( "invalid_address", - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ), @@ -44,17 +44,17 @@ func TestMsgAddToInTxTracker_ValidateBasic(t *testing.T) { name: "invalid proof", msg: &types.MsgAddToInTxTracker{ Creator: sample.AccAddress(), - ChainId: chains.ZetaTestnetChain().ChainId, + ChainId: chains.ZetaTestnetChain.ChainId, CoinType: coin.CoinType_Gas, Proof: &proofs.Proof{}, }, - err: errorsmod.Wrapf(types.ErrProofVerificationFail, "chain id %d does not support proof-based trackers", chains.ZetaTestnetChain().ChainId), + err: errorsmod.Wrapf(types.ErrProofVerificationFail, "chain id %d does not support proof-based trackers", chains.ZetaTestnetChain.ChainId), }, { name: "invalid coin type", msg: &types.MsgAddToInTxTracker{ Creator: sample.AccAddress(), - ChainId: chains.ZetaTestnetChain().ChainId, + ChainId: chains.ZetaTestnetChain.ChainId, CoinType: 5, }, err: errorsmod.Wrapf(types.ErrProofVerificationFail, "coin-type not supported"), @@ -63,7 +63,7 @@ func TestMsgAddToInTxTracker_ValidateBasic(t *testing.T) { name: "valid", msg: types.NewMsgAddToInTxTracker( sample.AccAddress(), - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ), @@ -93,7 +93,7 @@ func TestMsgAddToInTxTracker_GetSigners(t *testing.T) { name: "valid signer", msg: types.NewMsgAddToInTxTracker( signer, - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ), @@ -103,7 +103,7 @@ func TestMsgAddToInTxTracker_GetSigners(t *testing.T) { name: "invalid signer", msg: types.NewMsgAddToInTxTracker( "invalid_address", - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ), @@ -128,7 +128,7 @@ func TestMsgAddToInTxTracker_GetSigners(t *testing.T) { func TestMsgAddToInTxTracker_Type(t *testing.T) { msg := types.NewMsgAddToInTxTracker( sample.AccAddress(), - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ) @@ -138,7 +138,7 @@ func TestMsgAddToInTxTracker_Type(t *testing.T) { func TestMsgAddToInTxTracker_Route(t *testing.T) { msg := types.NewMsgAddToInTxTracker( sample.AccAddress(), - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ) @@ -148,7 +148,7 @@ func TestMsgAddToInTxTracker_Route(t *testing.T) { func TestMsgAddToInTxTracker_GetSignBytes(t *testing.T) { msg := types.NewMsgAddToInTxTracker( sample.AccAddress(), - chains.GoerliChain().ChainId, + chains.GoerliChain.ChainId, coin.CoinType_Gas, "hash", ) diff --git a/x/crosschain/types/message_vote_on_observed_outbound_tx.go b/x/crosschain/types/message_vote_on_observed_outbound_tx.go index 360038c6f4..7c468aa54a 100644 --- a/x/crosschain/types/message_vote_on_observed_outbound_tx.go +++ b/x/crosschain/types/message_vote_on_observed_outbound_tx.go @@ -80,8 +80,8 @@ func (msg *MsgVoteOnObservedOutboundTx) Digest() string { m := *msg m.Creator = "" - // Set status to ReceiveStatus_Created to make sure both successful and failed votes are added to the same ballot - m.Status = chains.ReceiveStatus_Created + // Set status to ReceiveStatus_created to make sure both successful and failed votes are added to the same ballot + m.Status = chains.ReceiveStatus_created // Outbound and reverted txs have different digest as ObservedOutTxHash is different so they are stored in different ballots hash := crypto.Keccak256Hash([]byte(m.String())) diff --git a/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go b/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go index d9e3f6a3ca..9c2c4714bf 100644 --- a/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go +++ b/x/crosschain/types/message_vote_on_observed_outbound_tx_test.go @@ -32,7 +32,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { math.NewInt(42), 42, math.NewUint(42), - chains.ReceiveStatus_Created, + chains.ReceiveStatus_created, 42, 42, coin.CoinType_Zeta, @@ -49,7 +49,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { math.NewInt(42), 42, math.NewUint(42), - chains.ReceiveStatus_Created, + chains.ReceiveStatus_created, 42, 42, coin.CoinType_Zeta, @@ -67,7 +67,7 @@ func TestMsgVoteOnObservedOutboundTx_ValidateBasic(t *testing.T) { math.NewInt(42), 42, math.NewUint(42), - chains.ReceiveStatus_Created, + chains.ReceiveStatus_created, -1, 42, coin.CoinType_Zeta, @@ -99,7 +99,7 @@ func TestMsgVoteOnObservedOutboundTx_Digest(t *testing.T) { ObservedOutTxEffectiveGasPrice: math.NewInt(42), ObservedOutTxEffectiveGasLimit: 42, ValueReceived: math.NewUint(42), - Status: chains.ReceiveStatus_Created, + Status: chains.ReceiveStatus_created, OutTxChain: 42, OutTxTssNonce: 42, CoinType: coin.CoinType_Zeta, @@ -115,7 +115,7 @@ func TestMsgVoteOnObservedOutboundTx_Digest(t *testing.T) { // status not used msg2 = msg - msg2.Status = chains.ReceiveStatus_Failed + msg2.Status = chains.ReceiveStatus_failed hash2 = msg2.Digest() require.Equal(t, hash, hash2, "status should not change hash") diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index f7fa9790e4..fabc4f9b44 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -920,7 +920,7 @@ func (m *MsgVoteOnObservedOutboundTx) GetStatus() chains.ReceiveStatus { if m != nil { return m.Status } - return chains.ReceiveStatus_Created + return chains.ReceiveStatus_created } func (m *MsgVoteOnObservedOutboundTx) GetOutTxChain() int64 { diff --git a/x/crosschain/types/tx_body_verification_test.go b/x/crosschain/types/tx_body_verification_test.go index 2836b755e9..57cb4c6deb 100644 --- a/x/crosschain/types/tx_body_verification_test.go +++ b/x/crosschain/types/tx_body_verification_test.go @@ -13,7 +13,7 @@ import ( func TestVerifyInTxBody(t *testing.T) { sampleTo := sample.EthAddress() - sampleEthTx, sampleEthTxBytes := sample.EthTx(t, chains.EthChain().ChainId, sampleTo, 42) + sampleEthTx, sampleEthTxBytes := sample.EthTx(t, chains.EthChain.ChainId, sampleTo, 42) // NOTE: errContains == "" means no error for _, tc := range []struct { @@ -27,7 +27,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "can't verify btc tx tx body", msg: types.MsgAddToInTxTracker{ - ChainId: chains.BtcMainnetChain().ChainId, + ChainId: chains.BtcMainnetChain.ChainId, }, txBytes: sample.Bytes(), errContains: "cannot verify inTx body for chain", @@ -35,7 +35,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "txBytes can't be unmarshaled", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, }, txBytes: []byte("invalid"), errContains: "failed to unmarshal transaction", @@ -43,7 +43,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "txHash doesn't correspond", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sample.Hash().Hex(), }, txBytes: sampleEthTxBytes, @@ -52,7 +52,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "chain id doesn't correspond", msg: types.MsgAddToInTxTracker{ - ChainId: chains.SepoliaChain().ChainId, + ChainId: chains.SepoliaChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), }, txBytes: sampleEthTxBytes, @@ -61,7 +61,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "invalid coin type", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType(1000), }, @@ -71,7 +71,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is zeta, but connector contract address is wrong", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_Zeta, }, @@ -82,7 +82,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is zeta, connector contract address is correct", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_Zeta, }, @@ -92,7 +92,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is erc20, but erc20 custody contract address is wrong", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_ERC20, }, @@ -103,7 +103,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is erc20, erc20 custody contract address is correct", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_ERC20, }, @@ -113,7 +113,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is gas, but tss address is not found", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_Gas, }, @@ -124,7 +124,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is gas, but tss address is wrong", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_Gas, }, @@ -135,7 +135,7 @@ func TestVerifyInTxBody(t *testing.T) { { desc: "coin types is gas, tss address is correct", msg: types.MsgAddToInTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, TxHash: sampleEthTx.Hash().Hex(), CoinType: coin.CoinType_Gas, }, @@ -157,8 +157,8 @@ func TestVerifyInTxBody(t *testing.T) { func TestVerifyOutTxBody(t *testing.T) { sampleTo := sample.EthAddress() - sampleEthTx, sampleEthTxBytes, sampleFrom := sample.EthTxSigned(t, chains.EthChain().ChainId, sampleTo, 42) - _, sampleEthTxBytesNonSigned := sample.EthTx(t, chains.EthChain().ChainId, sampleTo, 42) + sampleEthTx, sampleEthTxBytes, sampleFrom := sample.EthTxSigned(t, chains.EthChain.ChainId, sampleTo, 42) + _, sampleEthTxBytesNonSigned := sample.EthTx(t, chains.EthChain.ChainId, sampleTo, 42) // NOTE: errContains == "" means no error for _, tc := range []struct { @@ -181,7 +181,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "txBytes can't be unmarshaled", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, @@ -191,7 +191,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "can't recover sender address", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, @@ -201,7 +201,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "tss address not found", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, @@ -212,7 +212,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "tss address is wrong", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, @@ -223,7 +223,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "chain id doesn't correspond", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.SepoliaChain().ChainId, + ChainId: chains.SepoliaChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, @@ -234,7 +234,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "nonce doesn't correspond", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 100, TxHash: sampleEthTx.Hash().Hex(), }, @@ -245,7 +245,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "tx hash doesn't correspond", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sample.Hash().Hex(), }, @@ -256,7 +256,7 @@ func TestVerifyOutTxBody(t *testing.T) { { desc: "valid out tx body", msg: types.MsgAddToOutTxTracker{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Nonce: 42, TxHash: sampleEthTx.Hash().Hex(), }, diff --git a/x/crosschain/types/validate_test.go b/x/crosschain/types/validate_test.go index c768a7d4ab..3daf789442 100644 --- a/x/crosschain/types/validate_test.go +++ b/x/crosschain/types/validate_test.go @@ -11,23 +11,23 @@ import ( func TestValidateAddressForChain(t *testing.T) { // test for eth chain - require.Error(t, types.ValidateAddressForChain("0x123", chains.GoerliChain().ChainId)) - require.Error(t, types.ValidateAddressForChain("", chains.GoerliChain().ChainId)) - require.Error(t, types.ValidateAddressForChain("%%%%", chains.GoerliChain().ChainId)) - require.NoError(t, types.ValidateAddressForChain("0x792c127Fa3AC1D52F904056Baf1D9257391e7D78", chains.GoerliChain().ChainId)) + require.Error(t, types.ValidateAddressForChain("0x123", chains.GoerliChain.ChainId)) + require.Error(t, types.ValidateAddressForChain("", chains.GoerliChain.ChainId)) + require.Error(t, types.ValidateAddressForChain("%%%%", chains.GoerliChain.ChainId)) + require.NoError(t, types.ValidateAddressForChain("0x792c127Fa3AC1D52F904056Baf1D9257391e7D78", chains.GoerliChain.ChainId)) // test for btc chain - require.NoError(t, types.ValidateAddressForChain("bc1p4scddlkkuw9486579autxumxmkvuphm5pz4jvf7f6pdh50p2uzqstawjt9", chains.BtcMainnetChain().ChainId)) - require.NoError(t, types.ValidateAddressForChain("327z4GyFM8Y8DiYfasGKQWhRK4MvyMSEgE", chains.BtcMainnetChain().ChainId)) - require.NoError(t, types.ValidateAddressForChain("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", chains.BtcMainnetChain().ChainId)) - require.Error(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.BtcMainnetChain().ChainId)) - require.Error(t, types.ValidateAddressForChain("", chains.BtcRegtestChain().ChainId)) - require.NoError(t, types.ValidateAddressForChain("bc1qysd4sp9q8my59ul9wsf5rvs9p387hf8vfwatzu", chains.BtcMainnetChain().ChainId)) - require.NoError(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.BtcRegtestChain().ChainId)) + require.NoError(t, types.ValidateAddressForChain("bc1p4scddlkkuw9486579autxumxmkvuphm5pz4jvf7f6pdh50p2uzqstawjt9", chains.BtcMainnetChain.ChainId)) + require.NoError(t, types.ValidateAddressForChain("327z4GyFM8Y8DiYfasGKQWhRK4MvyMSEgE", chains.BtcMainnetChain.ChainId)) + require.NoError(t, types.ValidateAddressForChain("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3", chains.BtcMainnetChain.ChainId)) + require.Error(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.BtcMainnetChain.ChainId)) + require.Error(t, types.ValidateAddressForChain("", chains.BtcRegtestChain.ChainId)) + require.NoError(t, types.ValidateAddressForChain("bc1qysd4sp9q8my59ul9wsf5rvs9p387hf8vfwatzu", chains.BtcMainnetChain.ChainId)) + require.NoError(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.BtcRegtestChain.ChainId)) // test for zeta chain - require.NoError(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.ZetaChainMainnet().ChainId)) - require.NoError(t, types.ValidateAddressForChain("0x792c127Fa3AC1D52F904056Baf1D9257391e7D78", chains.ZetaChainMainnet().ChainId)) + require.NoError(t, types.ValidateAddressForChain("bcrt1qs758ursh4q9z627kt3pp5yysm78ddny6txaqgw", chains.ZetaChainMainnet.ChainId)) + require.NoError(t, types.ValidateAddressForChain("0x792c127Fa3AC1D52F904056Baf1D9257391e7D78", chains.ZetaChainMainnet.ChainId)) } func TestValidateZetaIndex(t *testing.T) { @@ -38,10 +38,10 @@ func TestValidateZetaIndex(t *testing.T) { } func TestValidateHashForChain(t *testing.T) { - require.NoError(t, types.ValidateHashForChain("0x84bd5c9922b63c52d8a9ca686e0a57ff978150b71be0583514d01c27aa341910", chains.GoerliChain().ChainId)) - require.Error(t, types.ValidateHashForChain("", chains.GoerliChain().ChainId)) - require.Error(t, types.ValidateHashForChain("a0fa5a82f106fb192e4c503bfa8d54b2de20a821e09338094ab825cc9b275059", chains.GoerliChain().ChainId)) - require.NoError(t, types.ValidateHashForChain("15b7880f5d236e857a5e8f043ce9d56f5ef01e1c3f2a786baf740fc0bb7a22a3", chains.BtcMainnetChain().ChainId)) - require.NoError(t, types.ValidateHashForChain("a0fa5a82f106fb192e4c503bfa8d54b2de20a821e09338094ab825cc9b275059", chains.BtcTestNetChain().ChainId)) - require.Error(t, types.ValidateHashForChain("0x84bd5c9922b63c52d8a9ca686e0a57ff978150b71be0583514d01c27aa341910", chains.BtcMainnetChain().ChainId)) + require.NoError(t, types.ValidateHashForChain("0x84bd5c9922b63c52d8a9ca686e0a57ff978150b71be0583514d01c27aa341910", chains.GoerliChain.ChainId)) + require.Error(t, types.ValidateHashForChain("", chains.GoerliChain.ChainId)) + require.Error(t, types.ValidateHashForChain("a0fa5a82f106fb192e4c503bfa8d54b2de20a821e09338094ab825cc9b275059", chains.GoerliChain.ChainId)) + require.NoError(t, types.ValidateHashForChain("15b7880f5d236e857a5e8f043ce9d56f5ef01e1c3f2a786baf740fc0bb7a22a3", chains.BtcMainnetChain.ChainId)) + require.NoError(t, types.ValidateHashForChain("a0fa5a82f106fb192e4c503bfa8d54b2de20a821e09338094ab825cc9b275059", chains.BtcTestNetChain.ChainId)) + require.Error(t, types.ValidateHashForChain("0x84bd5c9922b63c52d8a9ca686e0a57ff978150b71be0583514d01c27aa341910", chains.BtcMainnetChain.ChainId)) } diff --git a/x/lightclient/genesis_test.go b/x/lightclient/genesis_test.go index 049cfbe848..ee083e6e4b 100644 --- a/x/lightclient/genesis_test.go +++ b/x/lightclient/genesis_test.go @@ -26,9 +26,9 @@ func TestGenesis(t *testing.T) { sample.BlockHeader(sample.Hash().Bytes()), }, ChainStates: []types.ChainState{ - sample.ChainState(chains.EthChain().ChainId), - sample.ChainState(chains.BtcMainnetChain().ChainId), - sample.ChainState(chains.BscMainnetChain().ChainId), + sample.ChainState(chains.EthChain.ChainId), + sample.ChainState(chains.BtcMainnetChain.ChainId), + sample.ChainState(chains.BscMainnetChain.ChainId), }, } diff --git a/x/lightclient/keeper/block_header_test.go b/x/lightclient/keeper/block_header_test.go index 2ecf50c1d9..21e7e83f9e 100644 --- a/x/lightclient/keeper/block_header_test.go +++ b/x/lightclient/keeper/block_header_test.go @@ -68,21 +68,21 @@ func sepoliaBlockHeaders(t *testing.T) (proofs.BlockHeader, proofs.BlockHeader, Height: 5000000, Hash: header1.Hash().Bytes(), ParentHash: header1.ParentHash.Bytes(), - ChainId: chains.SepoliaChain().ChainId, + ChainId: chains.SepoliaChain.ChainId, Header: proofs.NewEthereumHeader(headerRLP1), }, proofs.BlockHeader{ Height: 5000001, Hash: header2.Hash().Bytes(), ParentHash: header2.ParentHash.Bytes(), - ChainId: chains.SepoliaChain().ChainId, + ChainId: chains.SepoliaChain.ChainId, Header: proofs.NewEthereumHeader(headerRLP2), }, proofs.BlockHeader{ Height: 5000002, Hash: header3.Hash().Bytes(), ParentHash: header3.ParentHash.Bytes(), - ChainId: chains.SepoliaChain().ChainId, + ChainId: chains.SepoliaChain.ChainId, Header: proofs.NewEthereumHeader(headerRLP3), } } diff --git a/x/lightclient/keeper/proof_test.go b/x/lightclient/keeper/proof_test.go index 810c9a0371..55de17e6b9 100644 --- a/x/lightclient/keeper/proof_test.go +++ b/x/lightclient/keeper/proof_test.go @@ -15,7 +15,7 @@ func TestKeeper_VerifyProof(t *testing.T) { t.Run("should error if verification flags not found", func(t *testing.T) { k, ctx, _, _ := keepertest.LightclientKeeper(t) - _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain().ChainId, sample.Hash().String(), 1) + _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain.ChainId, sample.Hash().String(), 1) require.ErrorIs(t, err, types.ErrVerificationFlagsNotFound) }) @@ -27,7 +27,7 @@ func TestKeeper_VerifyProof(t *testing.T) { BtcTypeChainEnabled: false, }) - _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.BtcMainnetChain().ChainId, sample.Hash().String(), 1) + _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.BtcMainnetChain.ChainId, sample.Hash().String(), 1) require.ErrorIs(t, err, types.ErrBlockHeaderVerificationDisabled) }) @@ -39,7 +39,7 @@ func TestKeeper_VerifyProof(t *testing.T) { BtcTypeChainEnabled: true, }) - _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain().ChainId, sample.Hash().String(), 1) + _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain.ChainId, sample.Hash().String(), 1) require.ErrorIs(t, err, types.ErrBlockHeaderVerificationDisabled) }) @@ -63,7 +63,7 @@ func TestKeeper_VerifyProof(t *testing.T) { BtcTypeChainEnabled: true, }) - _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.BtcMainnetChain().ChainId, "invalid", 1) + _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.BtcMainnetChain.ChainId, "invalid", 1) require.ErrorIs(t, err, types.ErrInvalidBlockHash) }) @@ -75,7 +75,7 @@ func TestKeeper_VerifyProof(t *testing.T) { BtcTypeChainEnabled: true, }) - _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain().ChainId, sample.Hash().String(), 1) + _, err := k.VerifyProof(ctx, &proofs.Proof{}, chains.SepoliaChain.ChainId, sample.Hash().String(), 1) require.ErrorIs(t, err, types.ErrBlockHeaderNotFound) }) diff --git a/x/lightclient/keeper/verification_flags_test.go b/x/lightclient/keeper/verification_flags_test.go index f90f78966a..2466005dcb 100644 --- a/x/lightclient/keeper/verification_flags_test.go +++ b/x/lightclient/keeper/verification_flags_test.go @@ -37,10 +37,10 @@ func TestKeeper_CheckVerificationFlagsEnabled(t *testing.T) { BtcTypeChainEnabled: false, }) - err := k.CheckVerificationFlagsEnabled(ctx, chains.EthChain().ChainId) + err := k.CheckVerificationFlagsEnabled(ctx, chains.EthChain.ChainId) require.NoError(t, err) - err = k.CheckVerificationFlagsEnabled(ctx, chains.BtcMainnetChain().ChainId) + err = k.CheckVerificationFlagsEnabled(ctx, chains.BtcMainnetChain.ChainId) require.Error(t, err) require.ErrorContains(t, err, "proof verification not enabled for bitcoin") @@ -56,11 +56,11 @@ func TestKeeper_CheckVerificationFlagsEnabled(t *testing.T) { BtcTypeChainEnabled: true, }) - err := k.CheckVerificationFlagsEnabled(ctx, chains.EthChain().ChainId) + err := k.CheckVerificationFlagsEnabled(ctx, chains.EthChain.ChainId) require.Error(t, err) require.ErrorContains(t, err, "proof verification not enabled for evm") - err = k.CheckVerificationFlagsEnabled(ctx, chains.BtcMainnetChain().ChainId) + err = k.CheckVerificationFlagsEnabled(ctx, chains.BtcMainnetChain.ChainId) require.NoError(t, err) err = k.CheckVerificationFlagsEnabled(ctx, 1000) diff --git a/x/lightclient/types/genesis_test.go b/x/lightclient/types/genesis_test.go index 1bec10f3be..ee875393ea 100644 --- a/x/lightclient/types/genesis_test.go +++ b/x/lightclient/types/genesis_test.go @@ -32,9 +32,9 @@ func TestGenesisState_Validate(t *testing.T) { sample.BlockHeader(sample.Hash().Bytes()), }, ChainStates: []types.ChainState{ - sample.ChainState(chains.EthChain().ChainId), - sample.ChainState(chains.BtcMainnetChain().ChainId), - sample.ChainState(chains.BscMainnetChain().ChainId), + sample.ChainState(chains.EthChain.ChainId), + sample.ChainState(chains.BtcMainnetChain.ChainId), + sample.ChainState(chains.BscMainnetChain.ChainId), }, }, valid: true, @@ -59,9 +59,9 @@ func TestGenesisState_Validate(t *testing.T) { desc: "duplicate chain state is invalid", genState: &types.GenesisState{ ChainStates: []types.ChainState{ - sample.ChainState(chains.EthChain().ChainId), - sample.ChainState(chains.EthChain().ChainId), - sample.ChainState(chains.BscMainnetChain().ChainId), + sample.ChainState(chains.EthChain.ChainId), + sample.ChainState(chains.EthChain.ChainId), + sample.ChainState(chains.BscMainnetChain.ChainId), }, }, valid: false, diff --git a/x/observer/keeper/grpc_query_chain_params_test.go b/x/observer/keeper/grpc_query_chain_params_test.go index 0e7145e5cd..c8e6f87a8c 100644 --- a/x/observer/keeper/grpc_query_chain_params_test.go +++ b/x/observer/keeper/grpc_query_chain_params_test.go @@ -38,7 +38,7 @@ func TestKeeper_GetChainParamsForChain(t *testing.T) { list := types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.ZetaPrivnetChain().ChainId, + ChainId: chains.ZetaPrivnetChain.ChainId, IsSupported: false, }, }, @@ -46,7 +46,7 @@ func TestKeeper_GetChainParamsForChain(t *testing.T) { k.SetChainParamsList(ctx, list) res, err := k.GetChainParamsForChain(wctx, &types.QueryGetChainParamsForChainRequest{ - ChainId: chains.ZetaPrivnetChain().ChainId, + ChainId: chains.ZetaPrivnetChain.ChainId, }) require.NoError(t, err) require.Equal(t, &types.QueryGetChainParamsForChainResponse{ @@ -81,7 +81,7 @@ func TestKeeper_GetChainParams(t *testing.T) { list := types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.ZetaPrivnetChain().ChainId, + ChainId: chains.ZetaPrivnetChain.ChainId, IsSupported: false, }, }, diff --git a/x/observer/keeper/grpc_query_tss_test.go b/x/observer/keeper/grpc_query_tss_test.go index 105d7c1cf9..601945c22f 100644 --- a/x/observer/keeper/grpc_query_tss_test.go +++ b/x/observer/keeper/grpc_query_tss_test.go @@ -146,10 +146,10 @@ func TestKeeper_GetTssAddress(t *testing.T) { k.SetTSS(ctx, tss) res, err := k.GetTssAddress(wctx, &types.QueryGetTssAddressRequest{ - BitcoinChainId: chains.BtcRegtestChain().ChainId, + BitcoinChainId: chains.BtcRegtestChain.ChainId, }) require.NoError(t, err) - expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain().ChainId) + expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain.ChainId) require.NoError(t, err) expectedBtcAddress, err := crypto.GetTssAddrBTC(tss.TssPubkey, expectedBitcoinParams) require.NoError(t, err) @@ -212,11 +212,11 @@ func TestKeeper_GetTssAddressByFinalizedHeight(t *testing.T) { } res, err := k.GetTssAddressByFinalizedHeight(wctx, &types.QueryGetTssAddressByFinalizedHeightRequest{ - BitcoinChainId: chains.BtcRegtestChain().ChainId, + BitcoinChainId: chains.BtcRegtestChain.ChainId, FinalizedZetaHeight: tssList[r].FinalizedZetaHeight, }) require.NoError(t, err) - expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain().ChainId) + expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain.ChainId) require.NoError(t, err) expectedBtcAddress, err := crypto.GetTssAddrBTC(tssList[r].TssPubkey, expectedBitcoinParams) require.NoError(t, err) diff --git a/x/observer/keeper/msg_server_reset_chain_nonces_test.go b/x/observer/keeper/msg_server_reset_chain_nonces_test.go index e4226968f8..ca64406828 100644 --- a/x/observer/keeper/msg_server_reset_chain_nonces_test.go +++ b/x/observer/keeper/msg_server_reset_chain_nonces_test.go @@ -19,7 +19,7 @@ func TestMsgServer_ResetChainNonces(t *testing.T) { UseAuthorityMock: true, }) srv := keeper.NewMsgServerImpl(*k) - chainId := chains.GoerliLocalnetChain().ChainId + chainId := chains.GoerliLocalnetChain.ChainId admin := sample.AccAddress() authorityMock := keepertest.GetObserverAuthorityMock(t, k) @@ -44,7 +44,7 @@ func TestMsgServer_ResetChainNonces(t *testing.T) { authorityMock := keepertest.GetObserverAuthorityMock(t, k) keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) - chainId := chains.GoerliLocalnetChain().ChainId + chainId := chains.GoerliLocalnetChain.ChainId _, err := srv.ResetChainNonces(sdk.WrapSDKContext(ctx), &types.MsgResetChainNonces{ Creator: admin, ChainId: chainId, @@ -88,8 +88,8 @@ func TestMsgServer_ResetChainNonces(t *testing.T) { keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) - chainId := chains.GoerliLocalnetChain().ChainId - index := chains.GoerliLocalnetChain().ChainName.String() + chainId := chains.GoerliLocalnetChain.ChainId + index := chains.GoerliLocalnetChain.ChainName.String() // check existing chain nonces _, found := k.GetChainNonces(ctx, index) diff --git a/x/observer/keeper/msg_server_vote_block_header_test.go b/x/observer/keeper/msg_server_vote_block_header_test.go index 161d26ff5a..f58ed14299 100644 --- a/x/observer/keeper/msg_server_vote_block_header_test.go +++ b/x/observer/keeper/msg_server_vote_block_header_test.go @@ -66,7 +66,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, IsSupported: true, BallotThreshold: one, }, @@ -75,7 +75,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { _, err := srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: sample.AccAddress(), - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: sample.Hash().Bytes(), Height: 42, Header: proofs.HeaderData{}, @@ -96,7 +96,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, IsSupported: true, BallotThreshold: one, }, @@ -113,7 +113,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { _, err := srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: sample.Hash().Bytes(), Height: 42, Header: proofs.HeaderData{}, @@ -134,7 +134,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, IsSupported: true, BallotThreshold: one, }, @@ -153,7 +153,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { // there is a single node account, so the ballot will be created and finalized in a single vote res, err := srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: sample.Hash().Bytes(), Height: 42, Header: proofs.HeaderData{}, @@ -179,7 +179,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, IsSupported: true, BallotThreshold: one, }, @@ -196,7 +196,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { mockCheckNewBlockHeader(lightclientMock, nil) res, err := srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer1, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: blockHash, Height: 42, Header: proofs.HeaderData{}, @@ -212,7 +212,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { mockCheckNewBlockHeader(lightclientMock, nil) res, err = srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer2, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: blockHash, Height: 42, Header: proofs.HeaderData{}, @@ -229,7 +229,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { mockAddBlockHeader(lightclientMock) res, err = srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer3, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: blockHash, Height: 42, Header: proofs.HeaderData{}, @@ -253,7 +253,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{ { - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, IsSupported: true, BallotThreshold: one, }, @@ -271,7 +271,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { mockCheckNewBlockHeader(lightclientMock, nil) _, err := srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: blockHash, Height: 42, Header: proofs.HeaderData{}, @@ -284,7 +284,7 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { mockCheckNewBlockHeader(lightclientMock, nil) _, err = srv.VoteBlockHeader(ctx, &types.MsgVoteBlockHeader{ Creator: observer, - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, BlockHash: blockHash, Height: 42, Header: proofs.HeaderData{}, diff --git a/x/observer/keeper/msg_server_vote_tss.go b/x/observer/keeper/msg_server_vote_tss.go index 87c7e0b31f..402a84a3db 100644 --- a/x/observer/keeper/msg_server_vote_tss.go +++ b/x/observer/keeper/msg_server_vote_tss.go @@ -73,7 +73,7 @@ func (k msgServer) VoteTSS(goCtx context.Context, msg *types.MsgVoteTSS) (*types // vote the ballot var err error vote := types.VoteType_SuccessObservation - if msg.Status == chains.ReceiveStatus_Failed { + if msg.Status == chains.ReceiveStatus_failed { vote = types.VoteType_FailureObservation } ballot, err = k.AddVoteToBallot(ctx, ballot, msg.Creator, vote) diff --git a/x/observer/keeper/msg_server_vote_tss_test.go b/x/observer/keeper/msg_server_vote_tss_test.go index f7ef851bf9..e92f59cb7e 100644 --- a/x/observer/keeper/msg_server_vote_tss_test.go +++ b/x/observer/keeper/msg_server_vote_tss_test.go @@ -22,7 +22,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: sample.AccAddress(), TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.ErrorIs(t, err, sdkerrors.ErrorInvalidSigner) }) @@ -39,7 +39,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.ErrorIs(t, err, types.ErrKeygenNotFound) }) @@ -59,7 +59,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.ErrorIs(t, err, types.ErrKeygenCompleted) }) @@ -81,7 +81,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.NoError(t, err) @@ -114,7 +114,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Failed, + Status: chains.ReceiveStatus_failed, }) require.NoError(t, err) @@ -152,7 +152,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc1.Operator, TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.NoError(t, err) @@ -171,7 +171,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc2.Operator, TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.NoError(t, err) @@ -190,7 +190,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc3.Operator, TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.NoError(t, err) @@ -224,7 +224,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.NoError(t, err) require.False(t, res.VoteFinalized) @@ -234,7 +234,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, - Status: chains.ReceiveStatus_Success, + Status: chains.ReceiveStatus_success, }) require.ErrorIs(t, err, types.ErrUnableToAddVote) }) diff --git a/x/observer/keeper/utils_test.go b/x/observer/keeper/utils_test.go index 4551e1ca24..3a04c739a3 100644 --- a/x/observer/keeper/utils_test.go +++ b/x/observer/keeper/utils_test.go @@ -33,9 +33,9 @@ func setSupportedChain(ctx sdk.Context, observerKeeper keeper.Keeper, chainIDs . func getValidEthChainIDWithIndex(t *testing.T, index int) int64 { switch index { case 0: - return chains.GoerliLocalnetChain().ChainId + return chains.GoerliLocalnetChain.ChainId case 1: - return chains.GoerliChain().ChainId + return chains.GoerliChain.ChainId default: require.Fail(t, "invalid index") } diff --git a/x/observer/keeper/vote_inbound_test.go b/x/observer/keeper/vote_inbound_test.go index 5b1c09e81b..b271bbfebe 100644 --- a/x/observer/keeper/vote_inbound_test.go +++ b/x/observer/keeper/vote_inbound_test.go @@ -24,7 +24,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err := k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, sample.AccAddress(), "index", @@ -46,7 +46,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err := k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, sample.AccAddress(), "index", @@ -68,7 +68,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err = k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, sample.AccAddress(), "index", @@ -97,7 +97,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err := k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, sample.AccAddress(), "index", @@ -134,7 +134,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err := k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, observer, "index", @@ -151,7 +151,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { IsSupported: true, }, { - ChainId: chains.ZetaPrivnetChain().ChainId, + ChainId: chains.ZetaPrivnetChain.ChainId, IsSupported: false, }, }, @@ -162,7 +162,7 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { _, _, err = k.VoteOnInboundBallot( ctx, getValidEthChainIDWithIndex(t, 0), - chains.ZetaPrivnetChain().ChainId, + chains.ZetaPrivnetChain.ChainId, coin.CoinType_ERC20, observer, "index", diff --git a/x/observer/keeper/vote_outbound_test.go b/x/observer/keeper/vote_outbound_test.go index c92fec5927..72f498d413 100644 --- a/x/observer/keeper/vote_outbound_test.go +++ b/x/observer/keeper/vote_outbound_test.go @@ -21,7 +21,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, sample.AccAddress(), ) require.Error(t, err) @@ -41,7 +41,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, sample.AccAddress(), ) require.Error(t, err) @@ -88,7 +88,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, sample.AccAddress(), ) require.Error(t, err) @@ -120,7 +120,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, observer, ) require.NoError(t, err) @@ -167,7 +167,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, observer, ) require.Error(t, err) @@ -208,7 +208,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, observer, ) require.NoError(t, err) @@ -266,7 +266,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, observer, ) require.NoError(t, err) @@ -322,7 +322,7 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { ctx, "index", getValidEthChainIDWithIndex(t, 0), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, observer, ) require.NoError(t, err) diff --git a/x/observer/types/chain_params.go b/x/observer/types/chain_params.go index e32ee9e597..6c44d6b706 100644 --- a/x/observer/types/chain_params.go +++ b/x/observer/types/chain_params.go @@ -140,7 +140,7 @@ func GetDefaultChainParams() ChainParamsList { func GetDefaultEthMainnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, ConfirmationCount: 14, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -158,7 +158,7 @@ func GetDefaultEthMainnetChainParams() *ChainParams { } func GetDefaultBscMainnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.BscMainnetChain().ChainId, + ChainId: chains.BscMainnetChain.ChainId, ConfirmationCount: 14, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -176,7 +176,7 @@ func GetDefaultBscMainnetChainParams() *ChainParams { } func GetDefaultBtcMainnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.BtcMainnetChain().ChainId, + ChainId: chains.BtcMainnetChain.ChainId, ConfirmationCount: 2, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -194,7 +194,7 @@ func GetDefaultBtcMainnetChainParams() *ChainParams { } func GetDefaultGoerliTestnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.GoerliChain().ChainId, + ChainId: chains.GoerliChain.ChainId, ConfirmationCount: 6, // This is the actual Zeta token Goerli testnet, we need to specify this address for the integration tests to pass ZetaTokenContractAddress: "0x0000c304d2934c00db1d51995b9f6996affd17c0", @@ -213,7 +213,7 @@ func GetDefaultGoerliTestnetChainParams() *ChainParams { } func GetDefaultBscTestnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.BscTestnetChain().ChainId, + ChainId: chains.BscTestnetChain.ChainId, ConfirmationCount: 6, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -231,7 +231,7 @@ func GetDefaultBscTestnetChainParams() *ChainParams { } func GetDefaultMumbaiTestnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.MumbaiChain().ChainId, + ChainId: chains.MumbaiChain.ChainId, ConfirmationCount: 12, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -249,7 +249,7 @@ func GetDefaultMumbaiTestnetChainParams() *ChainParams { } func GetDefaultBtcTestnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.BtcTestNetChain().ChainId, + ChainId: chains.BtcTestNetChain.ChainId, ConfirmationCount: 2, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -267,7 +267,7 @@ func GetDefaultBtcTestnetChainParams() *ChainParams { } func GetDefaultBtcRegtestChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.BtcRegtestChain().ChainId, + ChainId: chains.BtcRegtestChain.ChainId, ConfirmationCount: 1, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, @@ -285,7 +285,7 @@ func GetDefaultBtcRegtestChainParams() *ChainParams { } func GetDefaultGoerliLocalnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.GoerliLocalnetChain().ChainId, + ChainId: chains.GoerliLocalnetChain.ChainId, ConfirmationCount: 1, ZetaTokenContractAddress: "0x733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9", ConnectorContractAddress: "0xD28D6A0b8189305551a0A8bd247a6ECa9CE781Ca", @@ -303,7 +303,7 @@ func GetDefaultGoerliLocalnetChainParams() *ChainParams { } func GetDefaultZetaPrivnetChainParams() *ChainParams { return &ChainParams{ - ChainId: chains.ZetaPrivnetChain().ChainId, + ChainId: chains.ZetaPrivnetChain.ChainId, ConfirmationCount: 1, ZetaTokenContractAddress: zeroAddress, ConnectorContractAddress: zeroAddress, diff --git a/x/observer/types/message_vote_tss.go b/x/observer/types/message_vote_tss.go index bbd8a73e65..ccb3c8b960 100644 --- a/x/observer/types/message_vote_tss.go +++ b/x/observer/types/message_vote_tss.go @@ -50,7 +50,7 @@ func (msg *MsgVoteTSS) ValidateBasic() error { } // either success or observation failure - if msg.Status != chains.ReceiveStatus_Success && msg.Status != chains.ReceiveStatus_Failed { + if msg.Status != chains.ReceiveStatus_success && msg.Status != chains.ReceiveStatus_failed { return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid status: %s", msg.Status) } diff --git a/x/observer/types/message_vote_tss_test.go b/x/observer/types/message_vote_tss_test.go index fb8d92323b..4026ccb018 100644 --- a/x/observer/types/message_vote_tss_test.go +++ b/x/observer/types/message_vote_tss_test.go @@ -19,20 +19,20 @@ func TestMsgVoteTSS_ValidateBasic(t *testing.T) { }{ { name: "valid message", - msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Success), + msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success), }, { name: "valid message with receive status failed", - msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Failed), + msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_failed), }, { name: "invalid creator address", - msg: types.NewMsgVoteTSS("invalid", "pubkey", 1, chains.ReceiveStatus_Success), + msg: types.NewMsgVoteTSS("invalid", "pubkey", 1, chains.ReceiveStatus_success), err: sdkerrors.ErrInvalidAddress, }, { name: "invalid observation status", - msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Created), + msg: types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_created), err: sdkerrors.ErrInvalidRequest, }, } @@ -58,12 +58,12 @@ func TestMsgVoteTSS_GetSigners(t *testing.T) { }{ { name: "valid signer", - msg: types.NewMsgVoteTSS(signer, "pubkey", 1, chains.ReceiveStatus_Success), + msg: types.NewMsgVoteTSS(signer, "pubkey", 1, chains.ReceiveStatus_success), panics: false, }, { name: "invalid signer", - msg: types.NewMsgVoteTSS("invalid", "pubkey", 1, chains.ReceiveStatus_Success), + msg: types.NewMsgVoteTSS("invalid", "pubkey", 1, chains.ReceiveStatus_success), panics: true, }, } @@ -83,23 +83,23 @@ func TestMsgVoteTSS_GetSigners(t *testing.T) { } func TestMsgVoteTSS_Type(t *testing.T) { - msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Success) + msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) require.Equal(t, types.TypeMsgVoteTSS, msg.Type()) } func TestMsgVoteTSS_Route(t *testing.T) { - msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Success) + msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) require.Equal(t, types.RouterKey, msg.Route()) } func TestMsgVoteTSS_GetSignBytes(t *testing.T) { - msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Success) + msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) require.NotPanics(t, func() { msg.GetSignBytes() }) } func TestMsgVoteTSS_Digest(t *testing.T) { - msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_Success) + msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) require.Equal(t, "1-tss-keygen", msg.Digest()) } diff --git a/x/observer/types/observer.pb.go b/x/observer/types/observer.pb.go index ede9e119a5..dabe1e9681 100644 --- a/x/observer/types/observer.pb.go +++ b/x/observer/types/observer.pb.go @@ -87,6 +87,7 @@ func (ObserverUpdateReason) EnumDescriptor() ([]byte, []int) { return fileDescriptor_3004233a4a5969ce, []int{1} } +// Deprecated: Use ObserverSet instead to get the list of observers type ObserverMapper struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` ObserverChain *chains.Chain `protobuf:"bytes,2,opt,name=observer_chain,json=observerChain,proto3" json:"observer_chain,omitempty"` diff --git a/x/observer/types/observer_set.go b/x/observer/types/observer_set.go index 483f28592c..a5ca5661d0 100644 --- a/x/observer/types/observer_set.go +++ b/x/observer/types/observer_set.go @@ -26,9 +26,9 @@ func (m *ObserverSet) Validate() error { func CheckReceiveStatus(status chains.ReceiveStatus) error { switch status { - case chains.ReceiveStatus_Success: + case chains.ReceiveStatus_success: return nil - case chains.ReceiveStatus_Failed: + case chains.ReceiveStatus_failed: return nil default: return ErrInvalidStatus diff --git a/x/observer/types/observer_set_test.go b/x/observer/types/observer_set_test.go index 5efce2cd81..391ecc57b6 100644 --- a/x/observer/types/observer_set_test.go +++ b/x/observer/types/observer_set_test.go @@ -23,10 +23,10 @@ func TestObserverSet(t *testing.T) { } func TestCheckReceiveStatus(t *testing.T) { - err := types.CheckReceiveStatus(chains.ReceiveStatus_Success) + err := types.CheckReceiveStatus(chains.ReceiveStatus_success) require.NoError(t, err) - err = types.CheckReceiveStatus(chains.ReceiveStatus_Failed) + err = types.CheckReceiveStatus(chains.ReceiveStatus_failed) require.NoError(t, err) - err = types.CheckReceiveStatus(chains.ReceiveStatus_Created) + err = types.CheckReceiveStatus(chains.ReceiveStatus_created) require.Error(t, err) } diff --git a/x/observer/types/params.go b/x/observer/types/params.go index ea1db66657..b8479c9f0f 100644 --- a/x/observer/types/params.go +++ b/x/observer/types/params.go @@ -28,9 +28,9 @@ func NewParams(observerParams []*ObserverParams, adminParams []*Admin_Policy, ba // privnet chains are supported by default for testing purposes // custom params must be provided in genesis for other networks func DefaultParams() Params { - chains := chains.PrivnetChainList() - observerParams := make([]*ObserverParams, len(chains)) - for i, chain := range chains { + chainList := chains.ChainListByNetworkType(chains.NetworkType_privnet) + observerParams := make([]*ObserverParams, len(chainList)) + for i, chain := range chainList { observerParams[i] = &ObserverParams{ IsSupported: true, Chain: chain, diff --git a/x/observer/types/parsers.go b/x/observer/types/parsers.go index ad7537e18e..b202c06c2c 100644 --- a/x/observer/types/parsers.go +++ b/x/observer/types/parsers.go @@ -7,9 +7,9 @@ import ( func ConvertReceiveStatusToVoteType(status chains.ReceiveStatus) VoteType { switch status { - case chains.ReceiveStatus_Success: + case chains.ReceiveStatus_success: return VoteType_SuccessObservation - case chains.ReceiveStatus_Failed: + case chains.ReceiveStatus_failed: return VoteType_FailureObservation default: return VoteType_NotYetVoted diff --git a/x/observer/types/parsers_test.go b/x/observer/types/parsers_test.go index 1c108fcee8..50053758a3 100644 --- a/x/observer/types/parsers_test.go +++ b/x/observer/types/parsers_test.go @@ -16,9 +16,9 @@ func TestConvertReceiveStatusToVoteType(t *testing.T) { status chains.ReceiveStatus expected types.VoteType }{ - {"TestSuccessStatus", chains.ReceiveStatus_Success, types.VoteType_SuccessObservation}, - {"TestFailedStatus", chains.ReceiveStatus_Failed, types.VoteType_FailureObservation}, - {"TestDefaultStatus", chains.ReceiveStatus_Created, types.VoteType_NotYetVoted}, + {"TestSuccessStatus", chains.ReceiveStatus_success, types.VoteType_SuccessObservation}, + {"TestFailedStatus", chains.ReceiveStatus_failed, types.VoteType_FailureObservation}, + {"TestDefaultStatus", chains.ReceiveStatus_created, types.VoteType_NotYetVoted}, } for _, tt := range tests { diff --git a/x/observer/types/tx.pb.go b/x/observer/types/tx.pb.go index 87585e885d..233aca98ba 100644 --- a/x/observer/types/tx.pb.go +++ b/x/observer/types/tx.pb.go @@ -1008,7 +1008,7 @@ func (m *MsgVoteTSS) GetStatus() chains.ReceiveStatus { if m != nil { return m.Status } - return chains.ReceiveStatus_Created + return chains.ReceiveStatus_created } type MsgVoteTSSResponse struct { diff --git a/zetaclient/bitcoin/bitcoin_client.go b/zetaclient/bitcoin/bitcoin_client.go index 4f57bc2a7a..194100b119 100644 --- a/zetaclient/bitcoin/bitcoin_client.go +++ b/zetaclient/bitcoin/bitcoin_client.go @@ -642,7 +642,7 @@ func (ob *BTCChainClient) IsOutboundProcessed(cctx *types.CrossChainTx, logger z nil, // gas price not used with Bitcoin 0, // gas limit not used with Bitcoin amountInSat, - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ob.chain, nonce, coin.CoinType_Gas, diff --git a/zetaclient/bitcoin/bitcoin_client_live_test.go b/zetaclient/bitcoin/bitcoin_client_live_test.go index 522b604d19..06d42ba498 100644 --- a/zetaclient/bitcoin/bitcoin_client_live_test.go +++ b/zetaclient/bitcoin/bitcoin_client_live_test.go @@ -46,7 +46,7 @@ func (suite *BitcoinClientTestSuite) SetupTest() { PrivKey: privateKey, } appContext := appcontext.NewAppContext(&corecontext.ZetaCoreContext{}, config.Config{}) - client, err := NewBitcoinClient(appContext, chains.BtcRegtestChain(), nil, tss, tempSQLiteDbPath, + client, err := NewBitcoinClient(appContext, chains.BtcRegtestChain, nil, tss, tempSQLiteDbPath, clientcommon.DefaultLoggers(), config.BTCConfig{}, nil) suite.Require().NoError(err) suite.rpcClient, err = getRPCClient(18332) @@ -365,7 +365,7 @@ func LiveTestGetSenderByVin(t *testing.T) { net, err := chains.GetBTCChainParams(chainID) require.NoError(t, err) testnet := false - if chainID == chains.BtcTestNetChain().ChainId { + if chainID == chains.BtcTestNetChain.ChainId { testnet = true } diff --git a/zetaclient/bitcoin/bitcoin_client_test.go b/zetaclient/bitcoin/bitcoin_client_test.go index 82c7d69917..e3cbeda341 100644 --- a/zetaclient/bitcoin/bitcoin_client_test.go +++ b/zetaclient/bitcoin/bitcoin_client_test.go @@ -34,7 +34,7 @@ func MockBTCClientMainnet() *BTCChainClient { coreContext := corecontext.NewZetaCoreContext(cfg) return &BTCChainClient{ - chain: chains.BtcMainnetChain(), + chain: chains.BtcMainnetChain, zetaClient: stub.NewMockZetaCoreBridge(), Tss: stub.NewTSSMainnet(), coreContext: coreContext, @@ -62,9 +62,9 @@ func TestNewBitcoinClient(t *testing.T) { cfg := config.NewConfig() coreContext := corecontext.NewZetaCoreContext(cfg) appContext := appcontext.NewAppContext(coreContext, cfg) - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain bridge := stub.NewMockZetaCoreBridge() - tss := stub.NewMockTSS(chains.BtcTestNetChain(), sample.EthAddress().String(), "") + tss := stub.NewMockTSS(chains.BtcTestNetChain, sample.EthAddress().String(), "") loggers := clientcommon.ClientLogger{} btcCfg := cfg.BitcoinConfig ts := metrics.NewTelemetryServer() @@ -226,7 +226,7 @@ func TestCalcDepositorFee828440(t *testing.T) { func TestCheckTSSVout(t *testing.T) { // the archived outtx raw result file and cctx file // https://blockstream.info/tx/030cd813443f7b70cc6d8a544d320c6d8465e4528fc0f3410b599dc0b26753a0 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId nonce := uint64(148) @@ -308,7 +308,7 @@ func TestCheckTSSVout(t *testing.T) { func TestCheckTSSVoutCancelled(t *testing.T) { // the archived outtx raw result file and cctx file // https://blockstream.info/tx/030cd813443f7b70cc6d8a544d320c6d8465e4528fc0f3410b599dc0b26753a0 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain chainID := chain.ChainId nonce := uint64(148) @@ -375,7 +375,7 @@ func TestCheckTSSVoutCancelled(t *testing.T) { } func TestGetSenderAddressByVin(t *testing.T) { - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain net := &chaincfg.MainNetParams t.Run("should get sender address from P2TR tx", func(t *testing.T) { @@ -465,7 +465,7 @@ func TestGetSenderAddressByVin(t *testing.T) { func TestGetSenderAddressByVinErrors(t *testing.T) { // https://mempool.space/tx/3618e869f9e87863c0f1cc46dbbaa8b767b4a5d6d60b143c2c50af52b257e867 txHash := "3618e869f9e87863c0f1cc46dbbaa8b767b4a5d6d60b143c2c50af52b257e867" - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain net := &chaincfg.MainNetParams t.Run("should get sender address from P2TR tx", func(t *testing.T) { @@ -499,7 +499,7 @@ func TestGetBtcEvent(t *testing.T) { // load archived intx P2WPKH raw result // https://mempool.space/tx/847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa txHash := "847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa" - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain // GetBtcEvent arguments tx := testutils.LoadBTCIntxRawResult(t, chain.ChainId, txHash, false) @@ -673,7 +673,7 @@ func TestGetBtcEventErrors(t *testing.T) { // load archived intx P2WPKH raw result // https://mempool.space/tx/847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa txHash := "847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa" - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain net := &chaincfg.MainNetParams tssAddress := testutils.TSSAddressBTCMainnet blockNumber := uint64(835640) diff --git a/zetaclient/bitcoin/bitcoin_signer_test.go b/zetaclient/bitcoin/bitcoin_signer_test.go index 96dc48cdff..2115c427a3 100644 --- a/zetaclient/bitcoin/bitcoin_signer_test.go +++ b/zetaclient/bitcoin/bitcoin_signer_test.go @@ -258,7 +258,7 @@ func TestAddWithdrawTxOutputs(t *testing.T) { // receiver addresses receiver := "bc1qaxf82vyzy8y80v000e7t64gpten7gawewzu42y" - to, err := chains.DecodeBtcAddress(receiver, chains.BtcMainnetChain().ChainId) + to, err := chains.DecodeBtcAddress(receiver, chains.BtcMainnetChain.ChainId) require.NoError(t, err) toScript, err := PayToAddrScript(to) require.NoError(t, err) diff --git a/zetaclient/bitcoin/fee_test.go b/zetaclient/bitcoin/fee_test.go index c9276911cf..4b63a9587d 100644 --- a/zetaclient/bitcoin/fee_test.go +++ b/zetaclient/bitcoin/fee_test.go @@ -71,7 +71,7 @@ func generateKeyPair(t *testing.T, net *chaincfg.Params) (*btcec.PrivateKey, btc // getTestAddrScript returns hard coded test address scripts by script type func getTestAddrScript(t *testing.T, scriptType string) btcutil.Address { - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain if inputAddress, ok := testAddressMap[scriptType]; ok { address, err := chains.DecodeBtcAddress(inputAddress, chain.ChainId) require.NoError(t, err) diff --git a/zetaclient/bitcoin/tx_script_test.go b/zetaclient/bitcoin/tx_script_test.go index c29e22c556..ec411de5fc 100644 --- a/zetaclient/bitcoin/tx_script_test.go +++ b/zetaclient/bitcoin/tx_script_test.go @@ -17,7 +17,7 @@ import ( func TestDecodeVoutP2TR(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2TR", txHash)) @@ -35,7 +35,7 @@ func TestDecodeVoutP2TR(t *testing.T) { func TestDecodeVoutP2TRErrors(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2TR", txHash)) @@ -74,7 +74,7 @@ func TestDecodeVoutP2TRErrors(t *testing.T) { func TestDecodeVoutP2WSH(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/791bb9d16f7ab05f70a116d18eaf3552faf77b9d5688699a480261424b4f7e53 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "791bb9d16f7ab05f70a116d18eaf3552faf77b9d5688699a480261424b4f7e53" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2WSH", txHash)) @@ -92,7 +92,7 @@ func TestDecodeVoutP2WSH(t *testing.T) { func TestDecodeVoutP2WSHErrors(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/791bb9d16f7ab05f70a116d18eaf3552faf77b9d5688699a480261424b4f7e53 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "791bb9d16f7ab05f70a116d18eaf3552faf77b9d5688699a480261424b4f7e53" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2WSH", txHash)) @@ -131,7 +131,7 @@ func TestDecodeVoutP2WSHErrors(t *testing.T) { func TestDecodeP2WPKHVout(t *testing.T) { // load archived outtx raw result // https://mempool.space/tx/030cd813443f7b70cc6d8a544d320c6d8465e4528fc0f3410b599dc0b26753a0 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain nonce := uint64(148) net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCOuttx(chain.ChainId, nonce)) @@ -159,7 +159,7 @@ func TestDecodeP2WPKHVout(t *testing.T) { func TestDecodeP2WPKHVoutErrors(t *testing.T) { // load archived outtx raw result // https://mempool.space/tx/030cd813443f7b70cc6d8a544d320c6d8465e4528fc0f3410b599dc0b26753a0 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain nonce := uint64(148) net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCOuttx(chain.ChainId, nonce)) @@ -191,7 +191,7 @@ func TestDecodeP2WPKHVoutErrors(t *testing.T) { func TestDecodeVoutP2SH(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/fd68c8b4478686ca6f5ae4c28eaab055490650dbdaa6c2c8e380a7e075958a21 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "fd68c8b4478686ca6f5ae4c28eaab055490650dbdaa6c2c8e380a7e075958a21" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2SH", txHash)) @@ -209,7 +209,7 @@ func TestDecodeVoutP2SH(t *testing.T) { func TestDecodeVoutP2SHErrors(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/fd68c8b4478686ca6f5ae4c28eaab055490650dbdaa6c2c8e380a7e075958a21 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "fd68c8b4478686ca6f5ae4c28eaab055490650dbdaa6c2c8e380a7e075958a21" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2SH", txHash)) @@ -254,7 +254,7 @@ func TestDecodeVoutP2SHErrors(t *testing.T) { func TestDecodeVoutP2PKH(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/9c741de6e17382b7a9113fc811e3558981a35a360e3d1262a6675892c91322ca - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "9c741de6e17382b7a9113fc811e3558981a35a360e3d1262a6675892c91322ca" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2PKH", txHash)) @@ -272,7 +272,7 @@ func TestDecodeVoutP2PKH(t *testing.T) { func TestDecodeVoutP2PKHErrors(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/9c741de6e17382b7a9113fc811e3558981a35a360e3d1262a6675892c91322ca - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "9c741de6e17382b7a9113fc811e3558981a35a360e3d1262a6675892c91322ca" net := &chaincfg.MainNetParams nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2PKH", txHash)) @@ -332,7 +332,7 @@ func TestDecodeVoutP2PKHErrors(t *testing.T) { func TestDecodeOpReturnMemo(t *testing.T) { // load archived intx raw result // https://mempool.space/tx/847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "847139aa65aa4a5ee896375951cbf7417cfc8a4d6f277ec11f40cd87319f04aa" scriptHex := "6a1467ed0bcc4e1256bc2ce87d22e190d63a120114bf" rawResult := testutils.LoadBTCIntxRawResult(t, chain.ChainId, txHash, false) @@ -404,7 +404,7 @@ func TestDecodeOpReturnMemoErrors(t *testing.T) { } func TestDecodeTSSVout(t *testing.T) { - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain t.Run("should decode P2TR vout", func(t *testing.T) { // https://mempool.space/tx/259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7 @@ -476,7 +476,7 @@ func TestDecodeTSSVout(t *testing.T) { func TestDecodeTSSVoutErrors(t *testing.T) { // load archived tx raw result // https://mempool.space/tx/259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7 - chain := chains.BtcMainnetChain() + chain := chains.BtcMainnetChain txHash := "259fc21e63e138136c8f19270a0f7ca10039a66a474f91d23a17896f46e677a7" nameTx := path.Join("../", testutils.TestDataPathBTC, testutils.FileNameBTCTxByType(chain.ChainId, "P2TR", txHash)) @@ -504,7 +504,7 @@ func TestDecodeTSSVoutErrors(t *testing.T) { t.Run("should return error when invalid receiver passed", func(t *testing.T) { invalidVout := rawResult.Vout[0] // use testnet params to decode mainnet receiver - wrongChain := chains.BtcTestNetChain() + wrongChain := chains.BtcTestNetChain receiver, amount, err := DecodeTSSVout(invalidVout, "bc1qulmx8ej27cj0xe20953cztr2excnmsqvuh0s5c", wrongChain) require.ErrorContains(t, err, "error decoding receiver") require.Empty(t, receiver) diff --git a/zetaclient/compliance/compliance_test.go b/zetaclient/compliance/compliance_test.go index c88e3b5da8..1f4fe468bf 100644 --- a/zetaclient/compliance/compliance_test.go +++ b/zetaclient/compliance/compliance_test.go @@ -12,7 +12,7 @@ import ( func TestCctxRestricted(t *testing.T) { // load archived cctx - chain := chains.EthChain() + chain := chains.EthChain cctx := testutils.LoadCctxByNonce(t, chain.ChainId, 6270) // create config diff --git a/zetaclient/config/config_chain.go b/zetaclient/config/config_chain.go index bb414c6161..f8d0f0f069 100644 --- a/zetaclient/config/config_chain.go +++ b/zetaclient/config/config_chain.go @@ -36,30 +36,30 @@ var bitcoinConfigRegnet = BTCConfig{ } var evmChainsConfigs = map[int64]EVMConfig{ - chains.EthChain().ChainId: { - Chain: chains.EthChain(), + chains.EthChain.ChainId: { + Chain: chains.EthChain, }, - chains.BscMainnetChain().ChainId: { - Chain: chains.BscMainnetChain(), + chains.BscMainnetChain.ChainId: { + Chain: chains.BscMainnetChain, }, - chains.GoerliChain().ChainId: { - Chain: chains.GoerliChain(), + chains.GoerliChain.ChainId: { + Chain: chains.GoerliChain, Endpoint: "", }, - chains.SepoliaChain().ChainId: { - Chain: chains.SepoliaChain(), + chains.SepoliaChain.ChainId: { + Chain: chains.SepoliaChain, Endpoint: "", }, - chains.BscTestnetChain().ChainId: { - Chain: chains.BscTestnetChain(), + chains.BscTestnetChain.ChainId: { + Chain: chains.BscTestnetChain, Endpoint: "", }, - chains.MumbaiChain().ChainId: { - Chain: chains.MumbaiChain(), + chains.MumbaiChain.ChainId: { + Chain: chains.MumbaiChain, Endpoint: "", }, - chains.GoerliLocalnetChain().ChainId: { - Chain: chains.GoerliLocalnetChain(), + chains.GoerliLocalnetChain.ChainId: { + Chain: chains.GoerliLocalnetChain, Endpoint: "http://eth:8545", }, } diff --git a/zetaclient/core_context/zeta_core_context_test.go b/zetaclient/core_context/zeta_core_context_test.go index 93b0e1c57f..e9fb129023 100644 --- a/zetaclient/core_context/zeta_core_context_test.go +++ b/zetaclient/core_context/zeta_core_context_test.go @@ -261,7 +261,7 @@ func TestUpdateZetaCoreContext(t *testing.T) { }, } - testBtcChain := chains.BtcTestNetChain() + testBtcChain := chains.BtcTestNetChain btcChainParamsToUpdate := &observertypes.ChainParams{ ChainId: testBtcChain.ChainId, } @@ -320,7 +320,7 @@ func TestUpdateZetaCoreContext(t *testing.T) { func TestIsOutboundObservationEnabled(t *testing.T) { // create test chain params and flags - evmChain := chains.EthChain() + evmChain := chains.EthChain ccFlags := *sample.CrosschainFlags() verificationFlags := sample.VerificationFlags() chainParams := &observertypes.ChainParams{ @@ -350,7 +350,7 @@ func TestIsOutboundObservationEnabled(t *testing.T) { func TestIsInboundObservationEnabled(t *testing.T) { // create test chain params and flags - evmChain := chains.EthChain() + evmChain := chains.EthChain ccFlags := *sample.CrosschainFlags() verificationFlags := sample.VerificationFlags() chainParams := &observertypes.ChainParams{ diff --git a/zetaclient/evm/evm_client.go b/zetaclient/evm/evm_client.go index f86211fe60..03411366de 100644 --- a/zetaclient/evm/evm_client.go +++ b/zetaclient/evm/evm_client.go @@ -367,9 +367,9 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, // compliance check, special handling the cancelled cctx if compliance.IsCctxRestricted(cctx) { - recvStatus := chains.ReceiveStatus_Failed + recvStatus := chains.ReceiveStatus_failed if receipt.Status == 1 { - recvStatus = chains.ReceiveStatus_Success + recvStatus = chains.ReceiveStatus_success } zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( sendHash, @@ -394,9 +394,9 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, } if cointype == coin.CoinType_Cmd { - recvStatus := chains.ReceiveStatus_Failed + recvStatus := chains.ReceiveStatus_failed if receipt.Status == 1 { - recvStatus = chains.ReceiveStatus_Success + recvStatus = chains.ReceiveStatus_success } zetaTxHash, ballot, err := ob.zetaBridge.PostVoteOutbound( sendHash, @@ -428,7 +428,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), transaction.Value(), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ob.chain, nonce, coin.CoinType_Gas, @@ -449,7 +449,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), big.NewInt(0), - chains.ReceiveStatus_Failed, + chains.ReceiveStatus_failed, ob.chain, nonce, coin.CoinType_Gas, @@ -493,7 +493,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), mMint, - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ob.chain, nonce, coin.CoinType_Zeta, @@ -530,7 +530,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), mMint, - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ob.chain, nonce, coin.CoinType_Zeta, @@ -558,7 +558,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), big.NewInt(0), - chains.ReceiveStatus_Failed, + chains.ReceiveStatus_failed, ob.chain, nonce, coin.CoinType_Zeta, @@ -598,7 +598,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), event.Amount, - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ob.chain, nonce, coin.CoinType_ERC20, @@ -625,7 +625,7 @@ func (ob *ChainClient) IsSendOutTxProcessed(cctx *crosschaintypes.CrossChainTx, transaction.GasPrice(), transaction.Gas(), big.NewInt(0), - chains.ReceiveStatus_Failed, + chains.ReceiveStatus_failed, ob.chain, nonce, coin.CoinType_ERC20, diff --git a/zetaclient/evm/evm_client_test.go b/zetaclient/evm/evm_client_test.go index e71bfd49ed..6b195ab85c 100644 --- a/zetaclient/evm/evm_client_test.go +++ b/zetaclient/evm/evm_client_test.go @@ -185,7 +185,7 @@ func TestEVM_VoteOutboundBallot(t *testing.T) { math.NewIntFromBigInt(tx.GasPrice()), tx.Gas(), math.NewUintFromBigInt(tx.Value()), - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, chainID, tx.Nonce(), coinType, diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index 9c2b0e1716..9fb5551aff 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -710,7 +710,7 @@ func (signer *Signer) reportToOutTxTracker(zetaBridge interfaces.ZetaCoreBridger // getEVMRPC is a helper function to set up the client and signer, also initializes a mock client for unit tests func getEVMRPC(endpoint string) (interfaces.EVMRPCClient, ethtypes.Signer, error) { if endpoint == stub.EVMRPCEnabled { - chainID := big.NewInt(chains.BscMainnetChain().ChainId) + chainID := big.NewInt(chains.BscMainnetChain.ChainId) ethSigner := ethtypes.NewLondonSigner(chainID) client := &stub.MockEvmClient{} return client, ethSigner, nil diff --git a/zetaclient/evm/evm_signer_test.go b/zetaclient/evm/evm_signer_test.go index 03e014adde..15c3657cc9 100644 --- a/zetaclient/evm/evm_signer_test.go +++ b/zetaclient/evm/evm_signer_test.go @@ -34,7 +34,7 @@ func getNewEvmSigner() (*Signer, error) { ts := &metrics.TelemetryServer{} cfg := config.NewConfig() return NewEVMSigner( - chains.BscMainnetChain(), + chains.BscMainnetChain, stub.EVMRPCEnabled, stub.NewTSSMainnet(), config.GetConnectorABI(), @@ -52,8 +52,8 @@ func getNewEvmChainClient() (*ChainClient, error) { cfg := config.NewConfig() tss := stub.NewTSSMainnet() - evmcfg := config.EVMConfig{Chain: chains.BscMainnetChain(), Endpoint: "http://localhost:8545"} - cfg.EVMChainConfigs[chains.BscMainnetChain().ChainId] = evmcfg + evmcfg := config.EVMConfig{Chain: chains.BscMainnetChain, Endpoint: "http://localhost:8545"} + cfg.EVMChainConfigs[chains.BscMainnetChain.ChainId] = evmcfg coreCTX := corecontext.NewZetaCoreContext(cfg) appCTX := appcontext.NewAppContext(coreCTX, cfg) diff --git a/zetaclient/evm/inbounds_test.go b/zetaclient/evm/inbounds_test.go index 645a87d108..223c2f5daf 100644 --- a/zetaclient/evm/inbounds_test.go +++ b/zetaclient/evm/inbounds_test.go @@ -21,7 +21,7 @@ import ( func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { // load archived ZetaSent intx, receipt and cctx // https://etherscan.io/tx/0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76 - chain := chains.EthChain() + chain := chains.EthChain confirmation := uint64(10) chainID := chain.ChainId chainParam := stub.MockChainParams(chain.ChainId, confirmation) @@ -72,7 +72,7 @@ func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { // load archived ERC20 intx, receipt and cctx // https://etherscan.io/tx/0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da - chain := chains.EthChain() + chain := chains.EthChain confirmation := uint64(10) chainID := chain.ChainId chainParam := stub.MockChainParams(chain.ChainId, confirmation) @@ -123,7 +123,7 @@ func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { // load archived Gas intx, receipt and cctx // https://etherscan.io/tx/0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532 - chain := chains.EthChain() + chain := chains.EthChain confirmation := uint64(10) chainID := chain.ChainId chainParam := stub.MockChainParams(chain.ChainId, confirmation) @@ -187,7 +187,7 @@ func TestEVM_BuildInboundVoteMsgForZetaSentEvent(t *testing.T) { // load archived ZetaSent receipt // https://etherscan.io/tx/0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76 chainID := int64(1) - chain := chains.EthChain() + chain := chains.EthChain intxHash := "0xf3935200c80f98502d5edc7e871ffc40ca898e134525c42c2ae3cbc5725f9d76" receipt := testutils.LoadEVMIntxReceipt(t, chainID, intxHash, coin.CoinType_Zeta) cctx := testutils.LoadCctxByIntx(t, chainID, coin.CoinType_Zeta, intxHash) @@ -233,7 +233,7 @@ func TestEVM_BuildInboundVoteMsgForZetaSentEvent(t *testing.T) { func TestEVM_BuildInboundVoteMsgForDepositedEvent(t *testing.T) { // load archived Deposited receipt // https://etherscan.io/tx/0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId intxHash := "0x4ea69a0e2ff36f7548ab75791c3b990e076e2a4bffeb616035b239b7d33843da" tx, receipt := testutils.LoadEVMIntxNReceipt(t, chainID, intxHash, coin.CoinType_ERC20) @@ -278,7 +278,7 @@ func TestEVM_BuildInboundVoteMsgForDepositedEvent(t *testing.T) { func TestEVM_BuildInboundVoteMsgForTokenSentToTSS(t *testing.T) { // load archived gas token transfer to TSS // https://etherscan.io/tx/0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532 - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId intxHash := "0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532" tx, receipt := testutils.LoadEVMIntxNReceipt(t, chainID, intxHash, coin.CoinType_Gas) @@ -327,7 +327,7 @@ func TestEVM_BuildInboundVoteMsgForTokenSentToTSS(t *testing.T) { func TestEVM_ObserveTSSReceiveInBlock(t *testing.T) { // https://etherscan.io/tx/0xeaec67d5dd5d85f27b21bef83e01cbdf59154fd793ea7a22c297f7c3a722c532 - chain := chains.EthChain() + chain := chains.EthChain chainID := chain.ChainId confirmation := uint64(1) chainParam := stub.MockChainParams(chain.ChainId, confirmation) diff --git a/zetaclient/evm/outbound_transaction_data_test.go b/zetaclient/evm/outbound_transaction_data_test.go index 85c812119b..6effd80f34 100644 --- a/zetaclient/evm/outbound_transaction_data_test.go +++ b/zetaclient/evm/outbound_transaction_data_test.go @@ -51,14 +51,14 @@ func TestSigner_SetupGas(t *testing.T) { logger := zerolog.Logger{} t.Run("SetupGas_success", func(t *testing.T) { - chain := chains.BscMainnetChain() + chain := chains.BscMainnetChain err := txData.SetupGas(cctx, logger, evmSigner.EvmClient(), &chain) require.NoError(t, err) }) t.Run("SetupGas_error", func(t *testing.T) { cctx.GetCurrentOutTxParam().OutboundTxGasPrice = "invalidGasPrice" - chain := chains.BscMainnetChain() + chain := chains.BscMainnetChain err := txData.SetupGas(cctx, logger, evmSigner.EvmClient(), &chain) require.ErrorContains(t, err, "cannot convert gas price") }) diff --git a/zetaclient/evm/outbounds.go b/zetaclient/evm/outbounds.go index 081616256e..7811e1ddb9 100644 --- a/zetaclient/evm/outbounds.go +++ b/zetaclient/evm/outbounds.go @@ -81,9 +81,9 @@ func (ob *ChainClient) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, l if compliance.IsCctxRestricted(cctx) { // use cctx's amount to bypass the amount check in zetacore receiveValue = cctx.GetCurrentOutTxParam().Amount.BigInt() - receiveStatus := chains.ReceiveStatus_Failed + receiveStatus := chains.ReceiveStatus_failed if receipt.Status == ethtypes.ReceiptStatusSuccessful { - receiveStatus = chains.ReceiveStatus_Success + receiveStatus = chains.ReceiveStatus_success } ob.PostVoteOutbound(cctx.Index, receipt, transaction, receiveValue, receiveStatus, nonce, cointype, logger) return true, true, nil @@ -205,10 +205,10 @@ func ParseOuttxReceivedValue( // determine the receive status and value // https://docs.nethereum.com/en/latest/nethereum-receipt-status/ receiveValue := big.NewInt(0) - receiveStatus := chains.ReceiveStatus_Failed + receiveStatus := chains.ReceiveStatus_failed if receipt.Status == ethtypes.ReceiptStatusSuccessful { receiveValue = transaction.Value() - receiveStatus = chains.ReceiveStatus_Success + receiveStatus = chains.ReceiveStatus_success } // parse receive value from the outtx receipt for Zeta and ERC20 @@ -217,7 +217,7 @@ func ParseOuttxReceivedValue( if receipt.Status == ethtypes.ReceiptStatusSuccessful { receivedLog, revertedLog, err := ParseAndCheckZetaEvent(cctx, receipt, connectorAddress, connector) if err != nil { - return nil, chains.ReceiveStatus_Failed, err + return nil, chains.ReceiveStatus_failed, err } // use the value in ZetaReceived/ZetaReverted event for vote message if receivedLog != nil { @@ -230,7 +230,7 @@ func ParseOuttxReceivedValue( if receipt.Status == ethtypes.ReceiptStatusSuccessful { withdrawn, err := ParseAndCheckWithdrawnEvent(cctx, receipt, custodyAddress, custody) if err != nil { - return nil, chains.ReceiveStatus_Failed, err + return nil, chains.ReceiveStatus_failed, err } // use the value in Withdrawn event for vote message receiveValue = withdrawn.Amount @@ -238,7 +238,7 @@ func ParseOuttxReceivedValue( case coin.CoinType_Gas, coin.CoinType_Cmd: // nothing to do for CoinType_Gas/CoinType_Cmd, no need to parse event default: - return nil, chains.ReceiveStatus_Failed, fmt.Errorf("unknown coin type %s", cointype) + return nil, chains.ReceiveStatus_failed, fmt.Errorf("unknown coin type %s", cointype) } return receiveValue, receiveStatus, nil } diff --git a/zetaclient/evm/outbounds_test.go b/zetaclient/evm/outbounds_test.go index 30f523614f..b582323d11 100644 --- a/zetaclient/evm/outbounds_test.go +++ b/zetaclient/evm/outbounds_test.go @@ -30,8 +30,8 @@ func getContractsByChainID(chainID int64) (*zetaconnector.ZetaConnectorNonEth, e func Test_IsOutboundProcessed(t *testing.T) { // load archived outtx receipt that contains ZetaReceived event // https://etherscan.io/tx/0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f - chain := chains.EthChain() - chainID := chains.EthChain().ChainId + chain := chains.EthChain + chainID := chains.EthChain.ChainId nonce := uint64(9718) chainParam := stub.MockChainParams(chain.ChainId, 1) outtxHash := "0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f" @@ -107,8 +107,8 @@ func Test_IsOutboundProcessed_ContractError(t *testing.T) { // load archived outtx receipt that contains ZetaReceived event // https://etherscan.io/tx/0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f - chain := chains.EthChain() - chainID := chains.EthChain().ChainId + chain := chains.EthChain + chainID := chains.EthChain.ChainId nonce := uint64(9718) chainParam := stub.MockChainParams(chain.ChainId, 1) outtxHash := "0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f" @@ -145,7 +145,7 @@ func Test_PostVoteOutbound(t *testing.T) { // Note: outtx of Gas/ERC20 token can also be used for this test // load archived cctx, outtx and receipt for a ZetaReceived event // https://etherscan.io/tx/0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f - chain := chains.EthChain() + chain := chains.EthChain nonce := uint64(9718) coinType := coin.CoinType_Zeta cctx, outtx, receipt := testutils.LoadEVMCctxNOuttxNReceipt(t, chain.ChainId, nonce, testutils.EventZetaReceived) @@ -153,7 +153,7 @@ func Test_PostVoteOutbound(t *testing.T) { t.Run("post vote outbound successfully", func(t *testing.T) { // the amount and status to be used for vote receiveValue := cctx.GetCurrentOutTxParam().Amount.BigInt() - receiveStatus := chains.ReceiveStatus_Success + receiveStatus := chains.ReceiveStatus_success // create evm client using mock zetaBridge and post outbound vote zetaBridge := stub.NewMockZetaCoreBridge() @@ -169,7 +169,7 @@ func Test_PostVoteOutbound(t *testing.T) { func Test_ParseZetaReceived(t *testing.T) { // load archived outtx receipt that contains ZetaReceived event // https://etherscan.io/tx/0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f - chainID := chains.EthChain().ChainId + chainID := chains.EthChain.ChainId nonce := uint64(9718) outtxHash := "0x81342051b8a85072d3e3771c1a57c7bdb5318e8caf37f5a687b7a91e50a7257f" connector := stub.MockConnectorNonEth(chainID) @@ -230,7 +230,7 @@ func Test_ParseZetaReceived(t *testing.T) { func Test_ParseZetaReverted(t *testing.T) { // load archived outtx receipt that contains ZetaReverted event - chainID := chains.GoerliLocalnetChain().ChainId + chainID := chains.GoerliLocalnetChain.ChainId nonce := uint64(14) outtxHash := "0x1487e6a31dd430306667250b72bf15b8390b73108b69f3de5c1b2efe456036a7" connector := stub.MockConnectorNonEth(chainID) @@ -282,7 +282,7 @@ func Test_ParseZetaReverted(t *testing.T) { func Test_ParseERC20WithdrawnEvent(t *testing.T) { // load archived outtx receipt that contains ERC20 Withdrawn event - chainID := chains.EthChain().ChainId + chainID := chains.EthChain.ChainId nonce := uint64(8014) outtxHash := "0xd2eba7ac3da1b62800165414ea4bcaf69a3b0fb9b13a0fc32f4be11bfef79146" custody := stub.MockERC20Custody(chainID) @@ -338,7 +338,7 @@ func Test_ParseERC20WithdrawnEvent(t *testing.T) { } func Test_ParseOuttxReceivedValue(t *testing.T) { - chainID := chains.EthChain().ChainId + chainID := chains.EthChain.ChainId connector, connectorAddr, custody, custodyAddr := getContractsByChainID(chainID) t.Run("should parse and check ZetaReceived event from archived outtx receipt", func(t *testing.T) { @@ -351,12 +351,12 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, connectorAddr, connector, custodyAddr, custody) require.NoError(t, err) require.True(t, params.Amount.BigInt().Cmp(value) == 0) - require.Equal(t, chains.ReceiveStatus_Success, status) + require.Equal(t, chains.ReceiveStatus_success, status) }) t.Run("should parse and check ZetaReverted event from archived outtx receipt", func(t *testing.T) { // load archived outtx receipt that contains ZetaReverted event // use local network tx: 0x1487e6a31dd430306667250b72bf15b8390b73108b69f3de5c1b2efe456036a7 - localChainID := chains.GoerliLocalnetChain().ChainId + localChainID := chains.GoerliLocalnetChain.ChainId nonce := uint64(14) coinType := coin.CoinType_Zeta connectorLocal, connectorAddrLocal, custodyLocal, custodyAddrLocal := getContractsByChainID(localChainID) @@ -366,7 +366,7 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { cctx, receipt, outtx, coinType, connectorAddrLocal, connectorLocal, custodyAddrLocal, custodyLocal) require.NoError(t, err) require.True(t, params.Amount.BigInt().Cmp(value) == 0) - require.Equal(t, chains.ReceiveStatus_Success, status) + require.Equal(t, chains.ReceiveStatus_success, status) }) t.Run("should parse and check ERC20 Withdrawn event from archived outtx receipt", func(t *testing.T) { // load archived outtx receipt that contains ERC20 Withdrawn event @@ -378,7 +378,7 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, connectorAddr, connector, custodyAddr, custody) require.NoError(t, err) require.True(t, params.Amount.BigInt().Cmp(value) == 0) - require.Equal(t, chains.ReceiveStatus_Success, status) + require.Equal(t, chains.ReceiveStatus_success, status) }) t.Run("nothing to parse if coinType is Gas", func(t *testing.T) { // load archived outtx receipt of Gas token transfer @@ -390,7 +390,7 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, connectorAddr, connector, custodyAddr, custody) require.NoError(t, err) require.True(t, params.Amount.BigInt().Cmp(value) == 0) - require.Equal(t, chains.ReceiveStatus_Success, status) + require.Equal(t, chains.ReceiveStatus_success, status) }) t.Run("should fail on unknown coin type", func(t *testing.T) { // load archived outtx receipt that contains ZetaReceived event @@ -401,7 +401,7 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, connectorAddr, connector, custodyAddr, custody) require.ErrorContains(t, err, "unknown coin type") require.Nil(t, value) - require.Equal(t, chains.ReceiveStatus_Failed, status) + require.Equal(t, chains.ReceiveStatus_failed, status) }) t.Run("should fail if unable to parse ZetaReceived event", func(t *testing.T) { // load archived outtx receipt that contains ZetaReceived event @@ -415,7 +415,7 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, fakeConnectorAddress, connector, custodyAddr, custody) require.Error(t, err) require.Nil(t, value) - require.Equal(t, chains.ReceiveStatus_Failed, status) + require.Equal(t, chains.ReceiveStatus_failed, status) }) t.Run("should fail if unable to parse ERC20 Withdrawn event", func(t *testing.T) { // load archived outtx receipt that contains ERC20 Withdrawn event @@ -429,6 +429,6 @@ func Test_ParseOuttxReceivedValue(t *testing.T) { value, status, err := evm.ParseOuttxReceivedValue(cctx, receipt, outtx, coinType, connectorAddr, connector, fakeCustodyAddress, custody) require.Error(t, err) require.Nil(t, value) - require.Equal(t, chains.ReceiveStatus_Failed, status) + require.Equal(t, chains.ReceiveStatus_failed, status) }) } diff --git a/zetaclient/testutils/stub/tss_signer.go b/zetaclient/testutils/stub/tss_signer.go index 0f6d9787e6..bda2d34082 100644 --- a/zetaclient/testutils/stub/tss_signer.go +++ b/zetaclient/testutils/stub/tss_signer.go @@ -40,11 +40,11 @@ func NewMockTSS(chain chains.Chain, evmAddress string, btcAddress string) *TSS { } func NewTSSMainnet() *TSS { - return NewMockTSS(chains.BtcMainnetChain(), testutils.TSSAddressEVMMainnet, testutils.TSSAddressBTCMainnet) + return NewMockTSS(chains.BtcMainnetChain, testutils.TSSAddressEVMMainnet, testutils.TSSAddressBTCMainnet) } func NewTSSAthens3() *TSS { - return NewMockTSS(chains.BscTestnetChain(), testutils.TSSAddressEVMAthens3, testutils.TSSAddressBTCAthens3) + return NewMockTSS(chains.BscTestnetChain, testutils.TSSAddressEVMAthens3, testutils.TSSAddressBTCAthens3) } // Sign uses test key unrelated to any tss key in production diff --git a/zetaclient/zetabridge/broadcast_test.go b/zetaclient/zetabridge/broadcast_test.go index 4d838358b0..2a4d341db4 100644 --- a/zetaclient/zetabridge/broadcast_test.go +++ b/zetaclient/zetabridge/broadcast_test.go @@ -79,7 +79,7 @@ func TestBroadcast(t *testing.T) { zetabridge.EnableMockSDKClient(stub.NewSDKClientWithErr(nil, 0)) blockHash, err := hex.DecodeString(ethBlockHash) require.NoError(t, err) - msg := observerTypes.NewMsgVoteBlockHeader(address.String(), chains.EthChain().ChainId, blockHash, 18495266, getHeaderData(t)) + msg := observerTypes.NewMsgVoteBlockHeader(address.String(), chains.EthChain.ChainId, blockHash, 18495266, getHeaderData(t)) authzMsg, authzSigner, err := zetabridge.WrapMessageWithAuthz(msg) require.NoError(t, err) _, err = BroadcastToZetaCore(zetabridge, 10000, authzMsg, authzSigner) @@ -90,7 +90,7 @@ func TestBroadcast(t *testing.T) { zetabridge.EnableMockSDKClient(stub.NewSDKClientWithErr(errors.New("account sequence mismatch, expected 5 got 4"), 32)) blockHash, err := hex.DecodeString(ethBlockHash) require.NoError(t, err) - msg := observerTypes.NewMsgVoteBlockHeader(address.String(), chains.EthChain().ChainId, blockHash, 18495266, getHeaderData(t)) + msg := observerTypes.NewMsgVoteBlockHeader(address.String(), chains.EthChain.ChainId, blockHash, 18495266, getHeaderData(t)) authzMsg, authzSigner, err := zetabridge.WrapMessageWithAuthz(msg) require.NoError(t, err) _, err = BroadcastToZetaCore(zetabridge, 10000, authzMsg, authzSigner) diff --git a/zetaclient/zetabridge/query_test.go b/zetaclient/zetabridge/query_test.go index 556bb83101..2272ca9be4 100644 --- a/zetaclient/zetabridge/query_test.go +++ b/zetaclient/zetabridge/query_test.go @@ -399,7 +399,7 @@ func TestZetaCoreBridge_GetNodeInfo(t *testing.T) { } func TestZetaCoreBridge_GetLastBlockHeightByChain(t *testing.T) { - index := chains.BscMainnetChain() + index := chains.BscMainnetChain expectedOutput := crosschainTypes.QueryGetLastBlockHeightResponse{ LastBlockHeight: &crosschainTypes.LastBlockHeight{ Index: index.ChainName.String(), @@ -461,7 +461,7 @@ func TestZetaCoreBridge_GetBaseGasPrice(t *testing.T) { } func TestZetaCoreBridge_GetNonceByChain(t *testing.T) { - chain := chains.BscMainnetChain() + chain := chains.BscMainnetChain expectedOutput := observertypes.QueryGetChainNoncesResponse{ ChainNonces: observertypes.ChainNonces{ Creator: "", @@ -551,7 +551,7 @@ func TestZetaCoreBridge_GetBallotByID(t *testing.T) { } func TestZetaCoreBridge_GetInboundTrackersForChain(t *testing.T) { - chainID := chains.BscMainnetChain().ChainId + chainID := chains.BscMainnetChain.ChainId expectedOutput := crosschainTypes.QueryAllInTxTrackerByChainResponse{ InTxTracker: []crosschainTypes.InTxTracker{ { @@ -664,7 +664,7 @@ func TestZetaCoreBridge_GetTssHistory(t *testing.T) { } func TestZetaCoreBridge_GetOutTxTracker(t *testing.T) { - chain := chains.BscMainnetChain() + chain := chains.BscMainnetChain expectedOutput := crosschainTypes.QueryGetOutTxTrackerResponse{ OutTxTracker: crosschainTypes.OutTxTracker{ Index: "tracker12345", @@ -691,7 +691,7 @@ func TestZetaCoreBridge_GetOutTxTracker(t *testing.T) { } func TestZetaCoreBridge_GetAllOutTxTrackerByChain(t *testing.T) { - chain := chains.BscMainnetChain() + chain := chains.BscMainnetChain expectedOutput := crosschainTypes.QueryAllOutTxTrackerByChainResponse{ OutTxTracker: []crosschainTypes.OutTxTracker{ { @@ -734,11 +734,11 @@ func TestZetaCoreBridge_GetPendingNoncesByChain(t *testing.T) { PendingNonces: observertypes.PendingNonces{ NonceLow: 0, NonceHigh: 0, - ChainId: chains.EthChain().ChainId, + ChainId: chains.EthChain.ChainId, Tss: "", }, } - input := observertypes.QueryPendingNoncesByChainRequest{ChainId: chains.EthChain().ChainId} + input := observertypes.QueryPendingNoncesByChainRequest{ChainId: chains.EthChain.ChainId} method := "/zetachain.zetacore.observer.Query/PendingNoncesByChain" server := setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) server.Serve() @@ -747,13 +747,13 @@ func TestZetaCoreBridge_GetPendingNoncesByChain(t *testing.T) { zetabridge, err := setupCoreBridge() require.NoError(t, err) - resp, err := zetabridge.GetPendingNoncesByChain(chains.EthChain().ChainId) + resp, err := zetabridge.GetPendingNoncesByChain(chains.EthChain.ChainId) require.NoError(t, err) require.Equal(t, expectedOutput.PendingNonces, resp) } func TestZetaCoreBridge_GetBlockHeaderChainState(t *testing.T) { - chainID := chains.BscMainnetChain().ChainId + chainID := chains.BscMainnetChain.ChainId expectedOutput := lightclienttypes.QueryGetChainStateResponse{ChainState: &lightclienttypes.ChainState{ ChainId: chainID, LatestHeight: 5566654, @@ -777,11 +777,25 @@ func TestZetaCoreBridge_GetBlockHeaderChainState(t *testing.T) { func TestZetaCoreBridge_GetSupportedChains(t *testing.T) { expectedOutput := observertypes.QuerySupportedChainsResponse{ Chains: []*chains.Chain{ - {chains.BscMainnetChain().ChainName, - chains.BscMainnetChain().ChainId, + { + chains.BtcMainnetChain.ChainName, + chains.BtcMainnetChain.ChainId, + chains.BscMainnetChain.Network, + chains.BscMainnetChain.NetworkType, + chains.BscMainnetChain.Vm, + chains.BscMainnetChain.Consensus, + chains.BscMainnetChain.IsExternal, + chains.BscMainnetChain.IsHeaderSupported, }, - {chains.EthChain().ChainName, - chains.EthChain().ChainId, + { + chains.EthChain.ChainName, + chains.EthChain.ChainId, + chains.EthChain.Network, + chains.EthChain.NetworkType, + chains.EthChain.Vm, + chains.EthChain.Consensus, + chains.EthChain.IsExternal, + chains.EthChain.IsHeaderSupported, }, }, } @@ -825,7 +839,7 @@ func TestZetaCoreBridge_GetPendingNonces(t *testing.T) { } func TestZetaCoreBridge_Prove(t *testing.T) { - chainId := chains.BscMainnetChain().ChainId + chainId := chains.BscMainnetChain.ChainId txHash := "9c8d02b6956b9c78ecb6090a8160faaa48e7aecfd0026fcdf533721d861436a3" blockHash := "0000000000000000000172c9a64f86f208b867a84dc7a0b7c75be51e750ed8eb" txIndex := 555 diff --git a/zetaclient/zetabridge/tx.go b/zetaclient/zetabridge/tx.go index b76996e79a..3fa998a22a 100644 --- a/zetaclient/zetabridge/tx.go +++ b/zetaclient/zetabridge/tx.go @@ -316,7 +316,7 @@ func (b *ZetaCoreBridge) PostVoteOutbound( // the higher gas limit is only necessary when the vote is finalized and the outbound is processed // therefore we use a retryGasLimit with a higher value to resend the tx if it fails (when the vote is finalized) retryGasLimit := uint64(0) - if msg.Status == chains.ReceiveStatus_Failed { + if msg.Status == chains.ReceiveStatus_failed { retryGasLimit = PostVoteOutboundRevertGasLimit } diff --git a/zetaclient/zetabridge/tx_test.go b/zetaclient/zetabridge/tx_test.go index 4fd2ee19fb..498774a28c 100644 --- a/zetaclient/zetabridge/tx_test.go +++ b/zetaclient/zetabridge/tx_test.go @@ -143,7 +143,7 @@ func TestZetaCoreBridge_PostGasPrice(t *testing.T) { t.Run("post gas price success", func(t *testing.T) { zetaBridgeBroadcast = ZetaBridgeBroadcastTest - hash, err := zetabridge.PostGasPrice(chains.BscMainnetChain(), 1000000, "100", 1234) + hash, err := zetabridge.PostGasPrice(chains.BscMainnetChain, 1000000, "100", 1234) require.NoError(t, err) require.Equal(t, sampleHash, hash) }) @@ -152,7 +152,7 @@ func TestZetaCoreBridge_PostGasPrice(t *testing.T) { // //t.Run("post gas price fail", func(t *testing.T) { // zetaBridgeBroadcast = ZetaBridgeBroadcastTestErr - // hash, err := zetabridge.PostGasPrice(chains.BscMainnetChain(), 1000000, "100", 1234) + // hash, err := zetabridge.PostGasPrice(chains.BscMainnetChain, 1000000, "100", 1234) // require.ErrorContains(t, err, "post gasprice failed") // require.Equal(t, "", hash) //}) @@ -166,14 +166,14 @@ func TestZetaCoreBridge_AddTxHashToOutTxTracker(t *testing.T) { t.Run("add tx hash success", func(t *testing.T) { zetaBridgeBroadcast = ZetaBridgeBroadcastTest - hash, err := zetabridge.AddTxHashToOutTxTracker(chains.BscMainnetChain().ChainId, 123, "", nil, "", 456) + hash, err := zetabridge.AddTxHashToOutTxTracker(chains.BscMainnetChain.ChainId, 123, "", nil, "", 456) require.NoError(t, err) require.Equal(t, sampleHash, hash) }) t.Run("add tx hash fail", func(t *testing.T) { zetaBridgeBroadcast = ZetaBridgeBroadcastTestErr - hash, err := zetabridge.AddTxHashToOutTxTracker(chains.BscMainnetChain().ChainId, 123, "", nil, "", 456) + hash, err := zetabridge.AddTxHashToOutTxTracker(chains.BscMainnetChain.ChainId, 123, "", nil, "", 456) require.Error(t, err) require.Equal(t, "", hash) }) @@ -190,7 +190,7 @@ func TestZetaCoreBridge_SetTSS(t *testing.T) { hash, err := zetabridge.SetTSS( "zetapub1addwnpepqtadxdyt037h86z60nl98t6zk56mw5zpnm79tsmvspln3hgt5phdc79kvfc", 9987, - chains.ReceiveStatus_Success, + chains.ReceiveStatus_success, ) require.NoError(t, err) require.Equal(t, sampleHash, hash) @@ -245,11 +245,26 @@ func TestZetaCoreBridge_UpdateZetaCoreContext(t *testing.T) { WithPayload(observertypes.QuerySupportedChains{}). Return(observertypes.QuerySupportedChainsResponse{ Chains: []*chains.Chain{ - {chains.BscMainnetChain().ChainName, - chains.BscMainnetChain().ChainId, + + { + chains.BtcMainnetChain.ChainName, + chains.BtcMainnetChain.ChainId, + chains.BscMainnetChain.Network, + chains.BscMainnetChain.NetworkType, + chains.BscMainnetChain.Vm, + chains.BscMainnetChain.Consensus, + chains.BscMainnetChain.IsExternal, + chains.BscMainnetChain.IsHeaderSupported, }, - {chains.EthChain().ChainName, - chains.EthChain().ChainId, + { + chains.EthChain.ChainName, + chains.EthChain.ChainId, + chains.EthChain.Network, + chains.EthChain.NetworkType, + chains.EthChain.Vm, + chains.EthChain.Consensus, + chains.EthChain.IsExternal, + chains.EthChain.IsHeaderSupported, }, }, }) @@ -333,7 +348,7 @@ func TestZetaCoreBridge_PostBlameData(t *testing.T) { IsUnicast: false, BlameNodes: nil, }, - chains.BscMainnetChain().ChainId, + chains.BscMainnetChain.ChainId, "102394876-bsc", ) require.NoError(t, err) @@ -352,7 +367,7 @@ func TestZetaCoreBridge_PostVoteBlockHeader(t *testing.T) { t.Run("post add block header success", func(t *testing.T) { zetaBridgeBroadcast = ZetaBridgeBroadcastTest hash, err := zetabridge.PostVoteBlockHeader( - chains.EthChain().ChainId, + chains.EthChain.ChainId, blockHash, 18495266, getHeaderData(t), @@ -396,10 +411,10 @@ func TestZetaCoreBridge_GetInBoundVoteMessage(t *testing.T) { zetaBridgeBroadcast = ZetaBridgeBroadcastTest msg := GetInBoundVoteMessage( address.String(), - chains.EthChain().ChainId, + chains.EthChain.ChainId, "", address.String(), - chains.ZetaChainMainnet().ChainId, + chains.ZetaChainMainnet.ChainId, math.NewUint(500), "", "", 12345, @@ -456,8 +471,8 @@ func TestZetaCoreBridge_PostVoteOutbound(t *testing.T) { big.NewInt(100), 1200, big.NewInt(500), - chains.ReceiveStatus_Success, - chains.EthChain(), + chains.ReceiveStatus_success, + chains.EthChain, 10001, coin.CoinType_Gas) require.NoError(t, err) diff --git a/zetaclient/zetacore_observer_test.go b/zetaclient/zetacore_observer_test.go index d47c062757..a02263fb0f 100644 --- a/zetaclient/zetacore_observer_test.go +++ b/zetaclient/zetacore_observer_test.go @@ -75,8 +75,8 @@ func CreateCoreContext(evmChain, btcChain chains.Chain, evmChainParams, btcChain func Test_GetUpdatedSigner(t *testing.T) { // initial parameters for core observer creation - evmChain := chains.EthChain() - btcChain := chains.BtcMainnetChain() + evmChain := chains.EthChain + btcChain := chains.BtcMainnetChain evmChainParams := &observertypes.ChainParams{ ChainId: evmChain.ChainId, ConnectorContractAddress: testutils.ConnectorAddresses[evmChain.ChainId].Hex(), @@ -95,7 +95,7 @@ func Test_GetUpdatedSigner(t *testing.T) { observer := MockCoreObserver(t, evmChain, btcChain, evmChainParams, btcChainParams) coreContext := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // BSC signer should not be found - _, err := observer.GetUpdatedSigner(coreContext, chains.BscMainnetChain().ChainId) + _, err := observer.GetUpdatedSigner(coreContext, chains.BscMainnetChain.ChainId) require.ErrorContains(t, err, "signer not found") }) t.Run("should be able to update connector and erc20 custody address", func(t *testing.T) { @@ -111,8 +111,8 @@ func Test_GetUpdatedSigner(t *testing.T) { func Test_GetUpdatedChainClient(t *testing.T) { // initial parameters for core observer creation - evmChain := chains.EthChain() - btcChain := chains.BtcMainnetChain() + evmChain := chains.EthChain + btcChain := chains.BtcMainnetChain evmChainParams := &observertypes.ChainParams{ ChainId: evmChain.ChainId, ConnectorContractAddress: testutils.ConnectorAddresses[evmChain.ChainId].Hex(), @@ -160,7 +160,7 @@ func Test_GetUpdatedChainClient(t *testing.T) { observer := MockCoreObserver(t, evmChain, btcChain, evmChainParams, btcChainParams) coreContext := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // BSC chain client should not be found - _, err := observer.GetUpdatedChainClient(coreContext, chains.BscMainnetChain().ChainId) + _, err := observer.GetUpdatedChainClient(coreContext, chains.BscMainnetChain.ChainId) require.ErrorContains(t, err, "chain client not found") }) t.Run("chain params in evm chain client should be updated successfully", func(t *testing.T) { @@ -176,7 +176,7 @@ func Test_GetUpdatedChainClient(t *testing.T) { observer := MockCoreObserver(t, evmChain, btcChain, evmChainParams, btcChainParams) coreContext := CreateCoreContext(btcChain, btcChain, evmChainParams, btcChainParamsNew) // BTC testnet chain client should not be found - _, err := observer.GetUpdatedChainClient(coreContext, chains.BtcTestNetChain().ChainId) + _, err := observer.GetUpdatedChainClient(coreContext, chains.BtcTestNetChain.ChainId) require.ErrorContains(t, err, "chain client not found") }) t.Run("chain params in btc chain client should be updated successfully", func(t *testing.T) { From e62034857345bd970ad263561d10e1a4a4e8e8bf Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 30 Apr 2024 05:20:45 -0500 Subject: [PATCH 3/5] fix: replaced hard-coded MaxLookaheadNonce with a default lookback factor (#2033) * replaced hard-coded MaxLookaheadNonce with a default lookback factor * Update zetaclient/zetacore_observer.go Co-authored-by: Lucas Bertrand * use explicit variable names --------- Co-authored-by: Lucas Bertrand --- changelog.md | 3 ++- zetaclient/zetacore_observer.go | 31 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index 8497cfcd8e..3688b1f89c 100644 --- a/changelog.md +++ b/changelog.md @@ -95,11 +95,12 @@ * [1861](https://github.com/zeta-chain/node/pull/1861) - fix `ObserverSlashAmount` invalid read * [1880](https://github.com/zeta-chain/node/issues/1880) - lower the gas price multiplier for EVM chains. -* [1883](https://github.com/zeta-chain/node/issues/1883) - zetaclient should check 'IsSupported' flag to pause/unpause a specific chain +* [1883](https://github.com/zeta-chain/node/issues/1883) - zetaclient should check `IsSupported` flag to pause/unpause a specific chain * [1633](https://github.com/zeta-chain/node/issues/1633) - zetaclient should be able to pick up new connector and erc20Custody addresses * [1944](https://github.com/zeta-chain/node/pull/1944) - fix evm signer unit tests * [1888](https://github.com/zeta-chain/node/issues/1888) - zetaclient should stop inbound/outbound txs according to cross-chain flags * [1970](https://github.com/zeta-chain/node/issues/1970) - remove the timeout in the evm outtx tracker processing thread +* [1484](https://github.com/zeta-chain/node/issues/1484) - replaced hard-coded `MaxLookaheadNonce` with a default lookback factor ### Chores diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 5f187caed7..50be8a0f41 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -20,7 +20,11 @@ import ( ) const ( - MaxLookaheadNonce = 120 + // EVMOutboundTxLookbackFactor is the factor to determine how many nonces to look back for pending cctxs + // For example, give OutboundTxScheduleLookahead of 120, pending NonceLow of 1000 and factor of 1.0, + // the scheduler need to be able to pick up and schedule any pending cctx with nonce < 880 (1000 - 120 * 1.0) + // NOTE: 1.0 means look back the same number of cctxs as we look ahead + EVMOutboundTxLookbackFactor = 1.0 ) type ZetaCoreLog struct { @@ -28,7 +32,7 @@ type ZetaCoreLog struct { ZetaChainWatcher zerolog.Logger } -// CoreObserver wraps the zetabridge bridge and adds the client and signer maps to it . This is the high level object used for CCTX interactions +// CoreObserver wraps the zetabridge, chain clients and signers. This is the high level object used for CCTX scheduling type CoreObserver struct { bridge interfaces.ZetaCoreBridger signerMap map[int64]interfaces.ChainSigner @@ -285,6 +289,11 @@ func (co *CoreObserver) scheduleCctxEVM( for _, v := range res { trackerMap[v.Nonce] = true } + outboundScheduleLookahead := ob.GetChainParams().OutboundTxScheduleLookahead + // #nosec G701 always in range + outboundScheduleLookback := uint64(float64(outboundScheduleLookahead) * EVMOutboundTxLookbackFactor) + // #nosec G701 positive + outboundScheduleInterval := uint64(ob.GetChainParams().OutboundTxScheduleInterval) for idx, cctx := range cctxList { params := cctx.GetCurrentOutTxParam() @@ -295,7 +304,7 @@ func (co *CoreObserver) scheduleCctxEVM( co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxEVM: outtx %s chainid mismatch: want %d, got %d", outTxID, chainID, params.ReceiverChainId) continue } - if params.OutboundTxTssNonce > cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce+MaxLookaheadNonce { + if params.OutboundTxTssNonce > cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce+outboundScheduleLookback { co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxEVM: nonce too high: signing %d, earliest pending %d, chain %d", params.OutboundTxTssNonce, cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce, chainID) break @@ -312,15 +321,11 @@ func (co *CoreObserver) scheduleCctxEVM( continue } - // #nosec G701 positive - interval := uint64(ob.GetChainParams().OutboundTxScheduleInterval) - lookahead := ob.GetChainParams().OutboundTxScheduleLookahead - // determining critical outtx; if it satisfies following criteria // 1. it's the first pending outtx for this chain // 2. the following 5 nonces have been in tracker - criticalInterval := uint64(10) // for critical pending outTx we reduce re-try interval - nonCriticalInterval := interval * 2 // for non-critical pending outTx we increase re-try interval + criticalInterval := uint64(10) // for critical pending outTx we reduce re-try interval + nonCriticalInterval := outboundScheduleInterval * 2 // for non-critical pending outTx we increase re-try interval if nonce%criticalInterval == zetaHeight%criticalInterval { count := 0 for i := nonce + 1; i <= nonce+10; i++ { @@ -329,23 +334,23 @@ func (co *CoreObserver) scheduleCctxEVM( } } if count >= 5 { - interval = criticalInterval + outboundScheduleInterval = criticalInterval } } // if it's already in tracker, we increase re-try interval if _, ok := trackerMap[nonce]; ok { - interval = nonCriticalInterval + outboundScheduleInterval = nonCriticalInterval } // otherwise, the normal interval is used - if nonce%interval == zetaHeight%interval && !outTxMan.IsOutTxActive(outTxID) { + if nonce%outboundScheduleInterval == zetaHeight%outboundScheduleInterval && !outTxMan.IsOutTxActive(outTxID) { outTxMan.StartTryProcess(outTxID) co.logger.ZetaChainWatcher.Debug().Msgf("scheduleCctxEVM: sign outtx %s with value %d\n", outTxID, cctx.GetCurrentOutTxParam().Amount) go signer.TryProcessOutTx(cctx, outTxMan, outTxID, ob, co.bridge, zetaHeight) } // #nosec G701 always in range - if int64(idx) >= lookahead-1 { // only look at 'lookahead' cctxs per chain + if int64(idx) >= outboundScheduleLookahead-1 { // only look at 'lookahead' cctxs per chain break } } From 97e650fcd522b917c40d5893e423d661a0606949 Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Tue, 30 Apr 2024 09:51:34 -0700 Subject: [PATCH 4/5] test: optimize upgrade test image build (#2096) * test: optimize upgrade test build * versions build-arg --- Dockerfile-upgrade | 40 +++++++++++---------- Makefile | 14 ++++---- contrib/localnet/scripts/start-zetacored.sh | 4 +-- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/Dockerfile-upgrade b/Dockerfile-upgrade index e53b766256..42e9834bf6 100644 --- a/Dockerfile-upgrade +++ b/Dockerfile-upgrade @@ -1,4 +1,4 @@ -FROM golang:1.20-alpine3.18 +FROM golang:1.20-alpine3.18 as base # Purpose: This Dockerfile creates an environment for performing an upgrade test on ZetaChain # It contains the ZetaChain and ZetaClient binaries for two different versions of ZetaChain @@ -8,6 +8,7 @@ FROM golang:1.20-alpine3.18 ENV GOPATH /go ENV GOOS=linux ENV CGO_ENABLED=1 +ENV GOCACHE=/root/.cache/go-build RUN apk --no-cache add git make build-base jq openssh libusb-dev linux-headers bash curl tmux RUN ssh-keygen -b 2048 -t rsa -f /root/.ssh/localtest.pem -q -N "" @@ -20,32 +21,35 @@ WORKDIR /go/delivery/zeta-node RUN mkdir -p $GOPATH/bin/old RUN mkdir -p $GOPATH/bin/new -ARG OLD_VERSION=v14.0.0 -ENV NEW_VERSION=v15 - -# Build new release from the current source -COPY go.mod /go/delivery/zeta-node/ -COPY go.sum /go/delivery/zeta-node/ -RUN cd /go/delivery/zeta-node/ && go mod download -COPY . /go/delivery/zeta-node/ -RUN cd /go/delivery/zeta-node/ && make install -RUN cd /go/delivery/zeta-node/ && make install-zetae2e -RUN cp $GOPATH/bin/zetacored $GOPATH/bin/new/ -RUN cp $GOPATH/bin/zetaclientd $GOPATH/bin/new/ +RUN ssh-keygen -A +RUN cp /root/.ssh/localtest.pem.pub /root/.ssh/authorized_keys # Checkout and build old binary +FROM base as oldbuild +ARG OLD_VERSION RUN git clone https://github.com/zeta-chain/node.git RUN cd node && git fetch RUN cd node && git checkout ${OLD_VERSION} RUN cd node && make install -RUN cp $GOPATH/bin/zetacored $GOPATH/bin/old/ -RUN cp $GOPATH/bin/zetaclientd $GOPATH/bin/old/ -RUN ssh-keygen -A -WORKDIR /root +# Build new release from the current source +FROM base +ARG NEW_VERSION +ENV NEW_VERSION=${NEW_VERSION} +COPY go.mod /go/delivery/zeta-node/ +COPY go.sum /go/delivery/zeta-node/ +RUN cd /go/delivery/zeta-node/ && go mod download +COPY . /go/delivery/zeta-node/ +RUN --mount=type=cache,target="/root/.cache/go-build" cd /go/delivery/zeta-node/ && make install +RUN --mount=type=cache,target="/root/.cache/go-build" cd /go/delivery/zeta-node/ && make install-zetae2e +RUN cp $GOPATH/bin/zetacored $GOPATH/bin/new/ && \ + cp $GOPATH/bin/zetaclientd $GOPATH/bin/new/ -RUN cp /root/.ssh/localtest.pem.pub /root/.ssh/authorized_keys +COPY --from=oldbuild $GOPATH/bin/zetacored $GOPATH/bin/zetaclientd $GOPATH/bin/ +COPY --from=oldbuild $GOPATH/bin/zetacored $GOPATH/bin/zetaclientd $GOPATH/bin/old + +WORKDIR /root RUN cp /go/bin/zetaclientd /usr/local/bin RUN cp /go/bin/zetacored /usr/local/bin diff --git a/Makefile b/Makefile index 2cc2bf1d80..b679c488d3 100644 --- a/Makefile +++ b/Makefile @@ -214,16 +214,18 @@ start-stress-test: zetanode @echo "--> Starting stress test" cd contrib/localnet/ && $(DOCKER) compose -f docker-compose.yml -f docker-compose-stresstest.yml up -d -start-upgrade-test: - @echo "--> Starting upgrade test" - $(DOCKER) build -t zetanode -f ./Dockerfile-upgrade . +zetanode-upgrade: + @echo "Building zetanode-upgrade" + $(DOCKER) build -t zetanode -f ./Dockerfile-upgrade --build-arg OLD_VERSION=v14.0.0 --build-arg NEW_VERSION=v15 . $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile.fastbuild . +.PHONY: zetanode-upgrade + +start-upgrade-test: zetanode-upgrade + @echo "--> Starting upgrade test" cd contrib/localnet/ && $(DOCKER) compose -f docker-compose.yml -f docker-compose-upgrade.yml up -d -start-upgrade-test-light: +start-upgrade-test-light: zetanode-upgrade @echo "--> Starting light upgrade test (no ZetaChain state populating before upgrade)" - $(DOCKER) build -t zetanode -f ./Dockerfile-upgrade . - $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile.fastbuild . cd contrib/localnet/ && $(DOCKER) compose -f docker-compose.yml -f docker-compose-upgrade-light.yml up -d start-localnet: zetanode diff --git a/contrib/localnet/scripts/start-zetacored.sh b/contrib/localnet/scripts/start-zetacored.sh index d28f6ae446..4a83f7cb79 100755 --- a/contrib/localnet/scripts/start-zetacored.sh +++ b/contrib/localnet/scripts/start-zetacored.sh @@ -226,8 +226,8 @@ else sleep 7 /root/.zetacored/cosmovisor/genesis/bin/zetacored query gov proposal 1 - # We use tail -f to keep the container running - tail -f zetanode.log + # We use tail -f to keep the container running. Use -n999999 to ensure we get all the context. + tail -n999999 -f zetanode.log fi From 0e91dcf49c0c0b7571aa601d5dcbd68d093387eb Mon Sep 17 00:00:00 2001 From: Alex Gartner Date: Tue, 30 Apr 2024 10:27:43 -0700 Subject: [PATCH 5/5] docs: update release flow/docs (#2081) * docs: update release flow/docs * add note about RC from develop --- readme.md | 55 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index b4ba24455f..eb1438682a 100644 --- a/readme.md +++ b/readme.md @@ -81,27 +81,56 @@ to [run the E2E test](./LOCAL_TESTING.md). [Discord](https://discord.com/invite/zetachain) | [Telegram](https://t.me/zetachainofficial) | [Website](https://zetachain.com) +## Releases -## Creating a Release Candidate -Creating a release candidate for testing is a straightforward process. Here are the steps to follow: +To start a new major release, begin by creating and pushing a `release/` branch based on `develop`. -### Steps - - Step 1. Create the release candidate tag with the following format (e.g., vx.x.x-rc) ex. v11.0.0-rc. - - Step 2. Once a RC branch is created the automation will kickoff to build and upload the release and its binaries. +
+Example Commands + +```bash +git fetch +git checkout -b release/v15 origin/develop +git push origin release/v15 +``` + +
+ +Most changes should first be merged into `develop` then backported to the release branch via a PR. + +
+Example Commands to Backport a Change + +```bash +git fetch +git checkout -b my-backport-branch origin/release/v15 +git cherry-pick +git push origin my-backport-branch +``` + +
+ +### Creating a Release Candidate +You can use github actions to create a release candidate: +1) Create the release candidate tag with the following format (e.g., vx.x.x-rc) ex. v11.0.0-rc. +2) Push the tag and the automation will take care of the rest + +You may create the RC tag directly off `develop` if a release branch has not been created yet. You should use the release branch if it exists and has diverged from develop. By following these steps, you can efficiently create a release candidate for QA and validation. In the future we will make this automatically deploy to a testnet when a -rc branch is created. Currently, raising the proposal to deploy to testnet is a manual process via GovOps repo. -## Creating a Release / Hotfix Release +### Creating a Release / Hotfix Release -To create a release simply execute the publish-release workflow and follow the steps below. +To create a release simply execute the publish-release workflow and follow these steps: -### Steps - - Step 1. Go to this pipeline: https://github.com/zeta-chain/node/actions/workflows/publish-release.yml - - Step 2. Select the dropdown branch / tag you want to create the release with. - - Step 3. In the version input, include the version of your release. Note. The major version must match what is in the upgrade handler. - - Step 4. Select if you want to skip the tests by checking the checkbox for skip tests. - - Step 5. Once the testing steps pass it will create a Github Issue. This Github Issue needes to be approved by one of the approvers: kingpinXD,lumtis,brewmaster012 +1) Go to this pipeline: https://github.com/zeta-chain/node/actions/workflows/publish-release.yml +2) Select the release branch. +3) In the version input, include the version of your release. + - The major version must match what is in the upgrade handler + - The version should look like this: `v15.0.0` +4) Select if you want to skip the tests by checking the checkbox for skip tests. +5) Once the testing steps pass it will create a Github Issue. This Github Issue needes to be approved by one of the approvers: kingpinXD,lumtis,brewmaster012 Once the release is approved the pipeline will continue and will publish the releases with the title / version you specified in the user input.