From 61935a3317cd1b3d9c12a7aeb1c2ee4a03d9995d Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:23:27 -0600 Subject: [PATCH 01/67] fix: avoid duplicate keysign for outTx already pending (#1518) * avoid duplicate keysign for pending outTx * updated changelog * modified confirmTxByHash to return bool; renamed variable names and some cleanup --------- Co-authored-by: Lucas Bertrand --- changelog.md | 2 + zetaclient/evm_client.go | 188 +++++++++++++++++++++++---------------- zetaclient/evm_signer.go | 39 ++++---- 3 files changed, 132 insertions(+), 97 deletions(-) diff --git a/changelog.md b/changelog.md index a0e8794bc0..aaffa9a6c5 100644 --- a/changelog.md +++ b/changelog.md @@ -16,6 +16,8 @@ * added metrics to track the burn rate of the hotkey in the telemetry server as well as prometheus ### Fixes + +* [1518](https://github.com/zeta-chain/node/pull/1518) - Avoid duplicate keysign if an outTx is already pending * fix Code4rena issue - zetaclients potentially miss inTx when PostSend (or other RPC) fails * fix go-staticcheck warnings for zetaclient * fix Athens-3 issue - incorrect pending-tx inclusion and incorrect confirmation count diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 0475d5ff6c..2675b79250 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -64,28 +64,29 @@ const ( // Filled with above constants depending on chain type EVMChainClient struct { *ChainMetrics - chain common.Chain - evmClient EVMRPCClient - KlaytnClient KlaytnRPCClient - zetaClient ZetaCoreBridger - Tss TSSSigner - lastBlockScanned uint64 - lastBlock uint64 - BlockTimeExternalChain uint64 // block time in seconds - txWatchList map[ethcommon.Hash]string - Mu *sync.Mutex - db *gorm.DB - outTXConfirmedReceipts map[string]*ethtypes.Receipt - outTXConfirmedTransaction map[string]*ethtypes.Transaction - MinNonce int64 - MaxNonce int64 - OutTxChan chan OutTx // send to this channel if you want something back! - stop chan struct{} - fileLogger *zerolog.Logger // for critical info - logger EVMLog - cfg *config.Config - params observertypes.CoreParams - ts *TelemetryServer + chain common.Chain + evmClient EVMRPCClient + KlaytnClient KlaytnRPCClient + zetaClient ZetaCoreBridger + Tss 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 + MinNonce int64 + MaxNonce int64 + OutTxChan chan OutTx // send to this channel if you want something back! + stop chan struct{} + fileLogger *zerolog.Logger // for critical info + logger EVMLog + cfg *config.Config + params observertypes.CoreParams + ts *TelemetryServer BlockCache *lru.Cache } @@ -122,8 +123,9 @@ func NewEVMChainClient( ob.zetaClient = bridge ob.txWatchList = make(map[ethcommon.Hash]string) ob.Tss = tss + ob.outTxPendingTransactions = make(map[string]*ethtypes.Transaction) ob.outTXConfirmedReceipts = make(map[string]*ethtypes.Receipt) - ob.outTXConfirmedTransaction = make(map[string]*ethtypes.Transaction) + ob.outTXConfirmedTransactions = make(map[string]*ethtypes.Transaction) ob.OutTxChan = make(chan OutTx, 100) logFile, err := os.OpenFile(ob.chain.ChainName.String()+"_debug.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) @@ -294,15 +296,11 @@ func (ob *EVMChainClient) Stop() { // returns: isIncluded, isConfirmed, Error // If isConfirmed, it also post to ZetaCore func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, cointype common.CoinType, logger zerolog.Logger) (bool, bool, error) { - ob.Mu.Lock() - params := ob.params - receipt, found1 := ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] - transaction, found2 := ob.outTXConfirmedTransaction[ob.GetTxID(nonce)] - ob.Mu.Unlock() - found := found1 && found2 - if !found { + if !ob.isTxConfirmed(nonce) { return false, false, nil } + params := ob.GetCoreParams() + receipt, transaction := ob.GetTxNReceipt(nonce) sendID := fmt.Sprintf("%s-%d", ob.chain.String(), nonce) logger = logger.With().Str("sendID", sendID).Logger() @@ -560,11 +558,7 @@ func (ob *EVMChainClient) observeOutTx() { if err != nil || timeoutNonce <= 0 { timeoutNonce = 100 * 3 // process up to 100 hashes } - rpcRestTime, err := strconv.Atoi(os.Getenv("OS_RPC_REST_TIME")) - if err != nil || rpcRestTime <= 0 { - rpcRestTime = 20 // 20ms - } - ob.logger.ObserveOutTx.Info().Msgf("observeOutTx using timeoutNonce %d seconds, rpcRestTime %d ms", timeoutNonce, rpcRestTime) + ob.logger.ObserveOutTx.Info().Msgf("observeOutTx using timeoutNonce %d seconds", timeoutNonce) ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_observeOutTx_%d", ob.chain.ChainId), ob.GetCoreParams().OutTxTicker) if err != nil { @@ -589,10 +583,7 @@ func (ob *EVMChainClient) observeOutTx() { if nonceInt < lowestOutTxNonceToObserve[ob.chain.ChainId] { continue } - ob.Mu.Lock() - _, found := ob.outTXConfirmedReceipts[ob.GetTxID(nonceInt)] - ob.Mu.Unlock() - if found { // Go to next tracker if this one has already been confirmed + if ob.isTxConfirmed(nonceInt) { // Go to next tracker if this one already has a confirmed tx continue } for _, txHash := range tracker.HashList { @@ -601,20 +592,11 @@ func (ob *EVMChainClient) observeOutTx() { ob.logger.ObserveOutTx.Warn().Msgf("observeOutTx timeout on chain %d nonce %d", ob.chain.ChainId, nonceInt) break TRACKERLOOP default: - receipt, transaction, err := ob.queryTxByHash(txHash.TxHash, nonceInt) - time.Sleep(time.Duration(rpcRestTime) * time.Millisecond) - if err == nil && receipt != nil { // confirmed - ob.Mu.Lock() - ob.outTXConfirmedReceipts[ob.GetTxID(nonceInt)] = receipt - ob.outTXConfirmedTransaction[ob.GetTxID(nonceInt)] = transaction - ob.Mu.Unlock() + if ob.confirmTxByHash(txHash.TxHash, nonceInt) { ob.logger.ObserveOutTx.Info().Msgf("observeOutTx confirmed outTx %s for chain %d nonce %d", txHash.TxHash, ob.chain.ChainId, nonceInt) - break } - if err != nil { - ob.logger.ObserveOutTx.Debug().Err(err).Msgf("error queryTxByHash: chain %s hash %s", ob.chain.String(), txHash.TxHash) - } + ob.logger.ObserveOutTx.Debug().Msgf("observeOutTx outTx %s for chain %d nonce %d not confirmed yet", txHash.TxHash, ob.chain.ChainId, nonceInt) } } } @@ -626,47 +608,101 @@ func (ob *EVMChainClient) observeOutTx() { } } -// return the status of txHash -// receipt nil, err non-nil: txHash not found -// receipt nil, err nil: txHash receipt recorded, but may not be confirmed -// receipt non-nil, err nil: txHash confirmed -func (ob *EVMChainClient) queryTxByHash(txHash string, nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction, error) { - logger := ob.logger.ObserveOutTx.With().Str("txHash", txHash).Uint64("nonce", nonce).Logger() - if ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] != nil && ob.outTXConfirmedTransaction[ob.GetTxID(nonce)] != nil { - return nil, nil, fmt.Errorf("queryTxByHash: txHash %s receipts already recorded", txHash) - } +// SetPendingTx sets the pending transaction in memory +func (ob *EVMChainClient) SetPendingTx(nonce uint64, transaction *ethtypes.Transaction) { + ob.Mu.Lock() + ob.outTxPendingTransactions[ob.GetTxID(nonce)] = transaction + ob.Mu.Unlock() +} + +// GetPendingTx gets the pending transaction from memory +func (ob *EVMChainClient) GetPendingTx(nonce uint64) *ethtypes.Transaction { + ob.Mu.Lock() + transaction := ob.outTxPendingTransactions[ob.GetTxID(nonce)] + ob.Mu.Unlock() + return transaction +} + +// SetTxNReceipt sets the receipt and transaction in memory +func (ob *EVMChainClient) SetTxNReceipt(nonce uint64, receipt *ethtypes.Receipt, transaction *ethtypes.Transaction) { + ob.Mu.Lock() + delete(ob.outTxPendingTransactions, ob.GetTxID(nonce)) // remove pending transaction, if any + ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] = receipt + ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] = transaction + ob.Mu.Unlock() +} + +// getTxNReceipt gets the receipt and transaction from memory +func (ob *EVMChainClient) GetTxNReceipt(nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction) { + ob.Mu.Lock() + receipt := ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] + transaction := ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] + ob.Mu.Unlock() + return receipt, transaction +} + +// isTxConfirmed returns true if there is a confirmed tx for 'nonce' +func (ob *EVMChainClient) isTxConfirmed(nonce uint64) bool { + ob.Mu.Lock() + confirmed := ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] != nil && ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] != nil + ob.Mu.Unlock() + return confirmed +} + +// confirmTxByHash checks if a txHash is confirmed and saves transaction and receipt in memory +// returns true if confirmed or false otherwise +func (ob *EVMChainClient) confirmTxByHash(txHash string, nonce uint64) 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: TransactionByHash error, txHash %s nonce %d", txHash, nonce) + return false + } + if transaction == nil { // should not happen + log.Error().Msgf("confirmTxByHash: transaction is nil for txHash %s nonce %d", txHash, nonce) + return false + } + if isPending { // save pending transaction + ob.SetPendingTx(nonce, transaction) + return false + } + + // query receipt receipt, err := ob.evmClient.TransactionReceipt(ctxt, ethcommon.HexToHash(txHash)) if err != nil { if err != ethereum.NotFound { - logger.Warn().Err(err).Msgf("queryTxByHash: TransactionReceipt/TransactionByHash error, txHash %s nonce %d", txHash, nonce) + log.Warn().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) } - return nil, nil, err + return false } - transaction, isPending, err := ob.evmClient.TransactionByHash(ctxt, ethcommon.HexToHash(txHash)) - if err != nil { - return nil, nil, err + if receipt == nil { // should not happen + log.Error().Msgf("confirmTxByHash: receipt is nil for txHash %s nonce %d", txHash, nonce) + return false } + + // check nonce and confirmations if transaction.Nonce() != nonce { - return nil, nil, fmt.Errorf("queryTxByHash: txHash %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) + log.Error().Msgf("confirmTxByHash: txHash %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) + return false } confHeight := receipt.BlockNumber.Uint64() + ob.GetCoreParams().ConfirmationCount if confHeight >= math.MaxInt64 { - return nil, nil, fmt.Errorf("queryTxByHash: confHeight is out of range") + log.Error().Msgf("confirmTxByHash: confHeight is too large for txHash %s nonce %d", txHash, nonce) + return false } - if confHeight > ob.GetLastBlockHeight() { - log.Info().Msgf("queryTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) - return nil, nil, fmt.Errorf("included but not confirmed") - } - // transaction must NOT be pending - if isPending { - log.Error().Msgf("queryTxByHash: confirmed but still pending: txHash %s nonce %d receipt block %d", txHash, nonce, receipt.BlockNumber) - return nil, nil, fmt.Errorf("confirmed but still pending") + log.Info().Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", + txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) + return false } - return receipt, transaction, nil + + // confirmed, save receipt and transaction + ob.SetTxNReceipt(nonce, receipt, transaction) + + return true } // SetLastBlockHeightScanned set last block height scanned (not necessarily caught up with external block; could be slow/paused) @@ -1209,7 +1245,7 @@ func (ob *EVMChainClient) BuildTransactionsMap() error { if err != nil { return err } - ob.outTXConfirmedTransaction[transaction.Identifier] = trans + ob.outTXConfirmedTransactions[transaction.Identifier] = trans } return nil } diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index 7ea8b841b6..a0297a29b7 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -310,7 +310,7 @@ func (signer *EVMSigner) TryProcessOutTx( send *types.CrossChainTx, outTxMan *OutTxProcessorManager, outTxID string, - evmClient ChainClient, + chainclient ChainClient, zetaBridge ZetaCoreBridger, height uint64, ) { @@ -327,7 +327,6 @@ func (signer *EVMSigner) TryProcessOutTx( myID := zetaBridge.GetKeys().GetOperatorAddress() var to ethcommon.Address - var err error var toChain *common.Chain if send.CctxStatus.Status == types.CctxStatus_PendingRevert { to = ethcommon.HexToAddress(send.InboundTxParams.Sender) @@ -348,13 +347,15 @@ func (signer *EVMSigner) TryProcessOutTx( logger.Info().Msgf("Transaction doesn't need to be processed status: %d", send.CctxStatus.Status) return } - if err != nil { - logger.Error().Err(err).Msg("ParseChain fail; skip") + evmClient, ok := chainclient.(*EVMChainClient) + if !ok { + logger.Error().Msgf("chain client is not an EVMChainClient") return } // Early return if the cctx is already processed - included, confirmed, err := evmClient.IsSendOutTxProcessed(send.Index, send.GetCurrentOutTxParam().OutboundTxTssNonce, send.GetCurrentOutTxParam().CoinType, logger) + nonce := send.GetCurrentOutTxParam().OutboundTxTssNonce + included, confirmed, err := evmClient.IsSendOutTxProcessed(send.Index, nonce, send.GetCurrentOutTxParam().CoinType, logger) if err != nil { logger.Error().Err(err).Msg("IsSendOutTxProcessed failed") } @@ -381,7 +382,7 @@ func (signer *EVMSigner) TryProcessOutTx( logger.Warn().Msgf("gasLimit %d is too high; set to %d", send.GetCurrentOutTxParam().OutboundTxGasLimit, gasLimit) } - logger.Info().Msgf("chain %s minting %d to %s, nonce %d, finalized zeta bn %d", toChain, send.InboundTxParams.Amount, to.Hex(), send.GetCurrentOutTxParam().OutboundTxTssNonce, send.InboundTxParams.InboundTxFinalizedZetaHeight) + logger.Info().Msgf("chain %s minting %d to %s, nonce %d, finalized zeta bn %d", toChain, send.InboundTxParams.Amount, to.Hex(), nonce, send.InboundTxParams.InboundTxFinalizedZetaHeight) sendHash, err := hex.DecodeString(send.Index[2:]) // remove the leading 0x if err != nil || len(sendHash) != 32 { logger.Error().Err(err).Msgf("decode CCTX %s error", send.Index) @@ -412,21 +413,17 @@ func (signer *EVMSigner) TryProcessOutTx( } else { gasprice = specified } - //if common.IsEthereumChain(toChain.ChainId) { - // suggested, err := signer.client.SuggestGasPrice(context.Background()) - // if err != nil { - // logger.Error().Err(err).Msgf("cannot get gas price from chain %s ", toChain) - // return - // } - // gasprice = roundUpToNearestGwei(suggested) - //} else { - // specified, ok := new(big.Int).SetString(send.GetCurrentOutTxParam().OutboundTxGasPrice, 10) - // if !ok { - // logger.Error().Err(err).Msgf("cannot convert gas price %s ", send.GetCurrentOutTxParam().OutboundTxGasPrice) - // return - // } - // gasprice = specified - //} + + // In case there is a pending transaction, make sure this keysign is a transaction replacement + pendingTx := evmClient.GetPendingTx(nonce) + if pendingTx != nil { + if gasprice.Cmp(pendingTx.GasPrice()) > 0 { + logger.Info().Msgf("replace pending outTx %s nonce %d using gas price %d", pendingTx.Hash().Hex(), nonce, gasprice) + } else { + logger.Info().Msgf("please wait for pending outTx %s nonce %d to be included", pendingTx.Hash().Hex(), nonce) + return + } + } flags, err := zetaBridge.GetCrosschainFlags() if err != nil { From aad2e31579ad51f9fe57110fc9d41b53d8533c85 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:44:04 -0600 Subject: [PATCH 02/67] refactor: dependency: use revised go-tss lib (#1521) * use revised go-tss lib * update to merged go-tss lib * update changelog.md * update changelog.md --- changelog.md | 1 + cmd/zetaclientd/main.go | 2 +- go.mod | 10 ++++++---- go.sum | 16 ++++------------ zetaclient/tss_signer.go | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/changelog.md b/changelog.md index aaffa9a6c5..c65e43cd55 100644 --- a/changelog.md +++ b/changelog.md @@ -39,6 +39,7 @@ * GetTssAddress now returns only the current tss address for ETH and BTC * Add a new query GetTssAddressesByFinalizedBlockHeight to get any other tss addresses for a finalized block height * Add logger to smoke tests +* [1521](https://github.com/zeta-chain/node/pull/1521) - replace go-tss lib version with one that reverts back to thorchain tss-lib ### Chores * [1446](https://github.com/zeta-chain/node/pull/1446) - renamed file `zetaclientd/aux.go` to `zetaclientd/utils.go` to avoid complaints from go package resolver. diff --git a/cmd/zetaclientd/main.go b/cmd/zetaclientd/main.go index e6b195f783..a51fb40d82 100644 --- a/cmd/zetaclientd/main.go +++ b/cmd/zetaclientd/main.go @@ -1,10 +1,10 @@ package main import ( + ecdsakeygen "github.com/binance-chain/tss-lib/ecdsa/keygen" "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" "github.com/rs/zerolog" - ecdsakeygen "github.com/zeta-chain/tss-lib/ecdsa/keygen" "github.com/zeta-chain/zetacore/zetaclient/config" "github.com/zeta-chain/zetacore/cmd" diff --git a/go.mod b/go.mod index ded799f460..a8dd44e772 100644 --- a/go.mod +++ b/go.mod @@ -42,10 +42,9 @@ require ( github.com/pkg/errors v0.9.1 github.com/rakyll/statik v0.1.7 github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 - github.com/zeta-chain/go-tss v0.1.0 + github.com/zeta-chain/go-tss v0.1.1-0.20240103170132-35850edf5dbd github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b - github.com/zeta-chain/tss-lib v0.1.7 google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc gopkg.in/yaml.v2 v2.4.0 ) @@ -58,10 +57,11 @@ require ( gorm.io/gorm v1.24.6 ) +require github.com/binance-chain/tss-lib v0.0.0-20201118045712-70b2cb4bf916 + require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 // indirect - github.com/bnb-chain/tss-lib v1.5.0 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect @@ -305,7 +305,7 @@ require ( golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.2.0 // indirect + golang.org/x/sync v0.2.0 golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.9.0 // indirect golang.org/x/text v0.10.0 // indirect @@ -324,6 +324,7 @@ require ( replace ( github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43 + github.com/binance-chain/tss-lib => gitlab.com/thorchain/tss/tss-lib v0.1.5 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.3 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 @@ -334,6 +335,7 @@ replace ( // use cometbft github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.28 github.com/tendermint/tm-db => github.com/BlockPILabs/cosmos-db v0.0.3 + ) replace github.com/cometbft/cometbft-db => github.com/notional-labs/cometbft-db v0.0.0-20230321185329-6dc7c0ca6345 diff --git a/go.sum b/go.sum index 1ea1c542db..238beaf820 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.25.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -725,8 +724,6 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/bnb-chain/tss-lib v1.5.0 h1:fuP69k0c4K9kaWCrG+FPH4GDdGZpMRhLyAaA+TyGn0w= -github.com/bnb-chain/tss-lib v1.5.0/go.mod h1:o3zAAo7A88ZJnCE1qpjy1hTqPn+GPQlxRsj8soz14UU= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U= github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg= @@ -1851,7 +1848,6 @@ github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8 github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= @@ -2461,7 +2457,6 @@ github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJCh github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= @@ -2998,7 +2993,6 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSD github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= @@ -3036,14 +3030,12 @@ github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/zeta-chain/go-tss v0.1.0 h1:3sqSQGOW42j516xihIXDx+YjAYMWbCryEt14cufHb+g= -github.com/zeta-chain/go-tss v0.1.0/go.mod h1:pXgFOVodqkNxbjLe6N0Lx8FFjNTDST3C9H8J1/8LNXk= +github.com/zeta-chain/go-tss v0.1.1-0.20240103170132-35850edf5dbd h1:wv+VGLFX8IhPuoqAVQGAQjlEPWqYjowJgJVNReolJTM= +github.com/zeta-chain/go-tss v0.1.1-0.20240103170132-35850edf5dbd/go.mod h1:+lJfk/qqt+oxXeVuJV+PzpUoxftUfoTRf2eF3qlbyFI= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 h1:gd2uE0X+ZbdFJ8DubxNqLbOVlCB12EgWdzSNRAR82tM= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2/go.mod h1:x7Bkwbzt2W2lQfjOirnff0Dj+tykdbTG1FMJPVPZsvE= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b h1:aZRt5BtXdoDdyrUKwcv3B7mS30m/B854cjKjmnXBE5A= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b/go.mod h1:v79f+eY6PMpmLv188FAubst4XV2Mm8mUmx1OgmdFG3c= -github.com/zeta-chain/tss-lib v0.1.7 h1:NkIaK7qIeb2B8z85PW0wnAaEP87ZUvgA/V3el7Kf5Tk= -github.com/zeta-chain/tss-lib v0.1.7/go.mod h1:E1GSdTmOJSq+GVLUEKvTcM/4uqY0MJ3fvs8cqhWwS8Y= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -3053,6 +3045,8 @@ github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2f gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= gitlab.com/thorchain/binance-sdk v1.2.3-0.20210117202539-d569b6b9ba5d h1:GGPSI9gU22zW75m1YO7ZEMFtVEI5NgyK4g17CIXFjqI= gitlab.com/thorchain/binance-sdk v1.2.3-0.20210117202539-d569b6b9ba5d/go.mod h1:SW01IZMpqlPNPdhHnn99qnJNvg8ll/agyyW7p85npwY= +gitlab.com/thorchain/tss/tss-lib v0.1.5 h1:L9MD+E3B4lJmadso69lTIP6s2Iks24fS7Ancs62LTZo= +gitlab.com/thorchain/tss/tss-lib v0.1.5/go.mod h1:pEM3W/1inIzmdQn9IY9pA0MkG1bTGKhsSivxizeyyt4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -3184,7 +3178,6 @@ go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1 gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -3321,7 +3314,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index bff6789ad7..dd75835024 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/binance-chain/tss-lib/ecdsa/keygen" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcutil" ethcommon "github.com/ethereum/go-ethereum/common" @@ -24,7 +25,6 @@ import ( "github.com/zeta-chain/go-tss/keysign" "github.com/zeta-chain/go-tss/p2p" "github.com/zeta-chain/go-tss/tss" - "github.com/zeta-chain/tss-lib/ecdsa/keygen" "github.com/zeta-chain/zetacore/common" zcommon "github.com/zeta-chain/zetacore/common/cosmos" observertypes "github.com/zeta-chain/zetacore/x/observer/types" From f878069abf5e822bf9f470af2faf7923c413b603 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:33:49 -0600 Subject: [PATCH 03/67] fix: block `distribution` module account to receive ZETA (#1522) * block `distribution` module account to receive ZETA * update changelog * fix comment * add more module accounts to blocklist --------- Co-authored-by: Lucas Bertrand --- app/app.go | 21 ++++++++++++++++++++- changelog.md | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index a25a9c7095..d78ef88643 100644 --- a/app/app.go +++ b/app/app.go @@ -196,6 +196,15 @@ var ( emissionsModuleTypes.UndistributedObserverRewardsPool: nil, emissionsModuleTypes.UndistributedTssRewardsPool: nil, } + + // module accounts that are NOT allowed to receive tokens + blockedReceivingModAcc = map[string]bool{ + distrtypes.ModuleName: true, + authtypes.FeeCollectorName: true, + stakingtypes.BondedPoolName: true, + stakingtypes.NotBondedPoolName: true, + govtypes.ModuleName: true, + } ) var _ simapp.App = (*App)(nil) @@ -306,8 +315,9 @@ func New( maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(), ) + logger.Info("bank keeper blocklist addresses", "addresses", app.BlockedAddrs()) app.BankKeeper = bankkeeper.NewBaseKeeper( - appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), nil, + appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(), ) stakingKeeper := stakingkeeper.NewKeeper( appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), @@ -780,3 +790,12 @@ func VerifyAddressFormat(bz []byte) error { func (app *App) SimulationManager() *module.SimulationManager { return app.sm } + +func (app *App) BlockedAddrs() map[string]bool { + blockList := make(map[string]bool) + for k, v := range blockedReceivingModAcc { + addr := authtypes.NewModuleAddress(k) + blockList[addr.String()] = v + } + return blockList +} diff --git a/changelog.md b/changelog.md index c65e43cd55..3266548717 100644 --- a/changelog.md +++ b/changelog.md @@ -26,6 +26,7 @@ * add check to verify new tss has been produced when triggering tss funds migration * fix Athens-3 log print issue - avoid posting uncessary outtx confirmation * fix docker build issues with version: golang:1.20-alpine3.18 +* [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta ### Refactoring From edf5c6a9394c91a263cd4670f63d80190bec6352 Mon Sep 17 00:00:00 2001 From: Charlie <31941002+CharlieMc0@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:43:53 -0700 Subject: [PATCH 04/67] ci: fixing smoketest runners (#1529) * fixing runners * Updated Changelog * removing discord annoucements --- .github/actions/build-binaries/action.yml | 53 -------- .github/actions/build-binaries/readme.md | 11 -- .github/actions/build-zetavisor/action.yml | 20 --- .github/actions/cosmovisor-upgrade/action.yml | 125 ------------------ .github/actions/cosmovisor-upgrade/functions | 32 ----- .github/actions/cosmovisor-upgrade/readme.md | 26 ---- .github/actions/deploy-binaries/action.yml | 97 -------------- .github/actions/deploy-binaries/functions | 43 ------ .github/actions/install-awscli/action.yml | 18 --- .../actions/install-dependencies/action.yml | 17 +-- .github/actions/upload-to-s3/action.yml | 35 ----- .github/actions/upload-to-s3/readme.md | 17 --- .github/workflows/build.yml | 4 +- .github/workflows/publish-release.yml | 41 +----- .github/workflows/rc-release.yml | 38 ------ changelog.md | 1 + 16 files changed, 8 insertions(+), 570 deletions(-) delete mode 100644 .github/actions/build-binaries/action.yml delete mode 100644 .github/actions/build-binaries/readme.md delete mode 100644 .github/actions/build-zetavisor/action.yml delete mode 100644 .github/actions/cosmovisor-upgrade/action.yml delete mode 100644 .github/actions/cosmovisor-upgrade/functions delete mode 100644 .github/actions/cosmovisor-upgrade/readme.md delete mode 100644 .github/actions/deploy-binaries/action.yml delete mode 100644 .github/actions/deploy-binaries/functions delete mode 100644 .github/actions/install-awscli/action.yml delete mode 100644 .github/actions/upload-to-s3/action.yml delete mode 100644 .github/actions/upload-to-s3/readme.md diff --git a/.github/actions/build-binaries/action.yml b/.github/actions/build-binaries/action.yml deleted file mode 100644 index 5e76e8f42e..0000000000 --- a/.github/actions/build-binaries/action.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: 'Build Binaries' -description: 'Builds ZetaChain Binaries' -inputs: - run-tests: - description: 'Run Build Tests (true/false)' - required: false - default: "false" - go-version: - description: 'Optional - Install a specific verion of Go' - required: false - default: '' - ENVIRONMENT_NAME: - description: 'Environment Name' - required: true - default: "STAGING" - -runs: - using: "composite" - steps: - - name: Set Up Go - # Optionally install a specific version of Go - # Only use if go has not been installed in a previous step of the calling workflow - if : ${{ inputs.go-version != '' }} - uses: actions/setup-go@v3 - with: - go-version: ${{ inputs.go-version }} - cache: true - cache-dependency-path: go.mod - - - name: build zetacored and zetaclientd - shell: bash - run: | - make install - cp "$HOME"/go/bin/* ./ - - - name: Run Build tests - if: ${{ inputs.run-tests == 'true' }} - shell: bash - run: | - echo "Running Build Tests" - make test - - - name: Cosmovisor - shell: bash - run: | - go get github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/cosmovisor@zetavisor-v0.1.2 - go install github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/cosmovisor@zetavisor-v0.1.2 - cp "$HOME"/go/bin/cosmovisor ./cosmovisor - - - run: echo "Completed Build Action" - shell: bash - - diff --git a/.github/actions/build-binaries/readme.md b/.github/actions/build-binaries/readme.md deleted file mode 100644 index b45e46479c..0000000000 --- a/.github/actions/build-binaries/readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# Build ZetaChain Binaries - -## Example -``` - - name: Build Binaries - uses: ./.github/actions/build-binaries - with: - run-tests: ${{ env.GITHUB_REF_NAME != 'develop' }} - build-indexer: false - go-version: '1.20' -``` \ No newline at end of file diff --git a/.github/actions/build-zetavisor/action.yml b/.github/actions/build-zetavisor/action.yml deleted file mode 100644 index 26043336bc..0000000000 --- a/.github/actions/build-zetavisor/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: 'BUILD:ZETAVISOR' -description: 'Builds Zetavisor' -inputs: - zetavisor_version: - description: "version to use: zetavisor-v0.1.3" - required: true - workspace_dir: - description: "workspace directory where to copy cosmovisor once built." - required: true -runs: - using: "composite" - steps: - - uses: actions/checkout@v3 - - - name: Build Zetavisor - shell: bash - run: | - go get github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/cosmovisor@${{ inputs.zetavisor_version }} - go install github.com/zeta-chain/cosmos-sdk/cosmovisor/cmd/cosmovisor@${{ inputs.zetavisor_version }} - cp "$HOME"/go/bin/cosmovisor ${{ inputs.workspace_dir }}/cosmovisor \ No newline at end of file diff --git a/.github/actions/cosmovisor-upgrade/action.yml b/.github/actions/cosmovisor-upgrade/action.yml deleted file mode 100644 index 2e7df4e76d..0000000000 --- a/.github/actions/cosmovisor-upgrade/action.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: 'Create Cosmovisor Proposal' -description: 'Creates Cosmovisor Upgrade Proposal and Votes On All TestNet Valiators' -inputs: - UPGRADE_NAME: - description: 'Name of the upgrade (0.0.1)' - required: true - DESCRIPTION: - description: 'Description of the upgrade' - required: false - default: "Description" - ZETACORED_CHECKSUM: - description: 'Hash value of the zetacored binary' - required: true - ZETACORED_URL: - description: 'URL to download the zetacored binary' - required: false - default: "" - ZETACLIENTD_CHECKSUM: - description: 'Hash value of the zetaclientd binary' - required: true - ZETACLIENTD_URL: - description: 'URL to download the zetaclientd binary' - required: false - default: "" - CHAIN_ID: - description: 'Chain ID for the upgrade' - required: true - API_ENDPOINT: - description: 'Endpoint for the ZetaChain API' - required: false - default: "https://api.development.zetachain.com" - UPGRADE_BLOCK_HEIGHT: - description: 'What block height to upgrade at' - required: true - -runs: - using: "composite" - steps: - - - name: Set ENV Variables - shell: bash - run: | - echo Running Cosmovisor Upgrade Action - echo "API_ENDPOINT=${{ inputs.API_ENDPOINT }}" >> $GITHUB_ENV - echo "PATH=$PATH:$(pwd)" >> $GITHUB_ENV - - - name: Get Upgrade Height - shell: bash - run: | - UPGRADE_HEIGHT=${{ inputs.UPGRADE_BLOCK_HEIGHT }} - echo "UPGRADE_HEIGHT=$UPGRADE_HEIGHT" >> $GITHUB_ENV - echo "Proposed Upgrade Height: ${UPGRADE_HEIGHT}" - - - name: Check Inputs & Env Vars - Testing Only - shell: bash - if: ${{ env.ACT }} - run: | - echo "github.ref_name = ${{ github.ref_name }}" - echo "github.event.inputs.ENVIRONMENT = ${{ github.event.inputs.ENVIRONMENT }}" - echo "DESCRIPTION=${{ inputs.DESCRIPTION }}" - echo "ZETACORED_CHECKSUM=${{ env.ZETACORED_CHECKSUM }}" - echo "ZETACLIENTD_CHECKSUM=${{ env.ZETACLIENTD_CHECKSUM }}" - echo "CHAIN_ID=${{ env.CHAIN_ID }}" - echo "API_ENDPOINT=${{ inputs.API_ENDPOINT }}" - echo "ZETACORED_URL=${{ inputs.ZETACORED_URL }}" - echo "ZETACLIENTD_URL=${{ inputs.ZETACLIENTD_URL }}" - - - name: Prepare Validators # Temporary solution until we fix the "account sequence mismatch" GitHub Issue #359 - shell: bash - run: | - source ${{ github.action_path }}/functions - - COMMAND_ID=$(run_validators 'systemctl stop zetaclientd') - echo COMMAND_ID:$COMMAND_ID - check_cmd_status $COMMAND_ID - - COMMAND_ID=$(run_validators "systemctl restart cosmovisor") - check_cmd_status $COMMAND_ID - sleep 20 - - - name: Create & Submit Proposal - shell: bash - run: | - source ${{ github.action_path }}/functions - UPGRADE_INFO="{"binaries":{"linux/arm64":"${{ inputs.ZETACLIENTD_URL }}","linux/amd64":"${{ inputs.ZETACORED_URL }}"}}" - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Name,Values=validator0 \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=['export HOME=/home/zetachain && \ - zetacored tx gov submit-proposal software-upgrade ${{ inputs.UPGRADE_NAME }} \ - --from val \ - --deposit 10000000azeta \ - --upgrade-height ${{ inputs.UPGRADE_BLOCK_HEIGHT }} \ - --description \"${{ inputs.DESCRIPTION }}\" \ - --title \"${{ inputs.UPGRADE_NAME }}\" \ - --keyring-backend test \ - --chain-id \"${{ env.CHAIN_ID }}\" \ - --upgrade-info \'{\"binaries\":{\"zetacored-linux/amd64\":\"${{ inputs.ZETACORED_URL }}?checksum=sha256:${{ env.ZETACORED_CHECKSUM }}\",\"zetaclientd-linux/amd64\":\"${{ inputs.ZETACLIENTD_URL }}?checksum=sha256:${{ env.ZETACLIENTD_CHECKSUM }}\"}}\' \ - --yes']" | jq .Command.CommandId -r || exit 1) - echo COMMAND_ID: $COMMAND_ID - check_cmd_status $COMMAND_ID - sleep 20 - - # upgrade-info With Checksum data --upgrade-info \'{\"binaries\":{\"zetacored-linux/amd64\":\"${{ inputs.ZETACORED_URL }}?checksum=sha256:${{ env.ZETACORED_CHECKSUM }}\",\"zetaclientd-linux/amd64\":\"${{ inputs.ZETACLIENTD_URL }}?checksum=sha256:${{ env.ZETACLIENTD_CHECKSUM }}\"}}\' \ - - - - name: Vote on Proposal (All Validator Nodes) - shell: bash - run: | - source ${{ github.action_path }}/functions - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Role,Values=validator \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=['export HOME=/home/zetachain && zetacored tx gov vote \$(zetacored q gov proposals --status voting_period --reverse -o json | jq -r .proposals[0].proposal_id) yes --from val --keyring-backend test --chain-id $CHAIN_ID --yes']" | jq .Command.CommandId -r || exit 1) - - echo COMMAND_ID: $COMMAND_ID - check_cmd_status $COMMAND_ID - - - name: Resume zetaclientd - shell: bash - run: | - source ${{ github.action_path }}/functions - COMMAND_ID=$(run_validators "systemctl restart zetaclientd") - echo COMMAND_ID: $COMMAND_ID - check_cmd_status $COMMAND_ID \ No newline at end of file diff --git a/.github/actions/cosmovisor-upgrade/functions b/.github/actions/cosmovisor-upgrade/functions deleted file mode 100644 index 90c0ea8a23..0000000000 --- a/.github/actions/cosmovisor-upgrade/functions +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -run_validators () { - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Role,Values=validator \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=[$1]" | jq .Command.CommandId -r || exit 1) - echo "$COMMAND_ID" -} - -run_validator0 () { - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Name,Values=validator0 \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=[$1]" | jq .Command.CommandId -r || exit 1) - echo "$COMMAND_ID" -} - -check_cmd_status () { - COMMAND_ID=$1 - echo "COMMAND_ID: $COMMAND_ID" - COMMAND_STATUS=$(aws ssm list-commands --command-id "$COMMAND_ID" | jq '.Commands[0].Status' -r) - until [[ "$COMMAND_STATUS" == "Success" || "$COMMAND_STATUS" == "Failed" ]]; do - echo "Waiting for Command to complete. ID: $COMMAND_ID | Status: $COMMAND_STATUS" - sleep 2 - COMMAND_STATUS=$(aws ssm list-commands --command-id "$COMMAND_ID" | jq '.Commands[0].Status' -r) - done - echo "Complete. ID: $COMMAND_ID | Status: $COMMAND_STATUS" - if [ "$COMMAND_STATUS" == "Failed" ]; then - echo "Command ID $COMMAND_ID Failed" && exit 1 - fi -} \ No newline at end of file diff --git a/.github/actions/cosmovisor-upgrade/readme.md b/.github/actions/cosmovisor-upgrade/readme.md deleted file mode 100644 index 6d6d747a76..0000000000 --- a/.github/actions/cosmovisor-upgrade/readme.md +++ /dev/null @@ -1,26 +0,0 @@ -# Cosmosvisor Upgrade Proposal - -Creates a cosmovisor upgrade proposal and then issues a vote on all validators - -## Example - - name: Cosmovisor Upgrade Proposal and Vote - uses: ./.github/actions/cosmovisor-upgrade - with: - UPGRADE_NAME: ${{ github.event.inputs.UPGRADE_NAME }} - DESCRIPTION: "Upgrade Description Goes Here" - CHAIN_ID: ${{ env.CHAIN_ID }} - ZETACORED_CHECKSUM: "1234567" #SHA256 - ZETACORED_URL: "https://${{ env.S3_BUCKET_NAME }}.s3.amazonaws.com/builds/zeta-node/develop/zetacored" - ZETACLIENTD_CHECKSUM: "1234567" #SHA256 - ZETACLIENTD_URL: "https://${{ env.S3_BUCKET_NAME }}.s3.amazonaws.com/builds/zeta-node/develop/zetaclientd" - CHAIN_ID: ${{ github.event.inputs.CHAIN_ID }} - API_ENDPOINT: "https://api.${{ github.event.inputs.ENVIRONMENT }}.zetachain.com" - UPGRADE_BLOCK_HEIGHT: 999999 -## Functions File -These are bash functions used by the action. - -## Prerequestices - -### AWS Authentication -You must authenticate to AWS before calling this action - diff --git a/.github/actions/deploy-binaries/action.yml b/.github/actions/deploy-binaries/action.yml deleted file mode 100644 index c5a61e4181..0000000000 --- a/.github/actions/deploy-binaries/action.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: 'Update Nodes' -description: 'Builds ZetaChain Binaries' -inputs: - S3_BUCKET_PATH: - description: 'S3 Bucket Name' - required: true - TAKE_SNAPSHOTS: - description: 'Take Snapshots of Node Storage before update' - required: false - default: "true" - BRANCH_OR_TAG_NAME: - description: 'Name of GitHub tag, branch, or release (Usually $GITHUB_REF_NAME)' - required: true - -runs: - using: "composite" - steps: - - name: Set ENV Variables" - shell: bash - run: | - echo "Running update-nodes Action" - echo "S3_BUCKET_PATH=${{ inputs.S3_BUCKET_PATH }}" >> $GITHUB_ENV - - - name: Get Deployment ID - shell: bash - run: | - echo "${{ inputs.BRANCH_OR_TAG_NAME }}" - echo "GITHUB_REF_NAME=${{ inputs.BRANCH_OR_TAG_NAME }}" >> $GITHUB_ENV - - - name: Snapshot All Running ZetaChain Instances - if: ${{ inputs.TAKE_SNAPSHOTS == 'true' }} - shell: bash - run: | - echo "Taking Snapshots of ZetaChain Instances" - INSTANCE_IDS=$(aws ec2 describe-instances --filters "Name=tag:Role,Values=validator" "Name=instance-state-name,Values=running"| jq -r '.Reservations[].Instances[].InstanceId') - while IFS= read -r INSTANCE_ID; do - echo "$INSTANCE_ID" - aws ec2 create-snapshots \ - --instance-specification InstanceId=$INSTANCE_ID,ExcludeBootVolume=true \ - --description "Snapshot Prior To Deployment ID: ${{ env.GITHUB_REF_NAME }}" \ - --copy-tags-from-source "volume" > jq - done <<< "$INSTANCE_IDS" - sleep 2 - - - name: Copy Package Files - shell: bash - run: | - echo "Copying Package Files from S3 to local node storage" - source ${{ github.action_path }}/functions - COMMAND_ID=$(run_ssm_cmds_validators "mkdir -p /deployment-files/${{ env.GITHUB_REF_NAME }} && wget https://${{ env.S3_BUCKET_PATH }}.s3.amazonaws.com/${{ env.GITHUB_REF_NAME }}/zetacored -O /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored && wget https://${{ env.S3_BUCKET_PATH }}.s3.amazonaws.com/${{ env.GITHUB_REF_NAME }}/zetaclientd -O /deployment-files/${{ env.GITHUB_REF_NAME }}/zetaclientd") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_api_nodes "mkdir -p /deployment-files/${{ env.GITHUB_REF_NAME }} && wget https://${{ env.S3_BUCKET_PATH }}.s3.amazonaws.com/${{ env.GITHUB_REF_NAME }}/zetacored -O /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_archive_nodes "mkdir -p /deployment-files/${{ env.GITHUB_REF_NAME }} && wget https://${{ env.S3_BUCKET_PATH }}.s3.amazonaws.com/${{ env.GITHUB_REF_NAME }}/zetacored -O /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored") - check_cmd_status $COMMAND_ID - - - name: Stop ZetaChain - shell: bash - run: | - echo "Stopping ZetaChain" - source ${{ github.action_path }}/functions - COMMAND_ID=$(run_ssm_cmds_validators "systemctl stop zetaclientd && systemctl stop cosmovisor") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_api_nodes "systemctl stop cosmovisor") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_archive_nodes "systemctl stop cosmovisor") - check_cmd_status $COMMAND_ID - - - name: Update ZetaNode Binaries - shell: bash - run: | - echo "Updating ZetaNode Binaries" - source ${{ github.action_path }}/functions - COMMAND_ID=$(run_ssm_cmds_validators "\ - cp /deployment-files/${{ env.GITHUB_REF_NAME }}/zetaclientd /home/zetachain/.zetacored/cosmovisor/current/bin/zetaclientd && \ - cp /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored /home/zetachain/.zetacored/cosmovisor/current/bin/zetacored") - check_cmd_status $COMMAND_ID - - COMMAND_ID=$(run_ssm_cmds_api_nodes "\ - cp /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored /home/zetachain/.zetacored/cosmovisor/current/bin/zetacored") - check_cmd_status $COMMAND_ID - - COMMAND_ID=$(run_ssm_cmds_archive_nodes "\ - cp /deployment-files/${{ env.GITHUB_REF_NAME }}/zetacored /home/zetachain/.zetacored/cosmovisor/current/bin/zetacored") - check_cmd_status $COMMAND_ID - - - name: Restart ZetaChain - shell: bash - run: | - echo "Restarting ZetaChain" - source ${{ github.action_path }}/functions - COMMAND_ID=$(run_ssm_cmds_validators "systemctl restart cosmovisor && systemctl restart zetaclientd") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_api_nodes "systemctl restart cosmovisor") - check_cmd_status $COMMAND_ID - COMMAND_ID=$(run_ssm_cmds_archive_nodes "systemctl restart cosmovisor") - check_cmd_status $COMMAND_ID diff --git a/.github/actions/deploy-binaries/functions b/.github/actions/deploy-binaries/functions deleted file mode 100644 index ef7836ae7c..0000000000 --- a/.github/actions/deploy-binaries/functions +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -run_ssm_cmds_validators () { - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Role,Values=validator \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=[$1]" | jq .Command.CommandId -r || exit 1) - echo "$COMMAND_ID" -} - -run_ssm_cmds_api_nodes () { - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Role,Values=api \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=[$1]" | jq .Command.CommandId -r || exit 1) - echo "$COMMAND_ID" -} - -run_ssm_cmds_archive_nodes () { - COMMAND_ID=$(aws ssm send-command \ - --targets Key=tag:Role,Values=archive \ - --document-name "AWS-RunShellScript" \ - --parameters "commands=[$1]" | jq .Command.CommandId -r || exit 1) - echo "$COMMAND_ID" -} - -check_cmd_status () { - COMMAND_ID=$1 - echo "COMMAND_ID: $COMMAND_ID" - COMMAND_STATUS=$(aws ssm list-commands --command-id "$COMMAND_ID" | jq '.Commands[0].Status' -r) - until [[ "$COMMAND_STATUS" == "Success" || "$COMMAND_STATUS" == "Failed" ]]; do - echo "Waiting for Command to complete. ID: $COMMAND_ID | Status: $COMMAND_STATUS" - sleep 2 - COMMAND_STATUS=$(aws ssm list-commands --command-id "$COMMAND_ID" | jq '.Commands[0].Status' -r) - done - echo "Complete. ID: $COMMAND_ID | Status: $COMMAND_STATUS" - if [ "$COMMAND_STATUS" == "Failed" ]; then - echo "Command ID $COMMAND_ID Failed" && exit 1 - fi -} - - - diff --git a/.github/actions/install-awscli/action.yml b/.github/actions/install-awscli/action.yml deleted file mode 100644 index f95a72eccd..0000000000 --- a/.github/actions/install-awscli/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: 'AWSCLI:INSTALL' -description: 'Utilized for installing awscli' -inputs: - download_url: - description: "aws cli download url" - required: true -runs: - using: "composite" - steps: - - uses: actions/checkout@v3 - - - name: Install AWS CLI - shell: bash - if: ${{ env.ACT }} - run: | - curl "${{ inputs.download_url }}" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install --update diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index aa51cb5d67..d60a8f4711 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -61,16 +61,7 @@ runs: if: ${{ inputs.skip_docker_compose == 'false' }} shell: bash run: | - sudo apt-get update || echo "Issue running apt-get update." - sudo apt-get install \ - ca-certificates \ - curl \ - gnupg \ - lsb-release -y || echo "issue installing dependencies" - sudo mkdir -p /etc/apt/keyrings - sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --no-tty --batch --dearmor --yes -o /etc/apt/keyrings/docker.gpg - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt-get update || echo "Issue running apt-get update." - sudo apt-get install docker-compose-plugin -y || echo "Issue installing docker compose" + DESTINATION=/usr/local/bin/docker-compose + VERSION=v2.23.3 + sudo curl -L https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m) -o $DESTINATION + sudo chmod 755 $DESTINATION diff --git a/.github/actions/upload-to-s3/action.yml b/.github/actions/upload-to-s3/action.yml deleted file mode 100644 index 3afe70e8a2..0000000000 --- a/.github/actions/upload-to-s3/action.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: 'Upload Deployment Files To S3' -description: 'Uploads Files To S3' -inputs: - bucket-name: - description: 'S3 Bucket Name' - required: true - release-name: - description: 'Name of GitHub tag or release (Usually $GITHUB_REF_NAME)' - required: true - git-sha: - description: 'SHA hash of GitHub commit' - required: true - files: - description: "Newline-delimited list of asset files to upload" - required: true - -runs: - using: "composite" - steps: - - name: Upload Files - run: | - echo "Running Upload-To-S3 Action" - if [[ "${{ inputs.release-name }}" == "develop" ]]; then - echo "Use GITHUB_SHA instead of develop branch name" - S3_PREFIX=${{ inputs.git-sha }} - else - S3_PREFIX=${{ inputs.release-name }} - fi - - while IFS= read -r FILEPATH; do - FILENAME=$(echo "${FILEPATH}" | cut -d / -f2) - aws s3 cp "${FILEPATH}" "s3://${{ inputs.bucket-name }}/${{ inputs.release-name }}/${FILENAME}" - done <<< $(echo "${{ inputs.files }}" | awk NF) - shell: bash - diff --git a/.github/actions/upload-to-s3/readme.md b/.github/actions/upload-to-s3/readme.md deleted file mode 100644 index 33cde7c86d..0000000000 --- a/.github/actions/upload-to-s3/readme.md +++ /dev/null @@ -1,17 +0,0 @@ -# Uploade Files To S3 - - -## Example - -``` - - name: upload-files-to-s3 - uses: ./.github/actions/upload-to-s3 - with: - bucket-name: ${{ env.S3_BUCKET_PATH }} - release-name: "$(echo ${{ github.ref_name }} | tr '//' '-')" - git-sha: ${{ github.sha }} - files: | - zetacored - zetaclientd - cosmovisor -``` \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 93e26a1c31..d71ccd8f2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: cpu_architecture: ${{ env.CPU_ARCH }} skip_python: "true" skip_aws_cli: "true" - skip_docker_compose: "true" + skip_docker_compose: "false" - name: Test uses: nick-fields/retry@v2 @@ -78,7 +78,7 @@ jobs: run: rm -rf * smoke-test: - runs-on: ["zeta-runners"] + runs-on: buildjet-4vcpu-ubuntu-2204 timeout-minutes: 25 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 4f8f08ae6e..951f7a2888 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -130,46 +130,7 @@ jobs: touch .release-env make release - announce-release: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - timeout-minutes: 10 - needs: - - publish-release - steps: - - uses: actions/checkout@v3 - - name: Get Version - run: | - VERSION=$(cat app/setup_handlers.go | grep "const releaseVersion" | cut -d ' ' -f4 | tr -d '"') - echo "BINARY_VERSION=${VERSION}" >> ${GITHUB_ENV} - - - name: Determine Release Type - id: determine_release_type - run: | - if [[ "${{ env.BINARY_VERSION }}" =~ ^v[0-9]+\.0\.0+$ ]]; then - echo "RELEASE_TYPE=major" >> ${GITHUB_ENV} - elif [[ "${{ env.BINARY_VERSION }}" =~ ^v[0-9]+\.[0-9]+\.[1-9]+$ ]]; then - echo "RELEASE_TYPE=minor" >> ${GITHUB_ENV} - else - echo "RELEASE_TYPE=unknown" >> ${GITHUB_ENV} - fi - - - name: "SEND:DISCORD:MESSAGE" - if: steps.determine_release_type.outputs.RELEASE_TYPE == 'major' - uses: gzukel/CosmosComposites/send_discord_message@main - with: - discord_token: "${{ secrets.DISCORD_TOKEN }}" - discord_channel_id: "${{ secrets.DISCORD_CHANNEL_ID }}" - discord_message: | - Hey <@&1122981184255840306>! A new version of the ZetaChain software has been released. - - Major Version Upgrade (e.g. v5.x.x to V6.x.x) must be completed through a governance proposal. - We will submit a governance proposal in the next few days. - More specific information including block height will be shared as part of the governance proposal. - - See the release notes for more details. https://github.com/zeta-chain/node/releases/tag/${{ env.BINARY_VERSION }} - - name: Clean Up Workspace if: always() shell: bash - run: rm -rf * + run: rm -rf * \ No newline at end of file diff --git a/.github/workflows/rc-release.yml b/.github/workflows/rc-release.yml index de91c94649..fcd8faff9c 100644 --- a/.github/workflows/rc-release.yml +++ b/.github/workflows/rc-release.yml @@ -82,44 +82,6 @@ jobs: touch .release-env make release - announce-release: - runs-on: ubuntu-latest - timeout-minutes: 10 - needs: - - publish-release - steps: - - uses: actions/checkout@v3 - - name: Get Version - run: | - VERSION=$(cat app/setup_handlers.go | grep "const releaseVersion" | cut -d ' ' -f4 | tr -d '"') - echo "BINARY_VERSION=${VERSION}" >> ${GITHUB_ENV} - - - name: Determine Release Type - id: determine_release_type - run: | - if [[ "${{ env.BINARY_VERSION }}" =~ ^v[0-9]+\.0\.0+$ ]]; then - echo "RELEASE_TYPE=major" >> ${GITHUB_ENV} - elif [[ "${{ env.BINARY_VERSION }}" =~ ^v[0-9]+\.[0-9]+\.[1-9]+$ ]]; then - echo "RELEASE_TYPE=minor" >> ${GITHUB_ENV} - else - echo "RELEASE_TYPE=unknown" >> ${GITHUB_ENV} - fi - - - name: "SEND:DISCORD:MESSAGE" - if: steps.determine_release_type.outputs.RELEASE_TYPE == 'major' - uses: gzukel/CosmosComposites/send_discord_message@main - with: - discord_token: "${{ secrets.DISCORD_TOKEN }}" - discord_channel_id: "${{ secrets.DISCORD_CHANNEL_ID }}" - discord_message: | - Hey <@&1122981184255840306>! A new version of the ZetaChain software has been released. - - Major Version Upgrade (e.g. v5.x.x to V6.x.x) must be completed through a governance proposal. - We will submit a governance proposal in the next few days. - More specific information including block height will be shared as part of the governance proposal. - - See the release notes for more details. https://github.com/zeta-chain/node/releases/tag/${{ env.BINARY_VERSION }} - - name: Clean Up Workspace if: always() shell: bash diff --git a/changelog.md b/changelog.md index 3266548717..7fa1646871 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,7 @@ ### Tests ### CI +* Removed private runners and unused GitHub Action ## Version: v11.0.0 From 216213e6a4ea3d2098f2d00acddacb9f01e59930 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Mon, 8 Jan 2024 15:55:36 -0800 Subject: [PATCH 05/67] refactor: remove chain id from index for observer set (cherry picked) (#1440) * refactor to have a common observer set across all chains * generate files * add migrate script and test * refactor: move pending nonces, chain nonces and nonce to cctx to observer (#97) * add unit tests for observer set * Update x/observer/keeper/msg_server_update_observer.go Co-authored-by: Lucas Bertrand * Update x/observer/keeper/hooks.go Co-authored-by: Lucas Bertrand * minor changes to observer hooks.go * add changelog * skip ConsensusVersion 4 to make sure the correct migration is triggered * fix module version to trigger observer module migration script * rename SetObervers into SetObserverSet * fix unit tests --------- Co-authored-by: Tanmay Co-authored-by: Tanmay --- app/setup_handlers.go | 4 +- changelog.md | 1 + cmd/zetaclientd/start.go | 2 +- cmd/zetacored/observer_accounts.go | 25 +- .../cli/zetacored/zetacored_query_observer.md | 3 +- ...cored_query_observer_list-observer-set.md} | 8 +- .../zetacored_query_observer_show-observer.md | 33 - docs/openapi/openapi.swagger.yaml | 46 +- proto/observer/genesis.proto | 2 +- proto/observer/observer.proto | 4 + proto/observer/query.proto | 18 +- testutil/keeper/crosschain.go | 2 +- testutil/keeper/mocks/crosschain/observer.go | 58 +- testutil/keeper/mocks/fungible/observer.go | 69 +- testutil/keeper/mocks/mocks.go | 2 +- testutil/network/genesis_state.go | 12 +- testutil/sample/observer.go | 33 +- typescript/observer/genesis_pb.d.ts | 6 +- typescript/observer/observer_pb.d.ts | 24 + typescript/observer/query_pb.d.ts | 82 +- x/crosschain/keeper/keeper.go | 6 +- .../keeper/msg_server_add_to_intx_tracker.go | 2 +- .../keeper/msg_server_add_to_outtx_tracker.go | 2 +- .../keeper/msg_server_gas_price_voter.go | 2 +- .../keeper/msg_server_vote_inbound_tx.go | 2 +- .../keeper/msg_server_vote_outbound_tx.go | 2 +- x/crosschain/migrations/v2/migrate.go | 13 +- x/crosschain/migrations/v4/migrate.go | 6 +- x/crosschain/types/expected_keepers.go | 8 +- x/emissions/keeper/keeper.go | 6 +- x/emissions/types/expected_keepers.go | 19 +- x/fungible/types/expected_keepers.go | 6 +- x/observer/abci.go | 19 +- x/observer/client/cli/query.go | 3 +- x/observer/client/cli/query_observers.go | 41 +- x/observer/genesis.go | 20 +- x/observer/genesis_test.go | 8 +- x/observer/keeper/grpc_query_observer.go | 43 +- x/observer/keeper/hooks.go | 72 +- x/observer/keeper/last_observer_count.go | 25 + x/observer/keeper/migrator.go | 5 + .../keeper/msg_server_add_blame_vote.go | 2 +- .../keeper/msg_server_add_block_header.go | 2 +- .../msg_server_add_block_header_test.go | 6 +- x/observer/keeper/msg_server_add_observer.go | 14 +- .../keeper/msg_server_update_observer.go | 30 +- .../keeper/msg_server_update_observer_test.go | 195 +--- x/observer/keeper/observer_mapper.go | 120 --- x/observer/keeper/observer_mapper_test.go | 194 ---- x/observer/keeper/observer_set.go | 83 ++ x/observer/keeper/observer_set_test.go | 100 ++ x/observer/keeper/utils.go | 41 +- x/observer/keeper/utils_test.go | 49 +- x/observer/migrations/v5/migrate.go | 37 + x/observer/migrations/v5/migrate_test.go | 42 + x/observer/module.go | 5 +- x/observer/types/errors.go | 2 + x/observer/types/genesis.go | 4 +- x/observer/types/genesis.pb.go | 121 ++- x/observer/types/keys.go | 26 +- x/observer/types/observer.pb.go | 231 ++++- x/observer/types/observer_mapper.go | 31 +- x/observer/types/observer_set.go | 9 + x/observer/types/query.pb.go | 883 +++++------------- x/observer/types/query.pb.gw.go | 129 +-- x/observer/types/test_data.go | 24 - zetaclient/btc_signer.go | 2 +- zetaclient/evm_signer.go | 2 +- zetaclient/interfaces.go | 2 +- zetaclient/query.go | 4 +- 70 files changed, 1207 insertions(+), 1927 deletions(-) rename docs/cli/zetacored/{zetacored_query_observer_list-observer.md => zetacored_query_observer_list-observer-set.md} (85%) delete mode 100644 docs/cli/zetacored/zetacored_query_observer_show-observer.md create mode 100644 x/observer/keeper/last_observer_count.go delete mode 100644 x/observer/keeper/observer_mapper.go delete mode 100644 x/observer/keeper/observer_mapper_test.go create mode 100644 x/observer/keeper/observer_set.go create mode 100644 x/observer/keeper/observer_set_test.go create mode 100644 x/observer/migrations/v5/migrate.go create mode 100644 x/observer/migrations/v5/migrate_test.go create mode 100644 x/observer/types/observer_set.go diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 1a8cb053a3..8948c68527 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) const releaseVersion = "v11.0.0" @@ -17,7 +18,8 @@ func SetupHandlers(app *App) { for m, mb := range app.mm.Modules { vm[m] = mb.ConsensusVersion() } - vm[crosschaintypes.ModuleName] = vm[crosschaintypes.ModuleName] - 1 + vm[crosschaintypes.ModuleName] = 3 + vm[observertypes.ModuleName] = 4 return app.mm.RunMigrations(ctx, app.configurator, vm) }) diff --git a/changelog.md b/changelog.md index 7fa1646871..eeb890d260 100644 --- a/changelog.md +++ b/changelog.md @@ -39,6 +39,7 @@ * Add pagination to queries which iterate over large data sets InTxTrackerAll ,PendingNoncesAll ,AllBlameRecord ,TssHistory * GetTssAddress now returns only the current tss address for ETH and BTC * Add a new query GetTssAddressesByFinalizedBlockHeight to get any other tss addresses for a finalized block height +* Remove chain id from the index for observer mapper and rename it to observer set. * Add logger to smoke tests * [1521](https://github.com/zeta-chain/node/pull/1521) - replace go-tss lib version with one that reverts back to thorchain tss-lib diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 99173be7ae..f0528fb9d1 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -198,7 +198,7 @@ func start(_ *cobra.Command, _ []string) error { startLogger.Error().Msgf("No chains enabled in updated config %s ", cfg.String()) } - observerList, err := zetaBridge.GetObserverList(cfg.ChainsEnabled[0]) + observerList, err := zetaBridge.GetObserverList() if err != nil { startLogger.Error().Err(err).Msg("GetObserverList error") return err diff --git a/cmd/zetacored/observer_accounts.go b/cmd/zetacored/observer_accounts.go index 878f97cb15..38768c5926 100644 --- a/cmd/zetacored/observer_accounts.go +++ b/cmd/zetacored/observer_accounts.go @@ -72,14 +72,11 @@ func AddObserverAccountsCmd() *cobra.Command { if err != nil { return err } - var observerMapper []*types.ObserverMapper + var observerSet types.ObserverSet var grantAuthorizations []authz.GrantAuthorization var nodeAccounts []*types.NodeAccount var keygenPubKeys []string - observersForChain := map[int64][]string{} - // DefaultChainsList is based on Build Flags - supportedChains := common.DefaultChainsList() var balances []banktypes.Balance validatorTokens, ok := sdk.NewIntFromString(ValidatorTokens) if !ok { @@ -115,9 +112,8 @@ func AddObserverAccountsCmd() *cobra.Command { panic("ZetaClientGranteeAddress or ObserverAddress is empty") } grantAuthorizations = append(grantAuthorizations, generateGrants(info)...) - for _, chain := range supportedChains { - observersForChain[chain.ChainId] = append(observersForChain[chain.ChainId], info.ObserverAddress) - } + + observerSet.ObserverList = append(observerSet.ObserverList, info.ObserverAddress) if info.ZetaClientGranteePubKey != "" { pubkey, err := common.NewPubKey(info.ZetaClientGranteePubKey) if err != nil { @@ -143,17 +139,6 @@ func AddObserverAccountsCmd() *cobra.Command { keygenPubKeys = append(keygenPubKeys, info.ZetaClientGranteePubKey) } - // Generate observer mappers for each chain - for chainID, observers := range observersForChain { - observers = removeDuplicate(observers) - chain := common.GetChainFromChainID(chainID) - mapper := types.ObserverMapper{ - ObserverChain: chain, - ObserverList: observers, - } - observerMapper = append(observerMapper, &mapper) - } - genFile := serverConfig.GenesisFile() appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) if err != nil { @@ -176,10 +161,10 @@ func AddObserverAccountsCmd() *cobra.Command { KeyGenZetaHeight: 0, } } - + observerSet.ObserverList = removeDuplicate(observerSet.ObserverList) // Add observers to observer genesis state zetaObserverGenState := types.GetGenesisStateFromAppState(cdc, appState) - zetaObserverGenState.Observers = observerMapper + zetaObserverGenState.Observers = observerSet zetaObserverGenState.NodeAccountList = nodeAccounts zetaObserverGenState.Tss = &tss keyGenStatus := types.KeygenStatus_PendingKeygen diff --git a/docs/cli/zetacored/zetacored_query_observer.md b/docs/cli/zetacored/zetacored_query_observer.md index 73492a3bf1..4b6679e5df 100644 --- a/docs/cli/zetacored/zetacored_query_observer.md +++ b/docs/cli/zetacored/zetacored_query_observer.md @@ -33,7 +33,7 @@ zetacored query observer [flags] * [zetacored query observer list-chains](zetacored_query_observer_list-chains.md) - list all SupportedChains * [zetacored query observer list-core-params](zetacored_query_observer_list-core-params.md) - Query GetCoreParams * [zetacored query observer list-node-account](zetacored_query_observer_list-node-account.md) - list all NodeAccount -* [zetacored query observer list-observer](zetacored_query_observer_list-observer.md) - Query All Observer Mappers +* [zetacored query observer list-observer-set](zetacored_query_observer_list-observer-set.md) - Query observer set * [zetacored query observer list-pending-nonces](zetacored_query_observer_list-pending-nonces.md) - shows a chainNonces * [zetacored query observer list-tss-history](zetacored_query_observer_list-tss-history.md) - show historical list of TSS * [zetacored query observer params](zetacored_query_observer_params.md) - shows the parameters of the module @@ -44,7 +44,6 @@ zetacored query observer [flags] * [zetacored query observer show-crosschain-flags](zetacored_query_observer_show-crosschain-flags.md) - shows the crosschain flags * [zetacored query observer show-keygen](zetacored_query_observer_show-keygen.md) - shows keygen * [zetacored query observer show-node-account](zetacored_query_observer_show-node-account.md) - shows a NodeAccount -* [zetacored query observer show-observer](zetacored_query_observer_show-observer.md) - Query ObserversByChainAndType , Use common.chain for querying * [zetacored query observer show-observer-count](zetacored_query_observer_show-observer-count.md) - Query show-observer-count * [zetacored query observer show-tss](zetacored_query_observer_show-tss.md) - shows a TSS diff --git a/docs/cli/zetacored/zetacored_query_observer_list-observer.md b/docs/cli/zetacored/zetacored_query_observer_list-observer-set.md similarity index 85% rename from docs/cli/zetacored/zetacored_query_observer_list-observer.md rename to docs/cli/zetacored/zetacored_query_observer_list-observer-set.md index 55e179fcdd..506d5d86e2 100644 --- a/docs/cli/zetacored/zetacored_query_observer_list-observer.md +++ b/docs/cli/zetacored/zetacored_query_observer_list-observer-set.md @@ -1,9 +1,9 @@ -# query observer list-observer +# query observer list-observer-set -Query All Observer Mappers +Query observer set ``` -zetacored query observer list-observer [flags] +zetacored query observer list-observer-set [flags] ``` ### Options @@ -12,7 +12,7 @@ zetacored query observer list-observer [flags] --grpc-addr string the gRPC endpoint to use for this chain --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS --height int Use a specific height to query state at (this can error if the node is pruning state) - -h, --help help for list-observer + -h, --help help for list-observer-set --node string [host]:[port] to Tendermint RPC interface for this chain -o, --output string Output format (text|json) ``` diff --git a/docs/cli/zetacored/zetacored_query_observer_show-observer.md b/docs/cli/zetacored/zetacored_query_observer_show-observer.md deleted file mode 100644 index decc06cd60..0000000000 --- a/docs/cli/zetacored/zetacored_query_observer_show-observer.md +++ /dev/null @@ -1,33 +0,0 @@ -# query observer show-observer - -Query ObserversByChainAndType , Use common.chain for querying - -``` -zetacored query observer show-observer [observation-chain] [flags] -``` - -### Options - -``` - --grpc-addr string the gRPC endpoint to use for this chain - --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS - --height int Use a specific height to query state at (this can error if the node is pruning state) - -h, --help help for show-observer - --node string [host]:[port] to Tendermint RPC interface for this chain - -o, --output string Output format (text|json) -``` - -### Options inherited from parent commands - -``` - --chain-id string The network chain ID - --home string directory for config and data - --log_format string The logging format (json|plain) - --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) - --trace print out full stack trace on errors -``` - -### SEE ALSO - -* [zetacored query observer](zetacored_query_observer.md) - Querying commands for the observer module - diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 2ae06c6b6d..23743e4e66 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27446,20 +27446,6 @@ paths: $ref: '#/definitions/googlerpcStatus' tags: - Query - /zeta-chain/observer/all_observer_mappers: - get: - operationId: Query_AllObserverMappers - responses: - "200": - description: A successful response. - schema: - $ref: '#/definitions/observerQueryAllObserverMappersResponse' - default: - description: An unexpected error response. - schema: - $ref: '#/definitions/googlerpcStatus' - tags: - - Query /zeta-chain/observer/ballot_by_identifier/{ballot_identifier}: get: summary: Queries a list of VoterByIdentifier items. @@ -27976,24 +27962,19 @@ paths: type: string tags: - Query - /zeta-chain/observer/observers_by_chain/{observation_chain}: + /zeta-chain/observer/observer_set: get: summary: Queries a list of ObserversByChainAndType items. - operationId: Query_ObserversByChain + operationId: Query_ObserverSet responses: "200": description: A successful response. schema: - $ref: '#/definitions/observerQueryObserversByChainResponse' + $ref: '#/definitions/observerQueryObserverSetResponse' default: description: An unexpected error response. schema: $ref: '#/definitions/googlerpcStatus' - parameters: - - name: observation_chain - in: path - required: true - type: string tags: - Query /zeta-chain/observer/params: @@ -51464,17 +51445,6 @@ definitions: - TSSKeyGen - TSSKeySign default: EmptyObserverType - observerObserverMapper: - type: object - properties: - index: - type: string - observer_chain: - $ref: '#/definitions/commonChain' - observer_list: - type: array - items: - type: string observerObserverParams: type: object properties: @@ -51554,14 +51524,6 @@ definitions: $ref: '#/definitions/observerNodeAccount' pagination: $ref: '#/definitions/v1beta1PageResponse' - observerQueryAllObserverMappersResponse: - type: object - properties: - observer_mappers: - type: array - items: - type: object - $ref: '#/definitions/observerObserverMapper' observerQueryAllPendingNoncesResponse: type: object properties: @@ -51663,7 +51625,7 @@ definitions: properties: has_voted: type: boolean - observerQueryObserversByChainResponse: + observerQueryObserverSetResponse: type: object properties: observers: diff --git a/proto/observer/genesis.proto b/proto/observer/genesis.proto index d8a7e306a8..b8aaef283d 100644 --- a/proto/observer/genesis.proto +++ b/proto/observer/genesis.proto @@ -19,7 +19,7 @@ option go_package = "github.com/zeta-chain/zetacore/x/observer/types"; message GenesisState { repeated Ballot ballots = 1; - repeated ObserverMapper observers = 2; + ObserverSet observers = 2 [(gogoproto.nullable) = false]; repeated NodeAccount nodeAccountList = 3; CrosschainFlags crosschain_flags = 4; Params params = 5; diff --git a/proto/observer/observer.proto b/proto/observer/observer.proto index 32be146492..2c3cf0b931 100644 --- a/proto/observer/observer.proto +++ b/proto/observer/observer.proto @@ -28,6 +28,10 @@ message ObserverMapper { repeated string observer_list = 4; } +message ObserverSet { + repeated string observer_list = 1; +} + message LastObserverCount { uint64 count = 1; int64 last_change_height = 2; diff --git a/proto/observer/query.proto b/proto/observer/query.proto index 4060bbdbed..2796372004 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -35,11 +35,8 @@ service Query { } // Queries a list of ObserversByChainAndType items. - rpc ObserversByChain(QueryObserversByChainRequest) returns (QueryObserversByChainResponse) { - option (google.api.http).get = "/zeta-chain/observer/observers_by_chain/{observation_chain}"; - } - rpc AllObserverMappers(QueryAllObserverMappersRequest) returns (QueryAllObserverMappersResponse) { - option (google.api.http).get = "/zeta-chain/observer/all_observer_mappers"; + rpc ObserverSet(QueryObserverSet) returns (QueryObserverSetResponse) { + option (google.api.http).get = "/zeta-chain/observer/observer_set"; } rpc SupportedChains(QuerySupportedChains) returns (QuerySupportedChainsResponse) { @@ -261,19 +258,12 @@ message QueryBallotByIdentifierResponse { BallotStatus ballot_status = 4; } -message QueryObserversByChainRequest { - string observation_chain = 1; -} +message QueryObserverSet {} -message QueryObserversByChainResponse { +message QueryObserverSetResponse { repeated string observers = 1; } -message QueryAllObserverMappersRequest {} -message QueryAllObserverMappersResponse { - repeated ObserverMapper observer_mappers = 1; -} - message QuerySupportedChains {} message QuerySupportedChainsResponse { diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index 2bc0eed3a0..69f2ae68f4 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -72,7 +72,7 @@ func CrosschainKeeperWithMocks( ObserverKeeper: observerKeeperTmp, FungibleKeeper: fungiblekeeperTmp, } - var observerKeeper types.ZetaObserverKeeper = observerKeeperTmp + var observerKeeper types.ObserverKeeper = observerKeeperTmp var fungibleKeeper types.FungibleKeeper = fungiblekeeperTmp // Create the fungible keeper diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index 2f3bfb7669..369062b2fb 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -223,26 +223,6 @@ func (_m *CrosschainObserverKeeper) GetAllNonceToCctx(ctx types.Context) []obser return r0 } -// GetAllObserverMappers provides a mock function with given fields: ctx -func (_m *CrosschainObserverKeeper) GetAllObserverMappers(ctx types.Context) []*observertypes.ObserverMapper { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetAllObserverMappers") - } - - var r0 []*observertypes.ObserverMapper - if rf, ok := ret.Get(0).(func(types.Context) []*observertypes.ObserverMapper); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*observertypes.ObserverMapper) - } - } - - return r0 -} - // GetAllPendingNonces provides a mock function with given fields: ctx func (_m *CrosschainObserverKeeper) GetAllPendingNonces(ctx types.Context) ([]observertypes.PendingNonces, error) { ret := _m.Called(ctx) @@ -567,27 +547,27 @@ func (_m *CrosschainObserverKeeper) GetNonceToCctx(ctx types.Context, tss string return r0, r1 } -// GetObserverMapper provides a mock function with given fields: ctx, chain -func (_m *CrosschainObserverKeeper) GetObserverMapper(ctx types.Context, chain *common.Chain) (observertypes.ObserverMapper, bool) { - ret := _m.Called(ctx, chain) +// GetObserverSet provides a mock function with given fields: ctx +func (_m *CrosschainObserverKeeper) GetObserverSet(ctx types.Context) (observertypes.ObserverSet, bool) { + ret := _m.Called(ctx) if len(ret) == 0 { - panic("no return value specified for GetObserverMapper") + panic("no return value specified for GetObserverSet") } - var r0 observertypes.ObserverMapper + var r0 observertypes.ObserverSet var r1 bool - if rf, ok := ret.Get(0).(func(types.Context, *common.Chain) (observertypes.ObserverMapper, bool)); ok { - return rf(ctx, chain) + if rf, ok := ret.Get(0).(func(types.Context) (observertypes.ObserverSet, bool)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func(types.Context, *common.Chain) observertypes.ObserverMapper); ok { - r0 = rf(ctx, chain) + if rf, ok := ret.Get(0).(func(types.Context) observertypes.ObserverSet); ok { + r0 = rf(ctx) } else { - r0 = ret.Get(0).(observertypes.ObserverMapper) + r0 = ret.Get(0).(observertypes.ObserverSet) } - if rf, ok := ret.Get(1).(func(types.Context, *common.Chain) bool); ok { - r1 = rf(ctx, chain) + if rf, ok := ret.Get(1).(func(types.Context) bool); ok { + r1 = rf(ctx) } else { r1 = ret.Get(1).(bool) } @@ -727,17 +707,17 @@ func (_m *CrosschainObserverKeeper) GetTssAddress(goCtx context.Context, req *ob return r0, r1 } -// IsAuthorized provides a mock function with given fields: ctx, address, chain -func (_m *CrosschainObserverKeeper) IsAuthorized(ctx types.Context, address string, chain *common.Chain) bool { - ret := _m.Called(ctx, address, chain) +// IsAuthorized provides a mock function with given fields: ctx, address +func (_m *CrosschainObserverKeeper) IsAuthorized(ctx types.Context, address string) bool { + ret := _m.Called(ctx, address) if len(ret) == 0 { panic("no return value specified for IsAuthorized") } var r0 bool - if rf, ok := ret.Get(0).(func(types.Context, string, *common.Chain) bool); ok { - r0 = rf(ctx, address, chain) + if rf, ok := ret.Get(0).(func(types.Context, string) bool); ok { + r0 = rf(ctx, address) } else { r0 = ret.Get(0).(bool) } @@ -823,8 +803,8 @@ func (_m *CrosschainObserverKeeper) SetNonceToCctx(ctx types.Context, nonceToCct _m.Called(ctx, nonceToCctx) } -// SetObserverMapper provides a mock function with given fields: ctx, om -func (_m *CrosschainObserverKeeper) SetObserverMapper(ctx types.Context, om *observertypes.ObserverMapper) { +// SetObservers provides a mock function with given fields: ctx, om +func (_m *CrosschainObserverKeeper) SetObservers(ctx types.Context, om observertypes.ObserverSet) { _m.Called(ctx, om) } diff --git a/testutil/keeper/mocks/fungible/observer.go b/testutil/keeper/mocks/fungible/observer.go index 28fcbba60a..479fda3f80 100644 --- a/testutil/keeper/mocks/fungible/observer.go +++ b/testutil/keeper/mocks/fungible/observer.go @@ -4,7 +4,6 @@ package mocks import ( mock "github.com/stretchr/testify/mock" - common "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" @@ -36,26 +35,6 @@ func (_m *FungibleObserverKeeper) GetAllBallots(ctx types.Context) []*observerty return r0 } -// GetAllObserverMappers provides a mock function with given fields: ctx -func (_m *FungibleObserverKeeper) GetAllObserverMappers(ctx types.Context) []*observertypes.ObserverMapper { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetAllObserverMappers") - } - - var r0 []*observertypes.ObserverMapper - if rf, ok := ret.Get(0).(func(types.Context) []*observertypes.ObserverMapper); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*observertypes.ObserverMapper) - } - } - - return r0 -} - // GetBallot provides a mock function with given fields: ctx, index func (_m *FungibleObserverKeeper) GetBallot(ctx types.Context, index string) (observertypes.Ballot, bool) { ret := _m.Called(ctx, index) @@ -114,27 +93,47 @@ func (_m *FungibleObserverKeeper) GetCoreParamsByChainID(ctx types.Context, chai return r0, r1 } -// GetObserverMapper provides a mock function with given fields: ctx, chain -func (_m *FungibleObserverKeeper) GetObserverMapper(ctx types.Context, chain *common.Chain) (observertypes.ObserverMapper, bool) { - ret := _m.Called(ctx, chain) +// GetMaturedBallotList provides a mock function with given fields: ctx +func (_m *FungibleObserverKeeper) GetMaturedBallotList(ctx types.Context) []string { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetMaturedBallotList") + } + + var r0 []string + if rf, ok := ret.Get(0).(func(types.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// GetObserverSet provides a mock function with given fields: ctx +func (_m *FungibleObserverKeeper) GetObserverSet(ctx types.Context) (observertypes.ObserverSet, bool) { + ret := _m.Called(ctx) if len(ret) == 0 { - panic("no return value specified for GetObserverMapper") + panic("no return value specified for GetObserverSet") } - var r0 observertypes.ObserverMapper + var r0 observertypes.ObserverSet var r1 bool - if rf, ok := ret.Get(0).(func(types.Context, *common.Chain) (observertypes.ObserverMapper, bool)); ok { - return rf(ctx, chain) + if rf, ok := ret.Get(0).(func(types.Context) (observertypes.ObserverSet, bool)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func(types.Context, *common.Chain) observertypes.ObserverMapper); ok { - r0 = rf(ctx, chain) + if rf, ok := ret.Get(0).(func(types.Context) observertypes.ObserverSet); ok { + r0 = rf(ctx) } else { - r0 = ret.Get(0).(observertypes.ObserverMapper) + r0 = ret.Get(0).(observertypes.ObserverSet) } - if rf, ok := ret.Get(1).(func(types.Context, *common.Chain) bool); ok { - r1 = rf(ctx, chain) + if rf, ok := ret.Get(1).(func(types.Context) bool); ok { + r1 = rf(ctx) } else { r1 = ret.Get(1).(bool) } @@ -165,8 +164,8 @@ func (_m *FungibleObserverKeeper) SetBallot(ctx types.Context, ballot *observert _m.Called(ctx, ballot) } -// SetObserverMapper provides a mock function with given fields: ctx, om -func (_m *FungibleObserverKeeper) SetObserverMapper(ctx types.Context, om *observertypes.ObserverMapper) { +// SetObservers provides a mock function with given fields: ctx, om +func (_m *FungibleObserverKeeper) SetObservers(ctx types.Context, om observertypes.ObserverSet) { _m.Called(ctx, om) } diff --git a/testutil/keeper/mocks/mocks.go b/testutil/keeper/mocks/mocks.go index 53e5842e65..dbbdeccd76 100644 --- a/testutil/keeper/mocks/mocks.go +++ b/testutil/keeper/mocks/mocks.go @@ -26,7 +26,7 @@ type CrosschainStakingKeeper interface { //go:generate mockery --name CrosschainObserverKeeper --filename observer.go --case underscore --output ./crosschain type CrosschainObserverKeeper interface { - crosschaintypes.ZetaObserverKeeper + crosschaintypes.ObserverKeeper } //go:generate mockery --name CrosschainFungibleKeeper --filename fungible.go --case underscore --output ./crosschain diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index 623115330d..550b8190da 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -54,14 +54,10 @@ func SetupZetaGenesisState(t *testing.T, genesisState map[string]json.RawMessage // Observer genesis state var observerGenesis observertypes.GenesisState assert.NoError(t, codec.UnmarshalJSON(genesisState[observertypes.ModuleName], &observerGenesis)) - observerMapper := make([]*observertypes.ObserverMapper, len(common.PrivnetChainList())) - - for i, chain := range common.PrivnetChainList() { - observerMapper[i] = &observertypes.ObserverMapper{ - ObserverChain: chain, - ObserverList: observerList, - } + observerSet := observertypes.ObserverSet{ + ObserverList: observerList, } + if setupChainNonces { chainNonceList := make([]observertypes.ChainNonces, len(common.PrivnetChainList())) for i, chain := range common.PrivnetChainList() { @@ -74,7 +70,7 @@ func SetupZetaGenesisState(t *testing.T, genesisState map[string]json.RawMessage observerGenesis.ChainNonces = chainNonceList } - observerGenesis.Observers = observerMapper + observerGenesis.Observers = observerSet observerGenesis.NodeAccountList = nodeAccountList observerGenesis.Keygen = &observertypes.Keygen{ Status: observertypes.KeygenStatus_PendingKeygen, diff --git a/testutil/sample/observer.go b/testutil/sample/observer.go index ac1395411e..0fdf820573 100644 --- a/testutil/sample/observer.go +++ b/testutil/sample/observer.go @@ -27,13 +27,14 @@ func Ballot(t *testing.T, index string) *types.Ballot { } } -func ObserverMapper(t *testing.T, index string) *types.ObserverMapper { - r := newRandFromStringSeed(t, index) +func ObserverSet(n int) types.ObserverSet { + observerList := make([]string, n) + for i := 0; i < n; i++ { + observerList[i] = AccAddress() + } - return &types.ObserverMapper{ - Index: index, - ObserverChain: Chain(r.Int63()), - ObserverList: []string{AccAddress(), AccAddress()}, + return types.ObserverSet{ + ObserverList: observerList, } } @@ -200,3 +201,23 @@ func NonceToCctxList(t *testing.T, index string, count int) []types.NonceToCctx } return list } + +func LegacyObserverMapper(t *testing.T, index string, observerList []string) *types.ObserverMapper { + r := newRandFromStringSeed(t, index) + + return &types.ObserverMapper{ + Index: index, + ObserverChain: Chain(r.Int63()), + ObserverList: observerList, + } +} + +func LegacyObserverMapperList(t *testing.T, n int, index string) []*types.ObserverMapper { + r := newRandFromStringSeed(t, index) + observerList := []string{AccAddress(), AccAddress()} + observerMapperList := make([]*types.ObserverMapper, n) + for i := 0; i < n; i++ { + observerMapperList[i] = LegacyObserverMapper(t, fmt.Sprintf("%d-%s", r.Int63(), index), observerList) + } + return observerMapperList +} diff --git a/typescript/observer/genesis_pb.d.ts b/typescript/observer/genesis_pb.d.ts index 6c6c1dc2b5..8325515c35 100644 --- a/typescript/observer/genesis_pb.d.ts +++ b/typescript/observer/genesis_pb.d.ts @@ -6,7 +6,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; import type { Ballot } from "./ballot_pb.js"; -import type { LastObserverCount, ObserverMapper } from "./observer_pb.js"; +import type { LastObserverCount, ObserverSet } from "./observer_pb.js"; import type { NodeAccount } from "./node_account_pb.js"; import type { CrosschainFlags } from "./crosschain_flags_pb.js"; import type { CoreParamsList, Params } from "./params_pb.js"; @@ -28,9 +28,9 @@ export declare class GenesisState extends Message { ballots: Ballot[]; /** - * @generated from field: repeated zetachain.zetacore.observer.ObserverMapper observers = 2; + * @generated from field: zetachain.zetacore.observer.ObserverSet observers = 2; */ - observers: ObserverMapper[]; + observers?: ObserverSet; /** * @generated from field: repeated zetachain.zetacore.observer.NodeAccount nodeAccountList = 3; diff --git a/typescript/observer/observer_pb.d.ts b/typescript/observer/observer_pb.d.ts index d348caf97e..cf8f1beb79 100644 --- a/typescript/observer/observer_pb.d.ts +++ b/typescript/observer/observer_pb.d.ts @@ -91,6 +91,30 @@ export declare class ObserverMapper extends Message { static equals(a: ObserverMapper | PlainMessage | undefined, b: ObserverMapper | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.observer.ObserverSet + */ +export declare class ObserverSet extends Message { + /** + * @generated from field: repeated string observer_list = 1; + */ + observerList: string[]; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.ObserverSet"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): ObserverSet; + + static fromJson(jsonValue: JsonValue, options?: Partial): ObserverSet; + + static fromJsonString(jsonString: string, options?: Partial): ObserverSet; + + static equals(a: ObserverSet | PlainMessage | undefined, b: ObserverSet | PlainMessage | undefined): boolean; +} + /** * @generated from message zetachain.zetacore.observer.LastObserverCount */ diff --git a/typescript/observer/query_pb.d.ts b/typescript/observer/query_pb.d.ts index 6b3f4ad055..273f51c470 100644 --- a/typescript/observer/query_pb.d.ts +++ b/typescript/observer/query_pb.d.ts @@ -12,7 +12,7 @@ import type { TSS } from "./tss_pb.js"; import type { BlockHeader, Chain, Proof } from "../common/common_pb.js"; import type { CoreParams, CoreParamsList, Params } from "./params_pb.js"; import type { BallotStatus, VoteType } from "./ballot_pb.js"; -import type { LastObserverCount, ObservationType, ObserverMapper } from "./observer_pb.js"; +import type { LastObserverCount, ObservationType } from "./observer_pb.js"; import type { NodeAccount } from "./node_account_pb.js"; import type { CrosschainFlags } from "./crosschain_flags_pb.js"; import type { Keygen } from "./keygen_pb.js"; @@ -689,94 +689,46 @@ export declare class QueryBallotByIdentifierResponse extends Message { - /** - * @generated from field: string observation_chain = 1; - */ - observationChain: string; - - constructor(data?: PartialMessage); +export declare class QueryObserverSet extends Message { + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryObserversByChainRequest"; + static readonly typeName = "zetachain.zetacore.observer.QueryObserverSet"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryObserversByChainRequest; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryObserverSet; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryObserversByChainRequest; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryObserverSet; - static fromJsonString(jsonString: string, options?: Partial): QueryObserversByChainRequest; + static fromJsonString(jsonString: string, options?: Partial): QueryObserverSet; - static equals(a: QueryObserversByChainRequest | PlainMessage | undefined, b: QueryObserversByChainRequest | PlainMessage | undefined): boolean; + static equals(a: QueryObserverSet | PlainMessage | undefined, b: QueryObserverSet | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.QueryObserversByChainResponse + * @generated from message zetachain.zetacore.observer.QueryObserverSetResponse */ -export declare class QueryObserversByChainResponse extends Message { +export declare class QueryObserverSetResponse extends Message { /** * @generated from field: repeated string observers = 1; */ observers: string[]; - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryObserversByChainResponse"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): QueryObserversByChainResponse; - - static fromJson(jsonValue: JsonValue, options?: Partial): QueryObserversByChainResponse; - - static fromJsonString(jsonString: string, options?: Partial): QueryObserversByChainResponse; - - static equals(a: QueryObserversByChainResponse | PlainMessage | undefined, b: QueryObserversByChainResponse | PlainMessage | undefined): boolean; -} - -/** - * @generated from message zetachain.zetacore.observer.QueryAllObserverMappersRequest - */ -export declare class QueryAllObserverMappersRequest extends Message { - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryAllObserverMappersRequest"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): QueryAllObserverMappersRequest; - - static fromJson(jsonValue: JsonValue, options?: Partial): QueryAllObserverMappersRequest; - - static fromJsonString(jsonString: string, options?: Partial): QueryAllObserverMappersRequest; - - static equals(a: QueryAllObserverMappersRequest | PlainMessage | undefined, b: QueryAllObserverMappersRequest | PlainMessage | undefined): boolean; -} - -/** - * @generated from message zetachain.zetacore.observer.QueryAllObserverMappersResponse - */ -export declare class QueryAllObserverMappersResponse extends Message { - /** - * @generated from field: repeated zetachain.zetacore.observer.ObserverMapper observer_mappers = 1; - */ - observerMappers: ObserverMapper[]; - - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryAllObserverMappersResponse"; + static readonly typeName = "zetachain.zetacore.observer.QueryObserverSetResponse"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryAllObserverMappersResponse; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryObserverSetResponse; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryAllObserverMappersResponse; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryObserverSetResponse; - static fromJsonString(jsonString: string, options?: Partial): QueryAllObserverMappersResponse; + static fromJsonString(jsonString: string, options?: Partial): QueryObserverSetResponse; - static equals(a: QueryAllObserverMappersResponse | PlainMessage | undefined, b: QueryAllObserverMappersResponse | PlainMessage | undefined): boolean; + static equals(a: QueryObserverSetResponse | PlainMessage | undefined, b: QueryObserverSetResponse | PlainMessage | undefined): boolean; } /** diff --git a/x/crosschain/keeper/keeper.go b/x/crosschain/keeper/keeper.go index 877bd56016..52b25bb981 100644 --- a/x/crosschain/keeper/keeper.go +++ b/x/crosschain/keeper/keeper.go @@ -23,7 +23,7 @@ type ( paramstore paramtypes.Subspace authKeeper types.AccountKeeper bankKeeper types.BankKeeper - zetaObserverKeeper types.ZetaObserverKeeper + zetaObserverKeeper types.ObserverKeeper fungibleKeeper types.FungibleKeeper } ) @@ -36,7 +36,7 @@ func NewKeeper( paramstore paramtypes.Subspace, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, - zetaObserverKeeper types.ZetaObserverKeeper, + zetaObserverKeeper types.ObserverKeeper, fungibleKeeper types.FungibleKeeper, ) *Keeper { // ensure governance module account is set @@ -78,7 +78,7 @@ func (k Keeper) GetFungibleKeeper() types.FungibleKeeper { return k.fungibleKeeper } -func (k Keeper) GetObserverKeeper() types.ZetaObserverKeeper { +func (k Keeper) GetObserverKeeper() types.ObserverKeeper { return k.zetaObserverKeeper } diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go index d8f942f737..2a241c7f23 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go @@ -23,7 +23,7 @@ func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToIn adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_group1) isAdmin := msg.Creator == adminPolicyAccount - isObserver := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain) + isObserver := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator) isProven := false if !(isAdmin || isObserver) && msg.Proof != nil { diff --git a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go index 31d124e7e6..4817d3b75c 100644 --- a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go @@ -32,7 +32,7 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO if msg.Proof == nil { // without proof, only certain accounts can send this message adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_group1) isAdmin := msg.Creator == adminPolicyAccount - isObserver := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain) + isObserver := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator) // Sender needs to be either the admin policy account or an observer if !(isAdmin || isObserver) { diff --git a/x/crosschain/keeper/msg_server_gas_price_voter.go b/x/crosschain/keeper/msg_server_gas_price_voter.go index 63f0d27795..2a8410a7e2 100644 --- a/x/crosschain/keeper/msg_server_gas_price_voter.go +++ b/x/crosschain/keeper/msg_server_gas_price_voter.go @@ -27,7 +27,7 @@ func (k msgServer) GasPriceVoter(goCtx context.Context, msg *types.MsgGasPriceVo if chain == nil { return nil, observertypes.ErrSupportedChains } - if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain); !ok { + if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator); !ok { return nil, observertypes.ErrNotAuthorizedPolicy } if chain == nil { diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx.go b/x/crosschain/keeper/msg_server_vote_inbound_tx.go index dd5af15b4b..0fc1b7bea6 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx.go @@ -77,7 +77,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg tssPub = tss.TssPubkey } // IsAuthorized does various checks against the list of observer mappers - if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, observationChain); !ok { + if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator); !ok { return nil, observerTypes.ErrNotAuthorizedPolicy } diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index e954c25967..d3108c4c95 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -74,7 +74,7 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms return nil, err } //Check is msg.Creator is authorized to vote - if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, observationChain); !ok { + if ok := k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator); !ok { return nil, observerTypes.ErrNotAuthorizedPolicy } diff --git a/x/crosschain/migrations/v2/migrate.go b/x/crosschain/migrations/v2/migrate.go index 0461ba107a..308872726c 100644 --- a/x/crosschain/migrations/v2/migrate.go +++ b/x/crosschain/migrations/v2/migrate.go @@ -14,7 +14,7 @@ import ( // The data moved is the node accounts, permission flags and keygen. func MigrateStore( ctx sdk.Context, - observerKeeper types.ZetaObserverKeeper, + observerKeeper types.ObserverKeeper, crossChainStoreKey storetypes.StoreKey, cdc codec.BinaryCodec, ) error { @@ -63,14 +63,15 @@ func MigrateStore( observerKeeper.SetCrosschainFlags(ctx, crosschainFlags) } - allObservers := observerKeeper.GetAllObserverMappers(ctx) - totalObserverCountCurrentBlock := 0 - for _, observer := range allObservers { - totalObserverCountCurrentBlock += len(observer.ObserverList) + allObservers, found := observerKeeper.GetObserverSet(ctx) + if !found { + return observerTypes.ErrObserverSetNotFound } + totalObserverCountCurrentBlock := allObservers.LenUint() + observerKeeper.SetLastObserverCount(ctx, &observerTypes.LastObserverCount{ // #nosec G701 always positive - Count: uint64(totalObserverCountCurrentBlock), + Count: totalObserverCountCurrentBlock, LastChangeHeight: ctx.BlockHeight(), }) diff --git a/x/crosschain/migrations/v4/migrate.go b/x/crosschain/migrations/v4/migrate.go index 90ba70ddb0..1d94748fcc 100644 --- a/x/crosschain/migrations/v4/migrate.go +++ b/x/crosschain/migrations/v4/migrate.go @@ -17,7 +17,7 @@ import ( // It initializes the aborted zeta amount to 0 func MigrateStore( ctx sdk.Context, - observerKeeper types.ZetaObserverKeeper, + observerKeeper types.ObserverKeeper, crossChainStoreKey storetypes.StoreKey, cdc codec.BinaryCodec, ) error { @@ -57,7 +57,7 @@ func SetZetaAccounting( func MoveNonceToObserverModule( ctx sdk.Context, - observerKeeper types.ZetaObserverKeeper, + observerKeeper types.ObserverKeeper, crossChainStoreKey storetypes.StoreKey, cdc codec.BinaryCodec, ) { @@ -122,7 +122,7 @@ func MoveNonceToObserverModule( } func MoveTssToObserverModule(ctx sdk.Context, - observerKeeper types.ZetaObserverKeeper, + observerKeeper types.ObserverKeeper, crossChainStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) { // Using New Types from observer module as the structure is the same diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index d4747e68c2..efe117117b 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -44,10 +44,8 @@ type BankKeeper interface { MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error } -type ZetaObserverKeeper interface { - SetObserverMapper(ctx sdk.Context, om *observertypes.ObserverMapper) - GetObserverMapper(ctx sdk.Context, chain *common.Chain) (val observertypes.ObserverMapper, found bool) - GetAllObserverMappers(ctx sdk.Context) (mappers []*observertypes.ObserverMapper) +type ObserverKeeper interface { + GetObserverSet(ctx sdk.Context) (val observertypes.ObserverSet, found bool) SetBallot(ctx sdk.Context, ballot *observertypes.Ballot) GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) @@ -64,7 +62,7 @@ type ZetaObserverKeeper interface { SetLastObserverCount(ctx sdk.Context, lbc *observertypes.LastObserverCount) AddVoteToBallot(ctx sdk.Context, ballot observertypes.Ballot, address string, observationType observertypes.VoteType) (observertypes.Ballot, error) CheckIfFinalizingVote(ctx sdk.Context, ballot observertypes.Ballot) (observertypes.Ballot, bool) - IsAuthorized(ctx sdk.Context, address string, chain *common.Chain) bool + IsAuthorized(ctx sdk.Context, address string) bool FindBallot(ctx sdk.Context, index string, chain *common.Chain, observationType observertypes.ObservationType) (ballot observertypes.Ballot, isNew bool, err error) AddBallotToList(ctx sdk.Context, ballot observertypes.Ballot) GetBlockHeader(ctx sdk.Context, hash []byte) (val common.BlockHeader, found bool) diff --git a/x/emissions/keeper/keeper.go b/x/emissions/keeper/keeper.go index 3655c42016..fe9e4429e7 100644 --- a/x/emissions/keeper/keeper.go +++ b/x/emissions/keeper/keeper.go @@ -21,7 +21,7 @@ type ( feeCollectorName string bankKeeper types.BankKeeper stakingKeeper types.StakingKeeper - observerKeeper types.ZetaObserverKeeper + observerKeeper types.ObserverKeeper } ) @@ -33,7 +33,7 @@ func NewKeeper( feeCollectorName string, bankKeeper types.BankKeeper, stakingKeeper types.StakingKeeper, - observerKeeper types.ZetaObserverKeeper, + observerKeeper types.ObserverKeeper, ) *Keeper { // set KeyTable if it has not already been set @@ -70,6 +70,6 @@ func (k Keeper) GetStakingKeeper() types.StakingKeeper { return k.stakingKeeper } -func (k Keeper) GetObserverKeeper() types.ZetaObserverKeeper { +func (k Keeper) GetObserverKeeper() types.ObserverKeeper { return k.observerKeeper } diff --git a/x/emissions/types/expected_keepers.go b/x/emissions/types/expected_keepers.go index 25917b3540..e8b3a4d601 100644 --- a/x/emissions/types/expected_keepers.go +++ b/x/emissions/types/expected_keepers.go @@ -3,8 +3,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/zeta-chain/zetacore/common" - zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) // AccountKeeper defines the expected account keeper used for simulations (noalias) @@ -14,16 +13,14 @@ type AccountKeeper interface { // Methods imported from account should be defined here } -type ZetaObserverKeeper interface { - SetObserverMapper(ctx sdk.Context, om *zetaObserverTypes.ObserverMapper) - GetObserverMapper(ctx sdk.Context, chain *common.Chain) (val zetaObserverTypes.ObserverMapper, found bool) - GetAllObserverMappers(ctx sdk.Context) (mappers []*zetaObserverTypes.ObserverMapper) - SetBallot(ctx sdk.Context, ballot *zetaObserverTypes.Ballot) - GetBallot(ctx sdk.Context, index string) (val zetaObserverTypes.Ballot, found bool) - GetAllBallots(ctx sdk.Context) (voters []*zetaObserverTypes.Ballot) - GetParams(ctx sdk.Context) (params zetaObserverTypes.Params) - GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *zetaObserverTypes.CoreParams, found bool) +type ObserverKeeper interface { GetMaturedBallotList(ctx sdk.Context) []string + GetObserverSet(ctx sdk.Context) (val observertypes.ObserverSet, found bool) + SetBallot(ctx sdk.Context, ballot *observertypes.Ballot) + GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) + GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) + GetParams(ctx sdk.Context) (params observertypes.Params) + GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.CoreParams, found bool) } // BankKeeper defines the expected interface needed to retrieve account balances. diff --git a/x/fungible/types/expected_keepers.go b/x/fungible/types/expected_keepers.go index 46450aab09..43e9607820 100644 --- a/x/fungible/types/expected_keepers.go +++ b/x/fungible/types/expected_keepers.go @@ -13,7 +13,6 @@ import ( "github.com/evmos/ethermint/x/evm/statedb" evmtypes "github.com/evmos/ethermint/x/evm/types" - "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -41,14 +40,13 @@ type BankKeeper interface { } type ObserverKeeper interface { - SetObserverMapper(ctx sdk.Context, om *observertypes.ObserverMapper) - GetObserverMapper(ctx sdk.Context, chain *common.Chain) (val observertypes.ObserverMapper, found bool) - GetAllObserverMappers(ctx sdk.Context) (mappers []*observertypes.ObserverMapper) + GetObserverSet(ctx sdk.Context) (val observertypes.ObserverSet, found bool) SetBallot(ctx sdk.Context, ballot *observertypes.Ballot) GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) GetParams(ctx sdk.Context) (params observertypes.Params) GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.CoreParams, found bool) + GetMaturedBallotList(ctx sdk.Context) []string } type EVMKeeper interface { diff --git a/x/observer/abci.go b/x/observer/abci.go index f253819d6a..f219bb833d 100644 --- a/x/observer/abci.go +++ b/x/observer/abci.go @@ -15,25 +15,28 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { return } - allObservers := k.GetAllObserverMappers(ctx) - totalObserverCountCurrentBlock := 0 - for _, observer := range allObservers { - totalObserverCountCurrentBlock += len(observer.ObserverList) + allObservers, found := k.GetObserverSet(ctx) + if !found { + ctx.Logger().Error("ObserverSet not found at height", ctx.BlockHeight()) + return } + totalObserverCountCurrentBlock := allObservers.LenUint() if totalObserverCountCurrentBlock < 0 { ctx.Logger().Error("TotalObserverCount is negative at height", ctx.BlockHeight()) return } // #nosec G701 always in range - if totalObserverCountCurrentBlock == int(lastBlockObserverCount.Count) { + if totalObserverCountCurrentBlock == lastBlockObserverCount.Count { return } ctx.Logger().Error("LastBlockObserverCount does not match the number of observers found at current height", ctx.BlockHeight()) - for _, observer := range allObservers { - ctx.Logger().Error("Observes for | ", observer.ObserverChain.ChainName, ":", observer.ObserverList) + for _, observer := range allObservers.ObserverList { + ctx.Logger().Error("Observer : ", observer) } + // #nosec G701 always in range + k.DisableInboundOnly(ctx) k.SetKeygen(ctx, types.Keygen{BlockNumber: math.MaxInt64}) // #nosec G701 always positive - k.SetLastObserverCount(ctx, &types.LastObserverCount{Count: uint64(totalObserverCountCurrentBlock), LastChangeHeight: ctx.BlockHeight()}) + k.SetLastObserverCount(ctx, &types.LastObserverCount{Count: totalObserverCountCurrentBlock, LastChangeHeight: ctx.BlockHeight()}) } diff --git a/x/observer/client/cli/query.go b/x/observer/client/cli/query.go index 768d37828e..61aced4edd 100644 --- a/x/observer/client/cli/query.go +++ b/x/observer/client/cli/query.go @@ -27,8 +27,7 @@ func GetQueryCmd(_ string) *cobra.Command { cmd.AddCommand( CmdQueryParams(), CmdBallotByIdentifier(), - CmdObserversByChainAndType(), - CmdAllObserverMappers(), + CmdObserverSet(), CmdGetSupportedChains(), CmdGetCoreParamsForChain(), CmdGetCoreParams(), diff --git a/x/observer/client/cli/query_observers.go b/x/observer/client/cli/query_observers.go index edca162189..e2c25d2fb0 100644 --- a/x/observer/client/cli/query_observers.go +++ b/x/observer/client/cli/query_observers.go @@ -7,10 +7,10 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) -func CmdAllObserverMappers() *cobra.Command { +func CmdObserverSet() *cobra.Command { cmd := &cobra.Command{ - Use: "list-observer", - Short: "Query All Observer Mappers", + Use: "list-observer-set", + Short: "Query observer set", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { @@ -19,8 +19,8 @@ func CmdAllObserverMappers() *cobra.Command { return err } queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryAllObserverMappersRequest{} - res, err := queryClient.AllObserverMappers(cmd.Context(), params) + params := &types.QueryObserverSet{} + res, err := queryClient.ObserverSet(cmd.Context(), params) if err != nil { return err } @@ -30,34 +30,3 @@ func CmdAllObserverMappers() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd } - -func CmdObserversByChainAndType() *cobra.Command { - cmd := &cobra.Command{ - Use: "show-observer [observation-chain]", - Short: "Query ObserversByChainAndType , Use common.chain for querying", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) (err error) { - reqObservationChain := args[0] - - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - queryClient := types.NewQueryClient(clientCtx) - - params := &types.QueryObserversByChainRequest{ - ObservationChain: reqObservationChain, - } - - res, err := queryClient.ObserversByChain(cmd.Context(), params) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - flags.AddQueryFlagsToCmd(cmd) - return cmd -} diff --git a/x/observer/genesis.go b/x/observer/genesis.go index ce13a5e902..ca98575668 100644 --- a/x/observer/genesis.go +++ b/x/observer/genesis.go @@ -10,15 +10,12 @@ import ( // InitGenesis initializes the observer module's state from a provided genesis // state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { - genesisObservers := genState.Observers + observerCount := uint64(0) - for _, mapper := range genesisObservers { - if mapper != nil { - k.SetObserverMapper(ctx, mapper) - observerCount += uint64(len(mapper.ObserverList)) - } + if genState.Observers.Len() > 0 { + k.SetObserverSet(ctx, genState.Observers) + observerCount = uint64(len(genState.Observers.ObserverList)) } - // If core params are defined set them, otherwise set default if len(genState.CoreParamsList.CoreParams) > 0 { k.SetCoreParams(ctx, genState.CoreParamsList) @@ -172,9 +169,16 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { if err == nil { pendingNonces = p } + + os := types.ObserverSet{} + observers, found := k.GetObserverSet(ctx) + if found { + os = observers + } + return &types.GenesisState{ Ballots: k.GetAllBallots(ctx), - Observers: k.GetAllObserverMappers(ctx), + Observers: os, CoreParamsList: coreParams, Params: ¶ms, NodeAccountList: nodeAccounts, diff --git a/x/observer/genesis_test.go b/x/observer/genesis_test.go index 10b2cdbd1b..1cd0422e79 100644 --- a/x/observer/genesis_test.go +++ b/x/observer/genesis_test.go @@ -23,11 +23,7 @@ func TestGenesis(t *testing.T) { sample.Ballot(t, "1"), sample.Ballot(t, "2"), }, - Observers: []*types.ObserverMapper{ - sample.ObserverMapper(t, "0"), - sample.ObserverMapper(t, "1"), - sample.ObserverMapper(t, "2"), - }, + Observers: sample.ObserverSet(3), NodeAccountList: []*types.NodeAccount{ sample.NodeAccount(), sample.NodeAccount(), @@ -35,7 +31,7 @@ func TestGenesis(t *testing.T) { }, CrosschainFlags: types.DefaultCrosschainFlags(), Keygen: sample.Keygen(t), - LastObserverCount: sample.LastObserverCount(1000), + LastObserverCount: sample.LastObserverCount(10), CoreParamsList: sample.CoreParamsList(), TssFundMigrators: []types.TssFundMigratorInfo{sample.TssFundsMigrator(1), sample.TssFundsMigrator(2)}, ChainNonces: []types.ChainNonces{ diff --git a/x/observer/keeper/grpc_query_observer.go b/x/observer/keeper/grpc_query_observer.go index e9c8aacb77..d588aae96e 100644 --- a/x/observer/keeper/grpc_query_observer.go +++ b/x/observer/keeper/grpc_query_observer.go @@ -4,57 +4,40 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -func (k Keeper) ObserversByChain(goCtx context.Context, req *types.QueryObserversByChainRequest) (*types.QueryObserversByChainResponse, error) { +func (k Keeper) ShowObserverCount(goCtx context.Context, req *types.QueryShowObserverCountRequest) (*types.QueryShowObserverCountResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - ctx := sdk.UnwrapSDKContext(goCtx) - // TODO move parsing to client - // https://github.com/zeta-chain/node/issues/867 + ctx := sdk.UnwrapSDKContext(goCtx) - chainName := common.ParseChainName(req.ObservationChain) - chain := k.GetParams(ctx).GetChainFromChainName(chainName) - if chain == nil { - return &types.QueryObserversByChainResponse{}, types.ErrSupportedChains - } - mapper, found := k.GetObserverMapper(ctx, chain) + lb, found := k.GetLastObserverCount(ctx) if !found { - return &types.QueryObserversByChainResponse{}, types.ErrObserverNotPresent - } - return &types.QueryObserversByChainResponse{Observers: mapper.ObserverList}, nil -} - -func (k Keeper) AllObserverMappers(goCtx context.Context, req *types.QueryAllObserverMappersRequest) (*types.QueryAllObserverMappersResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") + return nil, status.Error(codes.NotFound, "last observer count not found") } - ctx := sdk.UnwrapSDKContext(goCtx) - - mappers := k.GetAllObserverMappers(ctx) - return &types.QueryAllObserverMappersResponse{ObserverMappers: mappers}, nil + return &types.QueryShowObserverCountResponse{ + LastObserverCount: &lb, + }, nil } -func (k Keeper) ShowObserverCount(goCtx context.Context, req *types.QueryShowObserverCountRequest) (*types.QueryShowObserverCountResponse, error) { +func (k Keeper) ObserverSet(goCtx context.Context, req *types.QueryObserverSet) (*types.QueryObserverSetResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } ctx := sdk.UnwrapSDKContext(goCtx) - - lb, found := k.GetLastObserverCount(ctx) + observerSet, found := k.GetObserverSet(ctx) if !found { - return nil, status.Error(codes.NotFound, "last observer count not found") + return nil, status.Error(codes.NotFound, "observer set not found") } - - return &types.QueryShowObserverCountResponse{ - LastObserverCount: &lb, + return &types.QueryObserverSetResponse{ + Observers: observerSet.ObserverList, }, nil + } diff --git a/x/observer/keeper/hooks.go b/x/observer/keeper/hooks.go index 2659eeb95c..097f9e42c7 100644 --- a/x/observer/keeper/hooks.go +++ b/x/observer/keeper/hooks.go @@ -77,22 +77,19 @@ func (k Keeper) CleanSlashedValidator(ctx sdk.Context, valAddress sdk.ValAddress if err != nil { return err } - mappers := k.GetAllObserverMappersForAddress(ctx, accAddress.String()) - if len(mappers) == 0 { + observerSet, found := k.GetObserverSet(ctx) + if !found || observerSet.Len() == 0 { return nil } tokensToBurn := sdk.NewDecFromInt(validator.Tokens).Mul(fraction) resultingTokens := validator.Tokens.Sub(tokensToBurn.Ceil().TruncateInt()) - for _, mapper := range mappers { - obsParams := k.GetParams(ctx).GetParamsForChain(mapper.ObserverChain) - if !obsParams.IsSupported { - return types.ErrSupportedChains - } - if sdk.NewDecFromInt(resultingTokens).LT(obsParams.MinObserverDelegation) { - mapper.ObserverList = CleanAddressList(mapper.ObserverList, accAddress.String()) - k.SetObserverMapper(ctx, mapper) - } + mindelegation, found := types.GetMinObserverDelegation() + if !found { + return types.ErrMinDelegationNotFound + } + if resultingTokens.LT(mindelegation) { + k.RemoveObserverFromSet(ctx, accAddress.String()) } return nil } @@ -103,62 +100,39 @@ func (k Keeper) CleanObservers(ctx sdk.Context, valAddress sdk.ValAddress) error if err != nil { return err } - mappers := k.GetAllObserverMappersForAddress(ctx, accAddress.String()) - for _, mapper := range mappers { - mapper.ObserverList = CleanAddressList(mapper.ObserverList, accAddress.String()) - k.SetObserverMapper(ctx, mapper) - } + k.RemoveObserverFromSet(ctx, accAddress.String()) return nil } -// CleanObservers cleans a observer Mapper checking delegation amount +// CheckAndCleanObserver checks if the observer self-delegation is sufficient, +// if not it removes the observer from the set func (k Keeper) CheckAndCleanObserver(ctx sdk.Context, valAddress sdk.ValAddress) error { accAddress, err := types.GetAccAddressFromOperatorAddress(valAddress.String()) if err != nil { return err } - k.CleanMapper(ctx, accAddress) + err = k.CheckObserverSelfDelegation(ctx, accAddress.String()) + if err != nil { + return err + } return nil } -// CleanObservers cleans a observer Mapper checking delegation amount for a speficific delagator. It is used when delgator is the validator . -// That is when when the validator is trying to remove self delgation +// CheckAndCleanObserverDelegator first checks if the delegation is self delegation, +// if it is, then it checks if the total delegation is sufficient after the delegation is removed, +// if not it removes the observer from the set func (k Keeper) CheckAndCleanObserverDelegator(ctx sdk.Context, valAddress sdk.ValAddress, delAddress sdk.AccAddress) error { accAddress, err := types.GetAccAddressFromOperatorAddress(valAddress.String()) if err != nil { return err } + // Check if this is a self delegation, if it's not then return, we only check self-delegation for cleaning observer set if !(accAddress.String() == delAddress.String()) { return nil } - k.CleanMapper(ctx, accAddress) - return nil -} - -func CleanAddressList(addresslist []string, address string) []string { - index := -1 - for i, addr := range addresslist { - if addr == address { - index = i - } - } - if index != -1 { - addresslist = RemoveIndex(addresslist, index) - } - return addresslist -} - -func RemoveIndex(s []string, index int) []string { - return append(s[:index], s[index+1:]...) -} - -func (k Keeper) CleanMapper(ctx sdk.Context, accAddress sdk.AccAddress) { - mappers := k.GetAllObserverMappersForAddress(ctx, accAddress.String()) - for _, mapper := range mappers { - err := k.CheckObserverDelegation(ctx, accAddress.String(), mapper.ObserverChain) - if err != nil { - mapper.ObserverList = CleanAddressList(mapper.ObserverList, accAddress.String()) - k.SetObserverMapper(ctx, mapper) - } + err = k.CheckObserverSelfDelegation(ctx, accAddress.String()) + if err != nil { + return err } + return nil } diff --git a/x/observer/keeper/last_observer_count.go b/x/observer/keeper/last_observer_count.go new file mode 100644 index 0000000000..7ae211acd1 --- /dev/null +++ b/x/observer/keeper/last_observer_count.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func (k Keeper) SetLastObserverCount(ctx sdk.Context, lbc *types.LastObserverCount) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.LastBlockObserverCountKey)) + b := k.cdc.MustMarshal(lbc) + store.Set([]byte{0}, b) +} + +func (k Keeper) GetLastObserverCount(ctx sdk.Context) (val types.LastObserverCount, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.LastBlockObserverCountKey)) + + b := store.Get([]byte{0}) + if b == nil { + return val, false + } + + k.cdc.MustUnmarshal(b, &val) + return val, true +} diff --git a/x/observer/keeper/migrator.go b/x/observer/keeper/migrator.go index 190de610cd..bb40ea8151 100644 --- a/x/observer/keeper/migrator.go +++ b/x/observer/keeper/migrator.go @@ -5,6 +5,7 @@ import ( v2 "github.com/zeta-chain/zetacore/x/observer/migrations/v2" v3 "github.com/zeta-chain/zetacore/x/observer/migrations/v3" v4 "github.com/zeta-chain/zetacore/x/observer/migrations/v4" + v5 "github.com/zeta-chain/zetacore/x/observer/migrations/v5" ) // Migrator is a struct for handling in-place store migrations. @@ -32,3 +33,7 @@ func (m Migrator) Migrate2to3(ctx sdk.Context) error { func (m Migrator) Migrate3to4(ctx sdk.Context) error { return v4.MigrateStore(ctx, m.observerKeeper.storeKey, m.observerKeeper.cdc) } + +func (m Migrator) Migrate4to5(ctx sdk.Context) error { + return v5.MigrateStore(ctx, m.observerKeeper.storeKey, m.observerKeeper.cdc) +} diff --git a/x/observer/keeper/msg_server_add_blame_vote.go b/x/observer/keeper/msg_server_add_blame_vote.go index 1330cc4815..80fb5d66aa 100644 --- a/x/observer/keeper/msg_server_add_blame_vote.go +++ b/x/observer/keeper/msg_server_add_blame_vote.go @@ -19,7 +19,7 @@ func (k msgServer) AddBlameVote(goCtx context.Context, vote *types.MsgAddBlameVo return nil, sdkerrors.Wrap(crosschainTypes.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Blame vote", vote.ChainId)) } // IsAuthorized does various checks against the list of observer mappers - if ok := k.IsAuthorized(ctx, vote.Creator, observationChain); !ok { + if ok := k.IsAuthorized(ctx, vote.Creator); !ok { return nil, types.ErrNotAuthorizedPolicy } diff --git a/x/observer/keeper/msg_server_add_block_header.go b/x/observer/keeper/msg_server_add_block_header.go index ef93cb42cb..fb1ae72742 100644 --- a/x/observer/keeper/msg_server_add_block_header.go +++ b/x/observer/keeper/msg_server_add_block_header.go @@ -16,7 +16,7 @@ func (k msgServer) AddBlockHeader(goCtx context.Context, msg *types.MsgAddBlockH // check authorization for this chain chain := common.GetChainFromChainID(msg.ChainId) - if ok := k.IsAuthorized(ctx, msg.Creator, chain); !ok { + if ok := k.IsAuthorized(ctx, msg.Creator); !ok { return nil, types.ErrNotAuthorizedPolicy } diff --git a/x/observer/keeper/msg_server_add_block_header_test.go b/x/observer/keeper/msg_server_add_block_header_test.go index eb2c93970f..04e9e9c560 100644 --- a/x/observer/keeper/msg_server_add_block_header_test.go +++ b/x/observer/keeper/msg_server_add_block_header_test.go @@ -26,7 +26,6 @@ func TestMsgServer_AddBlockHeader(t *testing.T) { header3RLP, err := rlp.EncodeToBytes(header3) assert.NoError(t, err) - observerChain := common.GoerliLocalnetChain() r := rand.New(rand.NewSource(9)) validator := sample.Validator(t, r) observerAddress, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) @@ -137,9 +136,8 @@ func TestMsgServer_AddBlockHeader(t *testing.T) { t.Run(tc.name, func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) srv := keeper.NewMsgServerImpl(*k) - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: &observerChain, - ObserverList: []string{observerAddress.String()}, + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{observerAddress.String()}, }) k.GetStakingKeeper().SetValidator(ctx, tc.validator) k.SetCrosschainFlags(ctx, types.CrosschainFlags{ diff --git a/x/observer/keeper/msg_server_add_observer.go b/x/observer/keeper/msg_server_add_observer.go index fa431e145a..5bf64e5d95 100644 --- a/x/observer/keeper/msg_server_add_observer.go +++ b/x/observer/keeper/msg_server_add_observer.go @@ -41,15 +41,9 @@ func (k msgServer) AddObserver(goCtx context.Context, msg *types.MsgAddObserver) k.SetKeygen(ctx, types.Keygen{BlockNumber: math.MaxInt64}) return &types.MsgAddObserverResponse{}, nil } - - observerMappers := k.GetAllObserverMappers(ctx) - totalObserverCountCurrentBlock := uint64(0) - for _, mapper := range observerMappers { - mapper.ObserverList = append(mapper.ObserverList, msg.ObserverAddress) - totalObserverCountCurrentBlock += uint64(len(mapper.ObserverList)) - k.SetObserverMapper(ctx, mapper) - } - k.SetLastObserverCount(ctx, &types.LastObserverCount{Count: totalObserverCountCurrentBlock}) - EmitEventAddObserver(ctx, totalObserverCountCurrentBlock, msg.ObserverAddress, granteeAddress.String(), msg.ZetaclientGranteePubkey) + k.AddObserverToSet(ctx, msg.ObserverAddress) + observerSet, _ := k.GetObserverSet(ctx) + k.SetLastObserverCount(ctx, &types.LastObserverCount{Count: observerSet.LenUint()}) + EmitEventAddObserver(ctx, observerSet.LenUint(), msg.ObserverAddress, granteeAddress.String(), msg.ZetaclientGranteePubkey) return &types.MsgAddObserverResponse{}, nil } diff --git a/x/observer/keeper/msg_server_update_observer.go b/x/observer/keeper/msg_server_update_observer.go index fb3ece273e..7a04c35ac9 100644 --- a/x/observer/keeper/msg_server_update_observer.go +++ b/x/observer/keeper/msg_server_update_observer.go @@ -21,12 +21,9 @@ func (k msgServer) UpdateObserver(goCtx context.Context, msg *types.MsgUpdateObs if !ok { return nil, errorsmod.Wrap(types.ErrUpdateObserver, fmt.Sprintf("Unable to update observer with update reason : %s", msg.UpdateReason)) } - - chains := k.GetParams(ctx).GetSupportedChains() - for _, chain := range chains { - if !k.IsObserverPresentInMappers(ctx, msg.OldObserverAddress, chain) { - return nil, errorsmod.Wrap(types.ErrNotAuthorized, fmt.Sprintf("Observer address is not authorized for chain : %s", chain.String())) - } + // We do not use IsAuthorized here because we want to allow tombstoned observers to be updated + if !k.IsAddressPartOfObserverSet(ctx, msg.OldObserverAddress) { + return nil, errorsmod.Wrap(types.ErrNotAuthorized, fmt.Sprintf("Observer address is not authorized : %s", msg.OldObserverAddress)) } err = k.IsValidator(ctx, msg.NewObserverAddress) @@ -35,7 +32,10 @@ func (k msgServer) UpdateObserver(goCtx context.Context, msg *types.MsgUpdateObs } // Update all mappers so that ballots can be created for the new observer address - k.UpdateObserverAddress(ctx, msg.OldObserverAddress, msg.NewObserverAddress) + err = k.UpdateObserverAddress(ctx, msg.OldObserverAddress, msg.NewObserverAddress) + if err != nil { + return nil, errorsmod.Wrap(types.ErrUpdateObserver, err.Error()) + } // Update the node account with the new operator address nodeAccount, found := k.GetNodeAccount(ctx, msg.OldObserverAddress) @@ -50,11 +50,11 @@ func (k msgServer) UpdateObserver(goCtx context.Context, msg *types.MsgUpdateObs k.SetNodeAccount(ctx, newNodeAccount) // Check LastBlockObserver count just to be safe - observerMappers := k.GetAllObserverMappers(ctx) - totalObserverCountCurrentBlock := uint64(0) - for _, mapper := range observerMappers { - totalObserverCountCurrentBlock += uint64(len(mapper.ObserverList)) + observerSet, found := k.GetObserverSet(ctx) + if !found { + return nil, errorsmod.Wrap(types.ErrObserverSetNotFound, fmt.Sprintf("Observer set not found")) } + totalObserverCountCurrentBlock := observerSet.LenUint() lastBlockCount, found := k.GetLastObserverCount(ctx) if !found { return nil, errorsmod.Wrap(types.ErrLastObserverCountNotFound, fmt.Sprintf("Observer count not found")) @@ -85,14 +85,6 @@ func (k Keeper) CheckUpdateReason(ctx sdk.Context, msg *types.MsgUpdateObserver) return false, nil } -func (k Keeper) UpdateObserverAddress(ctx sdk.Context, oldObserverAddress, newObserverAddress string) { - observerMappers := k.GetAllObserverMappers(ctx) - for _, om := range observerMappers { - UpdateObserverList(om.ObserverList, oldObserverAddress, newObserverAddress) - k.SetObserverMapper(ctx, om) - } -} - func UpdateObserverList(list []string, oldObserverAddresss, newObserverAddress string) { for i, observer := range list { if observer == oldObserverAddresss { diff --git a/x/observer/keeper/msg_server_update_observer_test.go b/x/observer/keeper/msg_server_update_observer_test.go index 44048f4200..181c360bb1 100644 --- a/x/observer/keeper/msg_server_update_observer_test.go +++ b/x/observer/keeper/msg_server_update_observer_test.go @@ -38,9 +38,6 @@ func TestMsgServer_UpdateObserver(t *testing.T) { Tombstoned: true, MissedBlocksCounter: 1, }) - - chains := k.GetParams(ctx).GetSupportedChains() - accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) @@ -48,13 +45,12 @@ func TestMsgServer_UpdateObserver(t *testing.T) { assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count = 1 + k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -96,8 +92,6 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() - accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) @@ -105,13 +99,10 @@ func TestMsgServer_UpdateObserver(t *testing.T) { assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count = 1 k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -152,17 +143,15 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 + k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -205,17 +194,14 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 + k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -258,17 +244,13 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 k.SetLastObserverCount(ctx, &types.LastObserverCount{ Count: count, @@ -308,18 +290,13 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } - + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -361,18 +338,13 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } - + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), }) @@ -419,17 +391,13 @@ func TestMsgServer_UpdateObserver(t *testing.T) { MissedBlocksCounter: 1, }) - chains := k.GetParams(ctx).GetSupportedChains() accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) count := uint64(0) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - count += 1 - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + count += 1 k.SetNodeAccount(ctx, types.NodeAccount{ Operator: accAddressOfValidator.String(), @@ -463,92 +431,3 @@ func TestUpdateObserverList(t *testing.T) { assert.Equal(t, newObserverAddress, list[3]) }) } - -func TestKeeper_UpdateObserverAddress(t *testing.T) { - t.Run("update observer address", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - oldObserverAddress := sample.AccAddress() - newObserverAddress := sample.AccAddress() - chains := k.GetParams(ctx).GetSupportedChains() - observerList := CreateRandomObserverList(10, oldObserverAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: observerList, - }) - } - k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) - observerMappers := k.GetAllObserverMappers(ctx) - for _, om := range observerMappers { - assert.Equal(t, len(observerList), len(om.ObserverList)) - assert.Equal(t, newObserverAddress, om.ObserverList[len(om.ObserverList)-1]) - } - }) - t.Run("update observer address long observerList", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - oldObserverAddress := sample.AccAddress() - newObserverAddress := sample.AccAddress() - chains := k.GetParams(ctx).GetSupportedChains() - observerList := CreateRandomObserverList(1000, oldObserverAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: observerList, - }) - } - k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) - observerMappers := k.GetAllObserverMappers(ctx) - for _, om := range observerMappers { - assert.Equal(t, len(observerList), len(om.ObserverList)) - assert.Equal(t, newObserverAddress, om.ObserverList[len(om.ObserverList)-1]) - } - }) - t.Run("update observer address super long observerList", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - oldObserverAddress := sample.AccAddress() - newObserverAddress := sample.AccAddress() - chains := k.GetParams(ctx).GetSupportedChains() - observerList := CreateRandomObserverList(100000, oldObserverAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: observerList, - }) - } - k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) - observerMappers := k.GetAllObserverMappers(ctx) - for _, om := range observerMappers { - assert.Equal(t, len(observerList), len(om.ObserverList)) - assert.Equal(t, newObserverAddress, om.ObserverList[len(om.ObserverList)-1]) - } - }) - t.Run("update observer address short observerList", func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - oldObserverAddress := sample.AccAddress() - newObserverAddress := sample.AccAddress() - chains := k.GetParams(ctx).GetSupportedChains() - observerList := CreateRandomObserverList(1, oldObserverAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: observerList, - }) - } - k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) - observerMappers := k.GetAllObserverMappers(ctx) - for _, om := range observerMappers { - assert.Equal(t, len(observerList), len(om.ObserverList)) - assert.Equal(t, newObserverAddress, om.ObserverList[len(om.ObserverList)-1]) - } - }) -} - -func CreateRandomObserverList(maxLen int, observerAddress string) []string { - r := rand.New(rand.NewSource(9)) - list := make([]string, r.Intn(maxLen)+1) - for i := range list { - list[i] = sample.AccAddress() - } - list = append(list, observerAddress) - return list -} diff --git a/x/observer/keeper/observer_mapper.go b/x/observer/keeper/observer_mapper.go deleted file mode 100644 index 121c7ec000..0000000000 --- a/x/observer/keeper/observer_mapper.go +++ /dev/null @@ -1,120 +0,0 @@ -package keeper - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func GetObserverMapperIndex(chain *common.Chain) string { - return fmt.Sprintf("%d", chain.ChainId) -} - -func (k Keeper) SetLastObserverCount(ctx sdk.Context, lbc *types.LastObserverCount) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.LastBlockObserverCountKey)) - b := k.cdc.MustMarshal(lbc) - store.Set([]byte{0}, b) -} - -func (k Keeper) GetLastObserverCount(ctx sdk.Context) (val types.LastObserverCount, found bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.LastBlockObserverCountKey)) - - b := store.Get([]byte{0}) - if b == nil { - return val, false - } - - k.cdc.MustUnmarshal(b, &val) - return val, true -} - -func (k Keeper) SetObserverMapper(ctx sdk.Context, om *types.ObserverMapper) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverMapperKey)) - om.Index = GetObserverMapperIndex(om.ObserverChain) - b := k.cdc.MustMarshal(om) - store.Set([]byte(om.Index), b) -} - -func (k Keeper) GetObserverMapper(ctx sdk.Context, chain *common.Chain) (val types.ObserverMapper, found bool) { - index := GetObserverMapperIndex(chain) - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverMapperKey)) - b := store.Get(types.KeyPrefix(index)) - if b == nil { - return val, false - } - k.cdc.MustUnmarshal(b, &val) - return val, true -} - -func (k Keeper) GetAllObserverMappers(ctx sdk.Context) (mappers []*types.ObserverMapper) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverMapperKey)) - iterator := sdk.KVStorePrefixIterator(store, []byte{}) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - var val types.ObserverMapper - k.cdc.MustUnmarshal(iterator.Value(), &val) - mappers = append(mappers, &val) - } - return -} -func (k Keeper) GetAllObserverMappersForAddress(ctx sdk.Context, address string) (mappers []*types.ObserverMapper) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverMapperKey)) - iterator := sdk.KVStorePrefixIterator(store, []byte{}) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - var val types.ObserverMapper - k.cdc.MustUnmarshal(iterator.Value(), &val) - addToList := false - for _, addr := range val.ObserverList { - if addr == address { - addToList = true - } - } - if addToList { - mappers = append(mappers, &val) - } - } - return -} - -// Utils - -func (k Keeper) GetAllObserverAddresses(ctx sdk.Context) []string { - var val []string - mappers := k.GetAllObserverMappers(ctx) - for _, mapper := range mappers { - val = append(val, mapper.ObserverList...) - } - allKeys := make(map[string]bool) - var dedupedList []string - for _, item := range val { - if _, value := allKeys[item]; !value { - allKeys[item] = true - dedupedList = append(dedupedList, item) - } - } - return dedupedList -} - -func (k Keeper) AddObserverToMapper(ctx sdk.Context, chain *common.Chain, address string) { - mapper, found := k.GetObserverMapper(ctx, chain) - if !found { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - Index: "", - ObserverChain: chain, - ObserverList: []string{address}, - }) - return - } - // Return if duplicate - for _, addr := range mapper.ObserverList { - if addr == address { - return - } - } - mapper.ObserverList = append(mapper.ObserverList, address) - k.SetObserverMapper(ctx, &mapper) -} diff --git a/x/observer/keeper/observer_mapper_test.go b/x/observer/keeper/observer_mapper_test.go deleted file mode 100644 index 12e572e81a..0000000000 --- a/x/observer/keeper/observer_mapper_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package keeper_test - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/assert" - "github.com/zeta-chain/zetacore/common" - keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func TestKeeper_GetObserver(t *testing.T) { - - tt := []struct { - name string - mapper []*types.ObserverMapper - assertChain *common.Chain - assertObsListLen int - isFound bool - }{ - { - name: "4 eth Observers", - mapper: types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }), - assertChain: &common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }, - assertObsListLen: 4, - isFound: true, - }, - { - name: "Filter out from multiple mappers", - mapper: append(append(types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - })...), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_bsc_mainnet, - ChainId: 2, - })...), - assertChain: &common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }, - assertObsListLen: 4, - isFound: true, - }, - { - name: "No Observers of expected Observation Chain", - mapper: append(append(types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_btc_mainnet, - ChainId: 3, - }), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_polygon_mainnet, - ChainId: 4, - })...), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_bsc_mainnet, - ChainId: 5, - })...), - assertChain: &common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }, - assertObsListLen: 0, - isFound: false, - }, - { - name: "No Observers of expected Observation Type", - mapper: append(append(types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_btc_mainnet, - ChainId: 3, - }), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_polygon_mainnet, - ChainId: 4, - })...), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_bsc_mainnet, - ChainId: 5, - })...), - assertChain: &common.Chain{ - ChainName: common.ChainName_eth_mainnet, - ChainId: 1, - }, - assertObsListLen: 0, - isFound: false, - }, - } - - for _, test := range tt { - test := test - t.Run(test.name, func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - for _, mapper := range test.mapper { - k.SetObserverMapper(ctx, mapper) - } - mapper, found := k.GetObserverMapper(ctx, test.assertChain) - assert.Equal(t, test.isFound, found) - if test.isFound { - assert.Equal(t, test.assertObsListLen, len(mapper.ObserverList)) - } - - }) - } -} - -func TestKeeper_ObserversByChainAndType(t *testing.T) { - tt := []struct { - name string - mapper []*types.ObserverMapper - assertChain common.ChainName - assertObsListLen int - isFound bool - }{ - { - name: "4 ETH InBoundTx Observers", - mapper: types.CreateObserverMapperList(1, common.GoerliChain()), - assertChain: common.ChainName_goerli_localnet, - isFound: true, - }, - { - name: "4 BTC InBoundTx Observers", - mapper: types.CreateObserverMapperList(1, common.BtcRegtestChain()), - assertChain: common.ChainName_btc_regtest, - isFound: true, - }, - { - name: "Filter out from multiple mappers", - mapper: append(append(types.CreateObserverMapperList(1, common.GoerliChain()), - types.CreateObserverMapperList(1, common.ZetaPrivnetChain())...)), - assertChain: common.ChainName_goerli_localnet, - isFound: true, - }, - { - name: "No Observers of expected Observation Chain", - mapper: append(append(types.CreateObserverMapperList(1, common.GoerliChain()), - types.CreateObserverMapperList(1, common.ZetaPrivnetChain())...)), - assertChain: common.ChainName_btc_regtest, - isFound: false, - }, - } - - for _, test := range tt { - test := test - t.Run(test.name, func(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - - for _, mapper := range test.mapper { - k.SetObserverMapper(ctx, mapper) - } - goCtx := sdk.WrapSDKContext(ctx) - msg := &types.QueryObserversByChainRequest{ - ObservationChain: test.assertChain.String(), - } - - mapper, _ := k.ObserversByChain(goCtx, msg) - if test.isFound { - assert.NotEqual(t, "", mapper) - } - - }) - } -} - -func TestKeeper_GetAllObserverAddresses(t *testing.T) { - mappers := append(append(types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_btc_mainnet, - ChainId: 3, - }), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_polygon_mainnet, - ChainId: 4, - })...), - types.CreateObserverMapperList(1, common.Chain{ - ChainName: common.ChainName_bsc_mainnet, - ChainId: 5, - })...) - k, ctx := keepertest.ObserverKeeper(t) - for _, mapper := range mappers { - k.SetObserverMapper(ctx, mapper) - } - addresses := k.GetAllObserverAddresses(ctx) - assert.Equal(t, 4, len(addresses)) -} diff --git a/x/observer/keeper/observer_set.go b/x/observer/keeper/observer_set.go new file mode 100644 index 0000000000..b8c45bfd30 --- /dev/null +++ b/x/observer/keeper/observer_set.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func (k Keeper) SetObserverSet(ctx sdk.Context, om types.ObserverSet) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverSetKey)) + b := k.cdc.MustMarshal(&om) + store.Set([]byte{0}, b) +} + +func (k Keeper) GetObserverSet(ctx sdk.Context) (val types.ObserverSet, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ObserverSetKey)) + b := store.Get([]byte{0}) + if b == nil { + return val, false + } + k.cdc.MustUnmarshal(b, &val) + return val, true +} + +func (k Keeper) IsAddressPartOfObserverSet(ctx sdk.Context, address string) bool { + observerSet, found := k.GetObserverSet(ctx) + if !found { + return false + } + for _, addr := range observerSet.ObserverList { + if addr == address { + return true + } + } + return false + +} + +func (k Keeper) AddObserverToSet(ctx sdk.Context, address string) { + observerSet, found := k.GetObserverSet(ctx) + if !found { + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{address}, + }) + return + } + for _, addr := range observerSet.ObserverList { + if addr == address { + return + } + } + observerSet.ObserverList = append(observerSet.ObserverList, address) + k.SetObserverSet(ctx, observerSet) +} + +func (k Keeper) RemoveObserverFromSet(ctx sdk.Context, address string) { + observerSet, found := k.GetObserverSet(ctx) + if !found { + return + } + for i, addr := range observerSet.ObserverList { + if addr == address { + observerSet.ObserverList = append(observerSet.ObserverList[:i], observerSet.ObserverList[i+1:]...) + k.SetObserverSet(ctx, observerSet) + return + } + } +} + +func (k Keeper) UpdateObserverAddress(ctx sdk.Context, oldObserverAddress, newObserverAddress string) error { + observerSet, found := k.GetObserverSet(ctx) + if !found { + return types.ErrObserverSetNotFound + } + for i, addr := range observerSet.ObserverList { + if addr == oldObserverAddress { + observerSet.ObserverList[i] = newObserverAddress + k.SetObserverSet(ctx, observerSet) + return nil + } + } + return types.ErrUpdateObserver +} diff --git a/x/observer/keeper/observer_set_test.go b/x/observer/keeper/observer_set_test.go new file mode 100644 index 0000000000..f1ca38fc8c --- /dev/null +++ b/x/observer/keeper/observer_set_test.go @@ -0,0 +1,100 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" +) + +func TestKeeper_GetObserverSet(t *testing.T) { + t.Run("get observer set", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + os := sample.ObserverSet(10) + k.SetObserverSet(ctx, os) + tfm, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Equal(t, os, tfm) + }) +} + +func TestKeeper_IsAddressPartOfObserverSet(t *testing.T) { + t.Run("address is part of observer set", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + os := sample.ObserverSet(10) + k.SetObserverSet(ctx, os) + assert.True(t, k.IsAddressPartOfObserverSet(ctx, os.ObserverList[0])) + assert.False(t, k.IsAddressPartOfObserverSet(ctx, sample.AccAddress())) + }) +} + +func TestKeeper_AddObserverToSet(t *testing.T) { + t.Run("add observer to set", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + os := sample.ObserverSet(10) + k.SetObserverSet(ctx, os) + newObserver := sample.AccAddress() + k.AddObserverToSet(ctx, newObserver) + assert.True(t, k.IsAddressPartOfObserverSet(ctx, newObserver)) + assert.False(t, k.IsAddressPartOfObserverSet(ctx, sample.AccAddress())) + osNew, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Len(t, osNew.ObserverList, len(os.ObserverList)+1) + }) +} + +func TestKeeper_RemoveObserverFromSet(t *testing.T) { + t.Run("remove observer from set", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + os := sample.ObserverSet(10) + k.SetObserverSet(ctx, os) + k.RemoveObserverFromSet(ctx, os.ObserverList[0]) + assert.False(t, k.IsAddressPartOfObserverSet(ctx, os.ObserverList[0])) + osNew, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Len(t, osNew.ObserverList, len(os.ObserverList)-1) + }) +} + +func TestKeeper_UpdateObserverAddress(t *testing.T) { + t.Run("update observer address", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + oldObserverAddress := sample.AccAddress() + newObserverAddress := sample.AccAddress() + observerSet := sample.ObserverSet(10) + observerSet.ObserverList = append(observerSet.ObserverList, oldObserverAddress) + k.SetObserverSet(ctx, observerSet) + err := k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) + assert.NoError(t, err) + observerSet, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Equal(t, newObserverAddress, observerSet.ObserverList[len(observerSet.ObserverList)-1]) + }) + t.Run("update observer address long observerList", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + oldObserverAddress := sample.AccAddress() + newObserverAddress := sample.AccAddress() + observerSet := sample.ObserverSet(10000) + observerSet.ObserverList = append(observerSet.ObserverList, oldObserverAddress) + k.SetObserverSet(ctx, observerSet) + err := k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) + assert.NoError(t, err) + observerMappers, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Equal(t, newObserverAddress, observerMappers.ObserverList[len(observerMappers.ObserverList)-1]) + }) + t.Run("update observer address short observerList", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + oldObserverAddress := sample.AccAddress() + newObserverAddress := sample.AccAddress() + observerSet := sample.ObserverSet(1) + observerSet.ObserverList = append(observerSet.ObserverList, oldObserverAddress) + k.SetObserverSet(ctx, observerSet) + err := k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) + assert.NoError(t, err) + observerMappers, found := k.GetObserverSet(ctx) + assert.True(t, found) + assert.Equal(t, newObserverAddress, observerMappers.ObserverList[len(observerMappers.ObserverList)-1]) + }) +} diff --git a/x/observer/keeper/utils.go b/x/observer/keeper/utils.go index a5a22bc36d..fecdbd5f73 100644 --- a/x/observer/keeper/utils.go +++ b/x/observer/keeper/utils.go @@ -31,10 +31,11 @@ func (k Keeper) CheckIfFinalizingVote(ctx sdk.Context, ballot types.Ballot) (typ return ballot, true } -// IsAuthorized checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type -// It also checks if the signer is a validator and if they are not tombstoned -func (k Keeper) IsAuthorized(ctx sdk.Context, address string, chain *common.Chain) bool { - isPresentInMapper := k.IsObserverPresentInMappers(ctx, address, chain) +// IsAuthorized checks whether a signer is authorized to sign +// This function checks if the signer is present in the observer set +// and also checks if the signer is not tombstoned +func (k Keeper) IsAuthorized(ctx sdk.Context, address string) bool { + isPresentInMapper := k.IsAddressPartOfObserverSet(ctx, address) if !isPresentInMapper { return false } @@ -45,24 +46,11 @@ func (k Keeper) IsAuthorized(ctx sdk.Context, address string, chain *common.Chai return true } -func (k Keeper) IsObserverPresentInMappers(ctx sdk.Context, address string, chain *common.Chain) bool { - observerMapper, found := k.GetObserverMapper(ctx, chain) - if !found { - return false - } - for _, obs := range observerMapper.ObserverList { - if obs == address { - return true - } - } - return false -} - func (k Keeper) FindBallot(ctx sdk.Context, index string, chain *common.Chain, observationType types.ObservationType) (ballot types.Ballot, isNew bool, err error) { isNew = false ballot, found := k.GetBallot(ctx, index) if !found { - observerMapper, _ := k.GetObserverMapper(ctx, chain) + observerSet, _ := k.GetObserverSet(ctx) obsParams := k.GetParams(ctx).GetParamsForChain(chain) if !obsParams.IsSupported { err = errors.Wrap(types.ErrSupportedChains, fmt.Sprintf("Thresholds not set for Chain %s and Observation %s", chain.String(), observationType)) @@ -71,8 +59,8 @@ func (k Keeper) FindBallot(ctx sdk.Context, index string, chain *common.Chain, o ballot = types.Ballot{ Index: "", BallotIdentifier: index, - VoterList: observerMapper.ObserverList, - Votes: types.CreateVotes(len(observerMapper.ObserverList)), + VoterList: observerSet.ObserverList, + Votes: types.CreateVotes(len(observerSet.ObserverList)), ObservationType: observationType, BallotThreshold: obsParams.BallotThreshold, BallotStatus: types.BallotStatus_BallotInProgress, @@ -117,7 +105,7 @@ func (k Keeper) IsOperatorTombstoned(ctx sdk.Context, creator string) (bool, err return k.slashingKeeper.IsTombstoned(ctx, consAddress), nil } -func (k Keeper) CheckObserverDelegation(ctx sdk.Context, accAddress string, chain *common.Chain) error { +func (k Keeper) CheckObserverSelfDelegation(ctx sdk.Context, accAddress string) error { selfdelAddr, err := sdk.AccAddressFromBech32(accAddress) if err != nil { return err @@ -135,14 +123,13 @@ func (k Keeper) CheckObserverDelegation(ctx sdk.Context, accAddress string, chai if !found { return types.ErrSelfDelegation } - obsParams := k.GetParams(ctx).GetParamsForChain(chain) - if !obsParams.IsSupported { - return errors.Wrap(types.ErrSupportedChains, fmt.Sprintf("Chain not suported %s ", chain.String())) + minDelegation, err := types.GetMinObserverDelegationDec() + if err != nil { + return err } - tokens := validator.TokensFromShares(delegation.Shares) - if tokens.LT(obsParams.MinObserverDelegation) { - return types.ErrCheckObserverDelegation + if tokens.LT(minDelegation) { + k.RemoveObserverFromSet(ctx, accAddress) } return nil } diff --git a/x/observer/keeper/utils_test.go b/x/observer/keeper/utils_test.go index b5dc13f5ab..a958fb5dc3 100644 --- a/x/observer/keeper/utils_test.go +++ b/x/observer/keeper/utils_test.go @@ -15,8 +15,6 @@ import ( func TestKeeper_IsAuthorized(t *testing.T) { t.Run("authorized observer", func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) - chains := k.GetParams(ctx).GetSupportedChains() - r := rand.New(rand.NewSource(9)) // Set validator in the store @@ -33,19 +31,15 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - } - for _, chain := range chains { - assert.True(t, k.IsAuthorized(ctx, accAddressOfValidator.String(), chain)) - } + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + assert.True(t, k.IsAuthorized(ctx, accAddressOfValidator.String())) + }) t.Run("not authorized for tombstoned observer", func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) - chains := k.GetParams(ctx).GetSupportedChains() r := rand.New(rand.NewSource(9)) @@ -63,19 +57,15 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - } - for _, chain := range chains { - assert.False(t, k.IsAuthorized(ctx, accAddressOfValidator.String(), chain)) - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + assert.False(t, k.IsAuthorized(ctx, accAddressOfValidator.String())) + }) t.Run("not authorized for non-validator observer", func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) - chains := k.GetParams(ctx).GetSupportedChains() r := rand.New(rand.NewSource(9)) @@ -93,14 +83,11 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) - for _, chain := range chains { - k.SetObserverMapper(ctx, &types.ObserverMapper{ - ObserverChain: chain, - ObserverList: []string{accAddressOfValidator.String()}, - }) - } - for _, chain := range chains { - assert.False(t, k.IsAuthorized(ctx, accAddressOfValidator.String(), chain)) - } + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + assert.False(t, k.IsAuthorized(ctx, accAddressOfValidator.String())) + }) } diff --git a/x/observer/migrations/v5/migrate.go b/x/observer/migrations/v5/migrate.go new file mode 100644 index 0000000000..a5666ff43b --- /dev/null +++ b/x/observer/migrations/v5/migrate.go @@ -0,0 +1,37 @@ +package v5 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func MigrateStore(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { + var legacyObserverMappers []*types.ObserverMapper + legacyObserverMapperStore := prefix.NewStore(ctx.KVStore(observerStoreKey), types.KeyPrefix(types.ObserverMapperKey)) + iterator := sdk.KVStorePrefixIterator(legacyObserverMapperStore, []byte{}) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var val types.ObserverMapper + cdc.MustUnmarshal(iterator.Value(), &val) + legacyObserverMappers = append(legacyObserverMappers, &val) + } + + // We can safely assume that the observer list is the same for all the observer mappers + observerList := legacyObserverMappers[0].ObserverList + + storelastBlockObserverCount := prefix.NewStore(ctx.KVStore(observerStoreKey), types.KeyPrefix(types.LastBlockObserverCountKey)) + b := cdc.MustMarshal(&types.LastObserverCount{Count: uint64(len(observerList)), LastChangeHeight: ctx.BlockHeight()}) + storelastBlockObserverCount.Set([]byte{0}, b) + + storeObserverSet := prefix.NewStore(ctx.KVStore(observerStoreKey), types.KeyPrefix(types.ObserverSetKey)) + b = cdc.MustMarshal(&types.ObserverSet{ObserverList: observerList}) + storeObserverSet.Set([]byte{0}, b) + + for _, legacyObserverMapper := range legacyObserverMappers { + legacyObserverMapperStore.Delete(types.KeyPrefix(legacyObserverMapper.Index)) + } + return nil +} diff --git a/x/observer/migrations/v5/migrate_test.go b/x/observer/migrations/v5/migrate_test.go new file mode 100644 index 0000000000..61e2c86739 --- /dev/null +++ b/x/observer/migrations/v5/migrate_test.go @@ -0,0 +1,42 @@ +package v5_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + v5 "github.com/zeta-chain/zetacore/x/observer/migrations/v5" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMigrateStore(t *testing.T) { + t.Run("TestMigrateStore", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + legacyObserverMapperStore := prefix.NewStore(ctx.KVStore(k.StoreKey()), types.KeyPrefix(types.ObserverMapperKey)) + legacyObserverMapperList := sample.LegacyObserverMapperList(t, 12, "sample") + for _, legacyObserverMapper := range legacyObserverMapperList { + legacyObserverMapperStore.Set(types.KeyPrefix(legacyObserverMapper.Index), k.Codec().MustMarshal(legacyObserverMapper)) + } + err := v5.MigrateStore(ctx, k.StoreKey(), k.Codec()) + assert.NoError(t, err) + observerSet, found := k.GetObserverSet(ctx) + assert.True(t, found) + + assert.Equal(t, legacyObserverMapperList[0].ObserverList, observerSet.ObserverList) + iterator := sdk.KVStorePrefixIterator(legacyObserverMapperStore, []byte{}) + defer iterator.Close() + + var observerMappers []*types.ObserverMapper + for ; iterator.Valid(); iterator.Next() { + var val types.ObserverMapper + if !iterator.Valid() { + k.Codec().MustUnmarshal(iterator.Value(), &val) + observerMappers = append(observerMappers, &val) + } + } + assert.Equal(t, 0, len(observerMappers)) + }) +} diff --git a/x/observer/module.go b/x/observer/module.go index 0e63ab0e08..563b5188ea 100644 --- a/x/observer/module.go +++ b/x/observer/module.go @@ -153,6 +153,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err := cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4); err != nil { panic(err) } + if err := cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4to5); err != nil { + panic(err) + } } // RegisterInvariants registers the observer module's invariants. @@ -177,7 +180,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 3 } +func (AppModule) ConsensusVersion() uint64 { return 5 } // BeginBlock executes all ABCI BeginBlock logic respective to the observer module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index de85c6a161..ca6f6fb10a 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -34,4 +34,6 @@ var ( ErrLastObserverCountNotFound = errorsmod.Register(ModuleName, 1123, "last observer count not found") ErrUpdateObserver = errorsmod.Register(ModuleName, 1124, "unable to update observer") ErrNodeAccountNotFound = errorsmod.Register(ModuleName, 1125, "node account not found") + ErrMinDelegationNotFound = errorsmod.Register(ModuleName, 1126, "min delegation not found") + ErrObserverSetNotFound = errorsmod.Register(ModuleName, 1127, "observer set not found") ) diff --git a/x/observer/types/genesis.go b/x/observer/types/genesis.go index 918636794c..d41169671a 100644 --- a/x/observer/types/genesis.go +++ b/x/observer/types/genesis.go @@ -13,7 +13,7 @@ func DefaultGenesis() *GenesisState { return &GenesisState{ Params: ¶ms, Ballots: nil, - Observers: nil, + Observers: ObserverSet{}, NodeAccountList: []*NodeAccount{}, CrosschainFlags: &CrosschainFlags{IsInboundEnabled: true, IsOutboundEnabled: true}, Keygen: nil, @@ -55,7 +55,7 @@ func (gs GenesisState) Validate() error { chainNoncesIndexMap[elem.Index] = true } - return VerifyObserverMapper(gs.Observers) + return gs.Observers.Validate() } func GetGenesisStateFromAppState(marshaler codec.JSONCodec, appState map[string]json.RawMessage) GenesisState { diff --git a/x/observer/types/genesis.pb.go b/x/observer/types/genesis.pb.go index 1f55b9fdb7..1dd109c840 100644 --- a/x/observer/types/genesis.pb.go +++ b/x/observer/types/genesis.pb.go @@ -26,7 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { Ballots []*Ballot `protobuf:"bytes,1,rep,name=ballots,proto3" json:"ballots,omitempty"` - Observers []*ObserverMapper `protobuf:"bytes,2,rep,name=observers,proto3" json:"observers,omitempty"` + Observers ObserverSet `protobuf:"bytes,2,opt,name=observers,proto3" json:"observers"` NodeAccountList []*NodeAccount `protobuf:"bytes,3,rep,name=nodeAccountList,proto3" json:"nodeAccountList,omitempty"` CrosschainFlags *CrosschainFlags `protobuf:"bytes,4,opt,name=crosschain_flags,json=crosschainFlags,proto3" json:"crosschain_flags,omitempty"` Params *Params `protobuf:"bytes,5,opt,name=params,proto3" json:"params,omitempty"` @@ -82,11 +82,11 @@ func (m *GenesisState) GetBallots() []*Ballot { return nil } -func (m *GenesisState) GetObservers() []*ObserverMapper { +func (m *GenesisState) GetObservers() ObserverSet { if m != nil { return m.Observers } - return nil + return ObserverSet{} } func (m *GenesisState) GetNodeAccountList() []*NodeAccount { @@ -187,48 +187,48 @@ func init() { func init() { proto.RegisterFile("observer/genesis.proto", fileDescriptor_15ea8c9d44da7399) } var fileDescriptor_15ea8c9d44da7399 = []byte{ - // 642 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xdd, 0x4e, 0x14, 0x31, - 0x14, 0xc7, 0x77, 0x05, 0xc1, 0xed, 0xf2, 0x65, 0x45, 0x6d, 0x40, 0x07, 0xc4, 0x1b, 0xe2, 0xc7, - 0x8c, 0xc1, 0x4b, 0xe3, 0x85, 0x6c, 0x02, 0x12, 0x01, 0x75, 0x20, 0x31, 0xd1, 0xc4, 0x49, 0xb7, - 0x5b, 0x86, 0x89, 0xb3, 0xed, 0x64, 0xda, 0x35, 0xe0, 0x53, 0xf8, 0x18, 0x3e, 0x0a, 0x97, 0x5c, - 0x7a, 0x65, 0x0c, 0xbc, 0x88, 0xe9, 0xd7, 0xcc, 0xce, 0x6e, 0x32, 0xee, 0x5d, 0xf3, 0x3f, 0xe7, - 0xff, 0x3b, 0xed, 0x69, 0x4f, 0xc1, 0x3d, 0xde, 0x15, 0x34, 0xff, 0x4e, 0xf3, 0x20, 0xa6, 0x8c, - 0x8a, 0x44, 0xf8, 0x59, 0xce, 0x25, 0x87, 0xab, 0x3f, 0xa8, 0xc4, 0xe4, 0x14, 0x27, 0xcc, 0xd7, - 0x2b, 0x9e, 0x53, 0xdf, 0xa5, 0xae, 0x2c, 0xc7, 0x3c, 0xe6, 0x3a, 0x2f, 0x50, 0x2b, 0x63, 0x59, - 0xb9, 0x5b, 0xa0, 0xba, 0x38, 0x4d, 0xb9, 0xb4, 0xf2, 0x72, 0x29, 0xa7, 0xb8, 0x4f, 0xad, 0xba, - 0x5a, 0xa8, 0xba, 0x48, 0xc4, 0x38, 0x23, 0xd4, 0x16, 0x5f, 0x59, 0x2b, 0x83, 0x39, 0x17, 0xc2, - 0x64, 0x9c, 0xa4, 0x38, 0x16, 0x63, 0xa5, 0xbe, 0xd1, 0xf3, 0x98, 0xb2, 0x31, 0x28, 0xe3, 0x3d, - 0x1a, 0x61, 0x42, 0xf8, 0x80, 0xb9, 0x7d, 0x3c, 0x18, 0x0a, 0x32, 0x42, 0x23, 0xc9, 0x23, 0x42, - 0xe4, 0x99, 0x8d, 0xde, 0x2f, 0xa2, 0x6e, 0x31, 0x56, 0x2a, 0xc3, 0x39, 0xee, 0xbb, 0x1d, 0x3c, - 0x2c, 0x65, 0xca, 0x7a, 0x09, 0x8b, 0xab, 0x27, 0x80, 0x45, 0x58, 0x0a, 0xa7, 0x3d, 0x1a, 0xd6, - 0xa2, 0x93, 0x01, 0xeb, 0x89, 0xa8, 0x9f, 0xc4, 0x39, 0x96, 0xdc, 0x16, 0xdb, 0xf8, 0xd5, 0x02, - 0x73, 0xbb, 0xe6, 0x1e, 0x8e, 0x24, 0x96, 0x14, 0xbe, 0x06, 0xb3, 0xa6, 0x99, 0x02, 0x35, 0xd7, - 0xa7, 0x36, 0xdb, 0x5b, 0x8f, 0xfd, 0x9a, 0x8b, 0xf1, 0xb7, 0x75, 0x6e, 0xe8, 0x3c, 0x70, 0x0f, - 0xb4, 0x5c, 0x4c, 0xa0, 0x1b, 0x1a, 0xf0, 0xb4, 0x16, 0xf0, 0xde, 0x2e, 0x0e, 0x70, 0x96, 0xd1, - 0x3c, 0x2c, 0xdd, 0x30, 0x04, 0x8b, 0xaa, 0xa9, 0x6f, 0x4c, 0x4f, 0xf7, 0x13, 0x21, 0xd1, 0x94, - 0x06, 0x6e, 0xd6, 0x02, 0x0f, 0x4b, 0x4f, 0x38, 0x0a, 0x80, 0x9f, 0xc0, 0xd2, 0xe8, 0x05, 0xa3, - 0xe9, 0xf5, 0xe6, 0x66, 0x7b, 0xeb, 0x59, 0x2d, 0xb4, 0x53, 0x98, 0x76, 0x94, 0x27, 0x5c, 0x24, - 0x55, 0x01, 0xbe, 0x02, 0x33, 0xe6, 0xb6, 0xd0, 0x4d, 0x8d, 0xab, 0xef, 0xda, 0x07, 0x9d, 0x1a, - 0x5a, 0x8b, 0x32, 0x9b, 0x57, 0x85, 0x66, 0x26, 0x30, 0xbf, 0xd3, 0xa9, 0xa1, 0xb5, 0xc0, 0xaf, - 0xe0, 0x4e, 0x8a, 0x85, 0x8c, 0x5c, 0x3c, 0xd2, 0xa7, 0x45, 0xb3, 0x9a, 0xe4, 0xd7, 0x92, 0xf6, - 0xb1, 0x90, 0xae, 0xff, 0x1d, 0xdd, 0xb0, 0xdb, 0xe9, 0xa8, 0x04, 0xbf, 0x80, 0x25, 0xe5, 0x8a, - 0xcc, 0x5e, 0xa3, 0x54, 0xdd, 0xc3, 0x2d, 0x0d, 0xaf, 0xbf, 0xd8, 0x0e, 0xcf, 0xa9, 0x39, 0xa7, - 0xea, 0xfc, 0xf6, 0xf4, 0xc5, 0x9f, 0xb5, 0x46, 0xb8, 0x40, 0x2a, 0x2a, 0xdc, 0x02, 0x53, 0x52, - 0x08, 0xd4, 0xd2, 0xbc, 0xf5, 0x5a, 0xde, 0xf1, 0xd1, 0x51, 0xa8, 0x92, 0xe1, 0x2e, 0x68, 0xab, - 0xe7, 0x7c, 0x9a, 0x08, 0xc9, 0xf3, 0x73, 0x04, 0xf4, 0x9b, 0xf8, 0xaf, 0xd7, 0x6e, 0x00, 0x48, - 0x21, 0xde, 0x1a, 0x27, 0xec, 0x01, 0xe8, 0xe6, 0xa2, 0x18, 0x0b, 0x81, 0xda, 0x9a, 0xf7, 0xa2, - 0x9e, 0x27, 0xc4, 0xce, 0x80, 0xf5, 0x0e, 0xac, 0x69, 0x8f, 0x9d, 0x70, 0xcb, 0x5f, 0x92, 0xd5, - 0x90, 0xda, 0x2e, 0xd0, 0xdf, 0x90, 0xe9, 0xdc, 0x9c, 0xa6, 0x6f, 0xd4, 0xcf, 0x94, 0x4a, 0xb7, - 0xbc, 0x96, 0xf6, 0xda, 0xb7, 0xbb, 0x50, 0x9d, 0x7c, 0x34, 0xaf, 0x61, 0x4f, 0xea, 0x9f, 0x9a, - 0xb1, 0x1c, 0x6a, 0x87, 0x85, 0xce, 0x67, 0xc3, 0x22, 0xfc, 0x08, 0xe6, 0x86, 0xbf, 0x44, 0xb4, - 0x30, 0xc1, 0x94, 0x75, 0x94, 0x5e, 0x81, 0xb6, 0x49, 0x29, 0xc1, 0x10, 0xcc, 0x57, 0xfe, 0x3c, - 0xb4, 0x38, 0xd1, 0xe4, 0x32, 0x42, 0x8f, 0x79, 0x87, 0xc8, 0x33, 0xc7, 0x64, 0x43, 0xd2, 0xde, - 0xc5, 0x95, 0xd7, 0xbc, 0xbc, 0xf2, 0x9a, 0x7f, 0xaf, 0xbc, 0xe6, 0xcf, 0x6b, 0xaf, 0x71, 0x79, - 0xed, 0x35, 0x7e, 0x5f, 0x7b, 0x8d, 0xcf, 0x41, 0x9c, 0xc8, 0xd3, 0x41, 0xd7, 0x27, 0xbc, 0x1f, - 0x28, 0xec, 0x73, 0x5d, 0x21, 0x70, 0x15, 0x82, 0xb3, 0xa0, 0xfc, 0x08, 0xcf, 0x33, 0x2a, 0xba, - 0x33, 0xfa, 0xf3, 0x7b, 0xf9, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xee, 0x86, 0x37, 0x94, 0x8c, 0x06, - 0x00, 0x00, + // 641 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, + 0x14, 0x4e, 0xfe, 0xf6, 0x6f, 0xe9, 0xa4, 0x37, 0x86, 0x02, 0xa3, 0x16, 0xdc, 0x52, 0x36, 0x15, + 0x17, 0x1b, 0x95, 0x25, 0x62, 0x41, 0x23, 0xb5, 0x54, 0x94, 0x02, 0x4e, 0x25, 0x24, 0x90, 0xb0, + 0x26, 0x93, 0xa9, 0x6b, 0xe1, 0xcc, 0x44, 0x9e, 0x09, 0x6a, 0x78, 0x0a, 0xde, 0x83, 0x17, 0xe9, + 0xb2, 0x4b, 0x56, 0x08, 0x25, 0x2f, 0x82, 0xe6, 0x66, 0xc7, 0x89, 0x64, 0xb2, 0x1b, 0x7d, 0xe7, + 0x7c, 0xdf, 0x39, 0x73, 0x6e, 0xe0, 0x0e, 0x6f, 0x0b, 0x9a, 0x7d, 0xa3, 0x59, 0x10, 0x53, 0x46, + 0x45, 0x22, 0xfc, 0x5e, 0xc6, 0x25, 0x87, 0x5b, 0xdf, 0xa9, 0xc4, 0xe4, 0x02, 0x27, 0xcc, 0xd7, + 0x2f, 0x9e, 0x51, 0xdf, 0xb9, 0x6e, 0x6e, 0xc4, 0x3c, 0xe6, 0xda, 0x2f, 0x50, 0x2f, 0x43, 0xd9, + 0xbc, 0x9d, 0x4b, 0xb5, 0x71, 0x9a, 0x72, 0x69, 0xe1, 0x8d, 0x02, 0x4e, 0x71, 0x97, 0x5a, 0x74, + 0x2b, 0x47, 0x75, 0x90, 0x88, 0x71, 0x46, 0xa8, 0x0d, 0xbe, 0xb9, 0x5d, 0x18, 0x33, 0x2e, 0x84, + 0xf1, 0x38, 0x4f, 0x71, 0x2c, 0xa6, 0x42, 0x7d, 0xa5, 0x83, 0x98, 0xb2, 0x29, 0x51, 0xc6, 0x3b, + 0x34, 0xc2, 0x84, 0xf0, 0x3e, 0x73, 0x79, 0xdc, 0x1b, 0x33, 0x32, 0x42, 0x23, 0xc9, 0x23, 0x42, + 0xe4, 0xa5, 0xb5, 0xde, 0xcd, 0xad, 0xee, 0x31, 0x15, 0xaa, 0x87, 0x33, 0xdc, 0x75, 0x19, 0xdc, + 0x2f, 0x60, 0xca, 0x3a, 0x09, 0x8b, 0xcb, 0x3f, 0x80, 0xb9, 0x59, 0x0a, 0x87, 0x3d, 0x18, 0xc7, + 0xa2, 0xf3, 0x3e, 0xeb, 0x88, 0xa8, 0x9b, 0xc4, 0x19, 0x96, 0xdc, 0x06, 0xdb, 0xfd, 0xb9, 0x04, + 0x96, 0x8f, 0x4c, 0x1f, 0x5a, 0x12, 0x4b, 0x0a, 0x5f, 0x82, 0x45, 0x53, 0x4c, 0x81, 0xea, 0x3b, + 0x73, 0x7b, 0x8d, 0xfd, 0x87, 0x7e, 0x45, 0x63, 0xfc, 0x03, 0xed, 0x1b, 0x3a, 0x0e, 0x3c, 0x01, + 0x4b, 0xce, 0x26, 0xd0, 0x7f, 0x3b, 0xf5, 0xbd, 0xc6, 0xfe, 0x5e, 0xa5, 0xc0, 0x3b, 0xfb, 0x68, + 0x51, 0x79, 0x30, 0x7f, 0xf5, 0x7b, 0xbb, 0x16, 0x16, 0x02, 0x30, 0x04, 0x6b, 0xaa, 0xae, 0xaf, + 0x4c, 0x59, 0x4f, 0x12, 0x21, 0xd1, 0x9c, 0x4e, 0xaa, 0x5a, 0xf3, 0xb4, 0xe0, 0x84, 0x93, 0x02, + 0xf0, 0x23, 0x58, 0x9f, 0xec, 0x31, 0x9a, 0xd7, 0x89, 0x3e, 0xa9, 0x14, 0x6d, 0xe6, 0xa4, 0x43, + 0xc5, 0x09, 0xd7, 0x48, 0x19, 0x80, 0x2f, 0xc0, 0x82, 0x69, 0x18, 0xfa, 0x5f, 0xcb, 0x55, 0x17, + 0xee, 0xbd, 0x76, 0x0d, 0x2d, 0x45, 0x91, 0xcd, 0x60, 0xa1, 0x85, 0x19, 0xc8, 0x6f, 0xb4, 0x6b, + 0x68, 0x29, 0xf0, 0x0b, 0xb8, 0x95, 0x62, 0x21, 0x23, 0x67, 0x8f, 0xf4, 0x6f, 0xd1, 0xa2, 0x56, + 0xf2, 0x2b, 0x95, 0x4e, 0xb0, 0x90, 0xae, 0x05, 0x4d, 0x5d, 0xb0, 0x9b, 0xe9, 0x24, 0x04, 0x3f, + 0x83, 0x75, 0xc5, 0x8a, 0x4c, 0xae, 0x51, 0xaa, 0xfa, 0x70, 0x43, 0x8b, 0x3f, 0xae, 0x2e, 0x19, + 0xcf, 0xa8, 0xf9, 0xa7, 0xaa, 0xbc, 0x6d, 0xef, 0x2a, 0x29, 0xa1, 0x70, 0x1f, 0xcc, 0x49, 0x21, + 0xd0, 0x92, 0xd6, 0xdb, 0xa9, 0xd4, 0x3b, 0x6b, 0xb5, 0x42, 0xe5, 0x0c, 0x8f, 0x40, 0x43, 0x4d, + 0xf4, 0x45, 0x22, 0x24, 0xcf, 0x06, 0x08, 0xe8, 0x99, 0xf8, 0x27, 0xd7, 0x26, 0x00, 0xa4, 0x10, + 0xaf, 0x0d, 0x13, 0x76, 0x00, 0x74, 0xab, 0x91, 0x6f, 0x86, 0x40, 0x0d, 0xad, 0xf7, 0xac, 0x5a, + 0x4f, 0x88, 0xc3, 0x3e, 0xeb, 0xbc, 0xb5, 0xa4, 0x63, 0x76, 0xce, 0xad, 0xfe, 0xba, 0x2c, 0x9b, + 0x54, 0xba, 0x40, 0x5f, 0x22, 0x53, 0xb9, 0x65, 0xad, 0xbe, 0x5b, 0xbd, 0x56, 0xca, 0xdd, 0xed, + 0x83, 0xe6, 0xda, 0xd9, 0x5d, 0x2d, 0x2f, 0x3f, 0x5a, 0xd1, 0x62, 0x8f, 0xaa, 0x47, 0xcd, 0x50, + 0x4e, 0x35, 0xc3, 0x8a, 0xae, 0xf4, 0xc6, 0x41, 0xf8, 0x01, 0x2c, 0x8f, 0x5f, 0x45, 0xb4, 0x3a, + 0xc3, 0x96, 0x35, 0x15, 0x5e, 0x12, 0x6d, 0x90, 0x02, 0x82, 0x21, 0x58, 0x29, 0x9d, 0x3d, 0xb4, + 0x36, 0xd3, 0xe6, 0x32, 0x42, 0xcf, 0x78, 0x93, 0xc8, 0x4b, 0xa7, 0xc9, 0xc6, 0xa0, 0xe3, 0xab, + 0xa1, 0x57, 0xbf, 0x1e, 0x7a, 0xf5, 0x3f, 0x43, 0xaf, 0xfe, 0x63, 0xe4, 0xd5, 0xae, 0x47, 0x5e, + 0xed, 0xd7, 0xc8, 0xab, 0x7d, 0x0a, 0xe2, 0x44, 0x5e, 0xf4, 0xdb, 0x3e, 0xe1, 0xdd, 0x40, 0xc9, + 0x3e, 0xd5, 0x11, 0x02, 0x17, 0x21, 0xb8, 0x0c, 0x8a, 0x5b, 0x38, 0xe8, 0x51, 0xd1, 0x5e, 0xd0, + 0xf7, 0xef, 0xf9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x39, 0x18, 0xe6, 0x8f, 0x06, 0x00, + 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -419,20 +419,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - if len(m.Observers) > 0 { - for iNdEx := len(m.Observers) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Observers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 + { + size, err := m.Observers.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x12 if len(m.Ballots) > 0 { for iNdEx := len(m.Ballots) - 1; iNdEx >= 0; iNdEx-- { { @@ -473,12 +469,8 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.Observers) > 0 { - for _, e := range m.Observers { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } + l = m.Observers.Size() + n += 1 + l + sovGenesis(uint64(l)) if len(m.NodeAccountList) > 0 { for _, e := range m.NodeAccountList { l = e.Size() @@ -644,8 +636,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Observers = append(m.Observers, &ObserverMapper{}) - if err := m.Observers[len(m.Observers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Observers.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/observer/types/keys.go b/x/observer/types/keys.go index 21a8ff4489..fe7669b57a 100644 --- a/x/observer/types/keys.go +++ b/x/observer/types/keys.go @@ -1,6 +1,11 @@ package types -import "fmt" +import ( + "fmt" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) const ( // ModuleName defines the module name @@ -19,8 +24,19 @@ const ( MemStoreKey = "mem_observer" GroupID1Address = "zeta1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsxn0x73" + + MinObserverDelegation = "1000000000000000000" ) +func GetMinObserverDelegation() (sdkmath.Int, bool) { + return sdkmath.NewIntFromString(MinObserverDelegation) +} + +func GetMinObserverDelegationDec() (sdk.Dec, error) { + return sdk.NewDecFromStr(MinObserverDelegation) + +} + func KeyPrefix(p string) []byte { return []byte(p) } @@ -32,9 +48,11 @@ func BallotListKeyPrefix(p int64) []byte { const ( BlameKey = "Blame-" // TODO change identifier for VoterKey to something more descriptive - VoterKey = "Voter-value-" - AllCoreParams = "CoreParams" - ObserverMapperKey = "Observer-value-" + VoterKey = "Voter-value-" + AllCoreParams = "CoreParams" + ObserverMapperKey = "Observer-value-" + + ObserverSetKey = "ObserverSet-value-" ObserverParamsKey = "ObserverParams" AdminPolicyParamsKey = "AdminParams" BallotMaturityBlocksParamsKey = "BallotMaturityBlocksParams" diff --git a/x/observer/types/observer.pb.go b/x/observer/types/observer.pb.go index 6276da7570..07218c037a 100644 --- a/x/observer/types/observer.pb.go +++ b/x/observer/types/observer.pb.go @@ -147,6 +147,50 @@ func (m *ObserverMapper) GetObserverList() []string { return nil } +type ObserverSet struct { + ObserverList []string `protobuf:"bytes,1,rep,name=observer_list,json=observerList,proto3" json:"observer_list,omitempty"` +} + +func (m *ObserverSet) Reset() { *m = ObserverSet{} } +func (m *ObserverSet) String() string { return proto.CompactTextString(m) } +func (*ObserverSet) ProtoMessage() {} +func (*ObserverSet) Descriptor() ([]byte, []int) { + return fileDescriptor_3004233a4a5969ce, []int{1} +} +func (m *ObserverSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ObserverSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ObserverSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ObserverSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObserverSet.Merge(m, src) +} +func (m *ObserverSet) XXX_Size() int { + return m.Size() +} +func (m *ObserverSet) XXX_DiscardUnknown() { + xxx_messageInfo_ObserverSet.DiscardUnknown(m) +} + +var xxx_messageInfo_ObserverSet proto.InternalMessageInfo + +func (m *ObserverSet) GetObserverList() []string { + if m != nil { + return m.ObserverList + } + return nil +} + type LastObserverCount struct { Count uint64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` LastChangeHeight int64 `protobuf:"varint,2,opt,name=last_change_height,json=lastChangeHeight,proto3" json:"last_change_height,omitempty"` @@ -156,7 +200,7 @@ func (m *LastObserverCount) Reset() { *m = LastObserverCount{} } func (m *LastObserverCount) String() string { return proto.CompactTextString(m) } func (*LastObserverCount) ProtoMessage() {} func (*LastObserverCount) Descriptor() ([]byte, []int) { - return fileDescriptor_3004233a4a5969ce, []int{1} + return fileDescriptor_3004233a4a5969ce, []int{2} } func (m *LastObserverCount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -203,39 +247,41 @@ func init() { proto.RegisterEnum("zetachain.zetacore.observer.ObservationType", ObservationType_name, ObservationType_value) proto.RegisterEnum("zetachain.zetacore.observer.ObserverUpdateReason", ObserverUpdateReason_name, ObserverUpdateReason_value) proto.RegisterType((*ObserverMapper)(nil), "zetachain.zetacore.observer.ObserverMapper") + proto.RegisterType((*ObserverSet)(nil), "zetachain.zetacore.observer.ObserverSet") proto.RegisterType((*LastObserverCount)(nil), "zetachain.zetacore.observer.LastObserverCount") } func init() { proto.RegisterFile("observer/observer.proto", fileDescriptor_3004233a4a5969ce) } var fileDescriptor_3004233a4a5969ce = []byte{ - // 415 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x52, 0xd1, 0x8a, 0xd3, 0x40, - 0x14, 0xcd, 0xb4, 0x51, 0xe8, 0xac, 0xed, 0x66, 0xc7, 0x8a, 0xa5, 0x42, 0x28, 0xeb, 0x4b, 0x59, - 0x34, 0x03, 0xea, 0x0f, 0xb8, 0x45, 0x74, 0xb1, 0xb2, 0x90, 0x76, 0x11, 0x7c, 0x29, 0x93, 0xe6, - 0x9a, 0x0c, 0x34, 0x33, 0x21, 0x33, 0x91, 0xc6, 0x37, 0xff, 0xc0, 0x8f, 0xf0, 0xc1, 0x4f, 0xf1, - 0x71, 0x1f, 0x7d, 0x94, 0xf6, 0x47, 0x64, 0x66, 0x76, 0xf6, 0x29, 0xe7, 0x9c, 0x3b, 0xe7, 0xde, - 0x43, 0xee, 0xc5, 0x4f, 0x65, 0xa6, 0xa0, 0xf9, 0x06, 0x0d, 0xf5, 0x20, 0xa9, 0x1b, 0xa9, 0x25, - 0x79, 0xf6, 0x1d, 0x34, 0xdb, 0x96, 0x8c, 0x8b, 0xc4, 0x22, 0xd9, 0x40, 0xe2, 0x9f, 0x4c, 0x1f, - 0x6f, 0x65, 0x55, 0x49, 0x41, 0xdd, 0xc7, 0x39, 0xa6, 0xe3, 0x42, 0x16, 0xd2, 0x42, 0x6a, 0x90, - 0x53, 0xcf, 0x7f, 0x20, 0x3c, 0xba, 0xbe, 0xf3, 0x7d, 0x62, 0x75, 0x0d, 0x0d, 0x19, 0xe3, 0x07, - 0x5c, 0xe4, 0xb0, 0x9f, 0xa0, 0x19, 0x9a, 0x0f, 0x52, 0x47, 0xc8, 0x1b, 0x3c, 0xf2, 0xfd, 0x37, - 0x76, 0xee, 0xa4, 0x37, 0x43, 0xf3, 0x93, 0x57, 0xc3, 0xe4, 0x6e, 0xca, 0xc2, 0x88, 0xe9, 0xd0, - 0x3f, 0xb2, 0x94, 0x3c, 0xc7, 0xf7, 0xc2, 0x66, 0xc7, 0x95, 0x9e, 0x84, 0xb3, 0xfe, 0x7c, 0x90, - 0x3e, 0xf2, 0xe2, 0x92, 0x2b, 0x7d, 0xfe, 0x19, 0x9f, 0x2d, 0x99, 0xd2, 0x3e, 0xc6, 0x42, 0xb6, - 0x42, 0x9b, 0x14, 0x5b, 0x03, 0x6c, 0x8a, 0x30, 0x75, 0x84, 0xbc, 0xc0, 0x64, 0xc7, 0x94, 0x36, - 0x09, 0x44, 0x01, 0x9b, 0x12, 0x78, 0x51, 0x6a, 0x9b, 0xa4, 0x9f, 0x46, 0xa6, 0xb2, 0xb0, 0x85, - 0x0f, 0x56, 0xbf, 0xd8, 0xe1, 0x53, 0xd7, 0x94, 0x69, 0x2e, 0xc5, 0xba, 0xab, 0x81, 0x3c, 0xc1, - 0x67, 0xef, 0xaa, 0x5a, 0x77, 0x7e, 0x98, 0x11, 0xa3, 0x80, 0x0c, 0xf1, 0xe0, 0x4a, 0x5c, 0xca, - 0x56, 0xe4, 0xeb, 0x7d, 0x84, 0xc8, 0x08, 0xe3, 0xeb, 0x56, 0x7b, 0xde, 0x33, 0xe5, 0xf5, 0x6a, - 0xf5, 0x11, 0xba, 0xf7, 0x20, 0xa2, 0xbe, 0x29, 0x3b, 0xba, 0xe2, 0x85, 0x88, 0xc2, 0x69, 0xf8, - 0xfb, 0x57, 0x8c, 0x2e, 0x96, 0x78, 0xec, 0xbb, 0xde, 0xd4, 0x39, 0xd3, 0x90, 0x02, 0x53, 0x52, - 0x18, 0xf3, 0x8d, 0xc8, 0xe1, 0x2b, 0x17, 0x90, 0x47, 0x81, 0x35, 0xcb, 0x2a, 0x53, 0x5a, 0x1a, - 0x8e, 0xc8, 0x29, 0x3e, 0x79, 0x9b, 0x57, 0x5c, 0x38, 0x4f, 0xd4, 0x73, 0xdd, 0x2e, 0xaf, 0xfe, - 0x1c, 0x62, 0x74, 0x7b, 0x88, 0xd1, 0xbf, 0x43, 0x8c, 0x7e, 0x1e, 0xe3, 0xe0, 0xf6, 0x18, 0x07, - 0x7f, 0x8f, 0x71, 0xf0, 0x85, 0x16, 0x5c, 0x97, 0x6d, 0x66, 0xfe, 0x3b, 0x35, 0xbb, 0x7f, 0x69, - 0xd7, 0x41, 0xfd, 0x19, 0xd0, 0xfd, 0xfd, 0xad, 0x50, 0xdd, 0xd5, 0xa0, 0xb2, 0x87, 0x76, 0xd5, - 0xaf, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x0c, 0x23, 0x95, 0x4d, 0x02, 0x00, 0x00, + // 427 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xc1, 0x8a, 0x13, 0x41, + 0x10, 0x9d, 0x4e, 0xa2, 0x90, 0x8e, 0xc9, 0xce, 0xb6, 0x11, 0x43, 0x84, 0x21, 0xac, 0x97, 0xb0, + 0x68, 0x1a, 0x56, 0x7f, 0xc0, 0x0d, 0xa2, 0x8b, 0x91, 0x85, 0x49, 0x16, 0xc1, 0x4b, 0xe8, 0x64, + 0xca, 0x49, 0x43, 0xa6, 0x7b, 0x98, 0xae, 0x48, 0xe2, 0xcd, 0x3f, 0xf0, 0x23, 0x3c, 0xf8, 0x29, + 0x1e, 0xf7, 0xe8, 0x51, 0x92, 0x1f, 0x91, 0xee, 0xde, 0xce, 0xc5, 0x3d, 0xf5, 0x7b, 0xaf, 0xfa, + 0x55, 0x3d, 0xa8, 0xa2, 0x4f, 0xf5, 0xc2, 0x40, 0xf5, 0x15, 0x2a, 0x1e, 0xc0, 0xa8, 0xac, 0x34, + 0x6a, 0xf6, 0xec, 0x1b, 0xa0, 0x58, 0xae, 0x84, 0x54, 0x23, 0x87, 0x74, 0x05, 0xa3, 0xf0, 0xa5, + 0xff, 0x78, 0xa9, 0x8b, 0x42, 0x2b, 0xee, 0x1f, 0xef, 0xe8, 0x77, 0x73, 0x9d, 0x6b, 0x07, 0xb9, + 0x45, 0x5e, 0x3d, 0xfb, 0x4e, 0x68, 0xe7, 0xfa, 0xce, 0xf7, 0x51, 0x94, 0x25, 0x54, 0xac, 0x4b, + 0x1f, 0x48, 0x95, 0xc1, 0xb6, 0x47, 0x06, 0x64, 0xd8, 0x4c, 0x3d, 0x61, 0xaf, 0x69, 0x27, 0xf4, + 0x9f, 0xbb, 0xb9, 0xbd, 0xda, 0x80, 0x0c, 0x5b, 0x17, 0xed, 0xd1, 0xdd, 0x94, 0xb1, 0x15, 0xd3, + 0x76, 0xf8, 0xe4, 0x28, 0x7b, 0x4e, 0x8f, 0xc2, 0x7c, 0x2d, 0x0d, 0xf6, 0x1a, 0x83, 0xfa, 0xb0, + 0x99, 0x3e, 0x0a, 0xe2, 0x44, 0x1a, 0x3c, 0xbb, 0xa0, 0xad, 0x10, 0x61, 0x0a, 0xf8, 0xbf, 0x87, + 0xdc, 0xe3, 0xf9, 0x44, 0x4f, 0x27, 0xc2, 0x60, 0xf0, 0x8d, 0xf5, 0x46, 0xa1, 0x4d, 0xbe, 0xb4, + 0xc0, 0x25, 0x6f, 0xa4, 0x9e, 0xb0, 0x17, 0x94, 0xad, 0x85, 0x41, 0x9b, 0x5a, 0xe5, 0x30, 0x5f, + 0x81, 0xcc, 0x57, 0xe8, 0xd2, 0xd7, 0xd3, 0xd8, 0x56, 0xc6, 0xae, 0xf0, 0xde, 0xe9, 0xe7, 0x6b, + 0x7a, 0xe2, 0x9b, 0x0a, 0x94, 0x5a, 0xcd, 0x76, 0x25, 0xb0, 0x27, 0xf4, 0xf4, 0x6d, 0x51, 0xe2, + 0x2e, 0x0c, 0xb3, 0x62, 0x1c, 0xb1, 0x36, 0x6d, 0x5e, 0xa9, 0x4b, 0xbd, 0x51, 0xd9, 0x6c, 0x1b, + 0x13, 0xd6, 0xa1, 0xf4, 0x7a, 0x83, 0x81, 0xd7, 0x6c, 0x79, 0x36, 0x9d, 0x7e, 0x80, 0xdd, 0x3b, + 0x50, 0x71, 0xdd, 0x96, 0x3d, 0x9d, 0xca, 0x5c, 0xc5, 0x8d, 0x7e, 0xe3, 0xd7, 0xcf, 0x84, 0x9c, + 0x4f, 0x68, 0x37, 0x74, 0xbd, 0x29, 0x33, 0x81, 0x90, 0x82, 0x30, 0x5a, 0x59, 0xf3, 0x8d, 0xca, + 0xe0, 0x8b, 0x54, 0x90, 0xc5, 0x91, 0x33, 0xeb, 0x62, 0x61, 0x50, 0x5b, 0x4e, 0xd8, 0x09, 0x6d, + 0xbd, 0xc9, 0x0a, 0xa9, 0xbc, 0x27, 0xae, 0xf9, 0x6e, 0x97, 0x57, 0xbf, 0xf7, 0x09, 0xb9, 0xdd, + 0x27, 0xe4, 0xef, 0x3e, 0x21, 0x3f, 0x0e, 0x49, 0x74, 0x7b, 0x48, 0xa2, 0x3f, 0x87, 0x24, 0xfa, + 0xcc, 0x73, 0x89, 0xab, 0xcd, 0xc2, 0xee, 0x8a, 0xdb, 0x7b, 0x79, 0xe9, 0x56, 0xc8, 0xc3, 0xe9, + 0xf0, 0xed, 0xf1, 0xbe, 0x38, 0xee, 0x4a, 0x30, 0x8b, 0x87, 0xee, 0x3c, 0x5e, 0xfd, 0x0b, 0x00, + 0x00, 0xff, 0xff, 0x3a, 0x82, 0x4c, 0x46, 0x81, 0x02, 0x00, 0x00, } func (m *ObserverMapper) Marshal() (dAtA []byte, err error) { @@ -289,6 +335,38 @@ func (m *ObserverMapper) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ObserverSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ObserverSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ObserverSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ObserverList) > 0 { + for iNdEx := len(m.ObserverList) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ObserverList[iNdEx]) + copy(dAtA[i:], m.ObserverList[iNdEx]) + i = encodeVarintObserver(dAtA, i, uint64(len(m.ObserverList[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *LastObserverCount) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -356,6 +434,21 @@ func (m *ObserverMapper) Size() (n int) { return n } +func (m *ObserverSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ObserverList) > 0 { + for _, s := range m.ObserverList { + l = len(s) + n += 1 + l + sovObserver(uint64(l)) + } + } + return n +} + func (m *LastObserverCount) Size() (n int) { if m == nil { return 0 @@ -527,6 +620,88 @@ func (m *ObserverMapper) Unmarshal(dAtA []byte) error { } return nil } +func (m *ObserverSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowObserver + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ObserverSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ObserverSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObserverList", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowObserver + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthObserver + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthObserver + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObserverList = append(m.ObserverList, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipObserver(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthObserver + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *LastObserverCount) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/types/observer_mapper.go b/x/observer/types/observer_mapper.go index 5fc6d54736..b78f5daa8c 100644 --- a/x/observer/types/observer_mapper.go +++ b/x/observer/types/observer_mapper.go @@ -1,35 +1,16 @@ package types import ( - "errors" - "fmt" - + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/common" ) // Validate observer mapper contains an existing chain -func (m *ObserverMapper) Validate() error { - if m.ObserverChain == nil { - return errors.New("observer chain is not set") - } - - chains := common.DefaultChainsList() - for _, chain := range chains { - if *m.ObserverChain == *chain { - return nil - } - } - return fmt.Errorf("observer chain %d doesn't exist: ", m.ObserverChain.ChainName) -} - -// VerifyObserverMapper verifies list of observer mappers -func VerifyObserverMapper(obs []*ObserverMapper) error { - for _, mapper := range obs { - if mapper != nil { - err := mapper.Validate() - if err != nil { - return fmt.Errorf("observer mapper %s is invalid: %s", mapper.String(), err.Error()) - } +func (m *ObserverSet) Validate() error { + for _, observerAddress := range m.ObserverList { + _, err := sdk.AccAddressFromBech32(observerAddress) + if err != nil { + return err } } return nil diff --git a/x/observer/types/observer_set.go b/x/observer/types/observer_set.go new file mode 100644 index 0000000000..71798f213f --- /dev/null +++ b/x/observer/types/observer_set.go @@ -0,0 +1,9 @@ +package types + +func (m *ObserverSet) Len() int { + return len(m.ObserverList) +} + +func (m *ObserverSet) LenUint() uint64 { + return uint64(len(m.ObserverList)) +} diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index cf78bf525a..7925d09576 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -1246,22 +1246,21 @@ func (m *QueryBallotByIdentifierResponse) GetBallotStatus() BallotStatus { return BallotStatus_BallotFinalized_SuccessObservation } -type QueryObserversByChainRequest struct { - ObservationChain string `protobuf:"bytes,1,opt,name=observation_chain,json=observationChain,proto3" json:"observation_chain,omitempty"` +type QueryObserverSet struct { } -func (m *QueryObserversByChainRequest) Reset() { *m = QueryObserversByChainRequest{} } -func (m *QueryObserversByChainRequest) String() string { return proto.CompactTextString(m) } -func (*QueryObserversByChainRequest) ProtoMessage() {} -func (*QueryObserversByChainRequest) Descriptor() ([]byte, []int) { +func (m *QueryObserverSet) Reset() { *m = QueryObserverSet{} } +func (m *QueryObserverSet) String() string { return proto.CompactTextString(m) } +func (*QueryObserverSet) ProtoMessage() {} +func (*QueryObserverSet) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{25} } -func (m *QueryObserversByChainRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryObserverSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryObserversByChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryObserverSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryObserversByChainRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryObserverSet.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1271,41 +1270,34 @@ func (m *QueryObserversByChainRequest) XXX_Marshal(b []byte, deterministic bool) return b[:n], nil } } -func (m *QueryObserversByChainRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryObserversByChainRequest.Merge(m, src) +func (m *QueryObserverSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryObserverSet.Merge(m, src) } -func (m *QueryObserversByChainRequest) XXX_Size() int { +func (m *QueryObserverSet) XXX_Size() int { return m.Size() } -func (m *QueryObserversByChainRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryObserversByChainRequest.DiscardUnknown(m) +func (m *QueryObserverSet) XXX_DiscardUnknown() { + xxx_messageInfo_QueryObserverSet.DiscardUnknown(m) } -var xxx_messageInfo_QueryObserversByChainRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryObserverSet proto.InternalMessageInfo -func (m *QueryObserversByChainRequest) GetObservationChain() string { - if m != nil { - return m.ObservationChain - } - return "" -} - -type QueryObserversByChainResponse struct { +type QueryObserverSetResponse struct { Observers []string `protobuf:"bytes,1,rep,name=observers,proto3" json:"observers,omitempty"` } -func (m *QueryObserversByChainResponse) Reset() { *m = QueryObserversByChainResponse{} } -func (m *QueryObserversByChainResponse) String() string { return proto.CompactTextString(m) } -func (*QueryObserversByChainResponse) ProtoMessage() {} -func (*QueryObserversByChainResponse) Descriptor() ([]byte, []int) { +func (m *QueryObserverSetResponse) Reset() { *m = QueryObserverSetResponse{} } +func (m *QueryObserverSetResponse) String() string { return proto.CompactTextString(m) } +func (*QueryObserverSetResponse) ProtoMessage() {} +func (*QueryObserverSetResponse) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{26} } -func (m *QueryObserversByChainResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryObserverSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryObserversByChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryObserverSetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryObserversByChainResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryObserverSetResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1315,105 +1307,25 @@ func (m *QueryObserversByChainResponse) XXX_Marshal(b []byte, deterministic bool return b[:n], nil } } -func (m *QueryObserversByChainResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryObserversByChainResponse.Merge(m, src) +func (m *QueryObserverSetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryObserverSetResponse.Merge(m, src) } -func (m *QueryObserversByChainResponse) XXX_Size() int { +func (m *QueryObserverSetResponse) XXX_Size() int { return m.Size() } -func (m *QueryObserversByChainResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryObserversByChainResponse.DiscardUnknown(m) +func (m *QueryObserverSetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryObserverSetResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryObserversByChainResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryObserverSetResponse proto.InternalMessageInfo -func (m *QueryObserversByChainResponse) GetObservers() []string { +func (m *QueryObserverSetResponse) GetObservers() []string { if m != nil { return m.Observers } return nil } -type QueryAllObserverMappersRequest struct { -} - -func (m *QueryAllObserverMappersRequest) Reset() { *m = QueryAllObserverMappersRequest{} } -func (m *QueryAllObserverMappersRequest) String() string { return proto.CompactTextString(m) } -func (*QueryAllObserverMappersRequest) ProtoMessage() {} -func (*QueryAllObserverMappersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{27} -} -func (m *QueryAllObserverMappersRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryAllObserverMappersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryAllObserverMappersRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryAllObserverMappersRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAllObserverMappersRequest.Merge(m, src) -} -func (m *QueryAllObserverMappersRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryAllObserverMappersRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAllObserverMappersRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryAllObserverMappersRequest proto.InternalMessageInfo - -type QueryAllObserverMappersResponse struct { - ObserverMappers []*ObserverMapper `protobuf:"bytes,1,rep,name=observer_mappers,json=observerMappers,proto3" json:"observer_mappers,omitempty"` -} - -func (m *QueryAllObserverMappersResponse) Reset() { *m = QueryAllObserverMappersResponse{} } -func (m *QueryAllObserverMappersResponse) String() string { return proto.CompactTextString(m) } -func (*QueryAllObserverMappersResponse) ProtoMessage() {} -func (*QueryAllObserverMappersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{28} -} -func (m *QueryAllObserverMappersResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryAllObserverMappersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryAllObserverMappersResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryAllObserverMappersResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAllObserverMappersResponse.Merge(m, src) -} -func (m *QueryAllObserverMappersResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryAllObserverMappersResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAllObserverMappersResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryAllObserverMappersResponse proto.InternalMessageInfo - -func (m *QueryAllObserverMappersResponse) GetObserverMappers() []*ObserverMapper { - if m != nil { - return m.ObserverMappers - } - return nil -} - type QuerySupportedChains struct { } @@ -1421,7 +1333,7 @@ func (m *QuerySupportedChains) Reset() { *m = QuerySupportedChains{} } func (m *QuerySupportedChains) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChains) ProtoMessage() {} func (*QuerySupportedChains) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{29} + return fileDescriptor_dcb801e455adaee4, []int{27} } func (m *QuerySupportedChains) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1458,7 +1370,7 @@ func (m *QuerySupportedChainsResponse) Reset() { *m = QuerySupportedChai func (m *QuerySupportedChainsResponse) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChainsResponse) ProtoMessage() {} func (*QuerySupportedChainsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{30} + return fileDescriptor_dcb801e455adaee4, []int{28} } func (m *QuerySupportedChainsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1502,7 +1414,7 @@ func (m *QueryGetCoreParamsForChainRequest) Reset() { *m = QueryGetCoreP func (m *QueryGetCoreParamsForChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsForChainRequest) ProtoMessage() {} func (*QueryGetCoreParamsForChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{31} + return fileDescriptor_dcb801e455adaee4, []int{29} } func (m *QueryGetCoreParamsForChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1546,7 +1458,7 @@ func (m *QueryGetCoreParamsForChainResponse) Reset() { *m = QueryGetCore func (m *QueryGetCoreParamsForChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsForChainResponse) ProtoMessage() {} func (*QueryGetCoreParamsForChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{32} + return fileDescriptor_dcb801e455adaee4, []int{30} } func (m *QueryGetCoreParamsForChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1589,7 +1501,7 @@ func (m *QueryGetCoreParamsRequest) Reset() { *m = QueryGetCoreParamsReq func (m *QueryGetCoreParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsRequest) ProtoMessage() {} func (*QueryGetCoreParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{33} + return fileDescriptor_dcb801e455adaee4, []int{31} } func (m *QueryGetCoreParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1626,7 +1538,7 @@ func (m *QueryGetCoreParamsResponse) Reset() { *m = QueryGetCoreParamsRe func (m *QueryGetCoreParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCoreParamsResponse) ProtoMessage() {} func (*QueryGetCoreParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{34} + return fileDescriptor_dcb801e455adaee4, []int{32} } func (m *QueryGetCoreParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1670,7 +1582,7 @@ func (m *QueryGetNodeAccountRequest) Reset() { *m = QueryGetNodeAccountR func (m *QueryGetNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountRequest) ProtoMessage() {} func (*QueryGetNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{35} + return fileDescriptor_dcb801e455adaee4, []int{33} } func (m *QueryGetNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1714,7 +1626,7 @@ func (m *QueryGetNodeAccountResponse) Reset() { *m = QueryGetNodeAccount func (m *QueryGetNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountResponse) ProtoMessage() {} func (*QueryGetNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{36} + return fileDescriptor_dcb801e455adaee4, []int{34} } func (m *QueryGetNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1758,7 +1670,7 @@ func (m *QueryAllNodeAccountRequest) Reset() { *m = QueryAllNodeAccountR func (m *QueryAllNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountRequest) ProtoMessage() {} func (*QueryAllNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{37} + return fileDescriptor_dcb801e455adaee4, []int{35} } func (m *QueryAllNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1803,7 +1715,7 @@ func (m *QueryAllNodeAccountResponse) Reset() { *m = QueryAllNodeAccount func (m *QueryAllNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountResponse) ProtoMessage() {} func (*QueryAllNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{38} + return fileDescriptor_dcb801e455adaee4, []int{36} } func (m *QueryAllNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1853,7 +1765,7 @@ func (m *QueryGetCrosschainFlagsRequest) Reset() { *m = QueryGetCrosscha func (m *QueryGetCrosschainFlagsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsRequest) ProtoMessage() {} func (*QueryGetCrosschainFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{39} + return fileDescriptor_dcb801e455adaee4, []int{37} } func (m *QueryGetCrosschainFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1890,7 +1802,7 @@ func (m *QueryGetCrosschainFlagsResponse) Reset() { *m = QueryGetCrossch func (m *QueryGetCrosschainFlagsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsResponse) ProtoMessage() {} func (*QueryGetCrosschainFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{40} + return fileDescriptor_dcb801e455adaee4, []int{38} } func (m *QueryGetCrosschainFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1933,7 +1845,7 @@ func (m *QueryGetKeygenRequest) Reset() { *m = QueryGetKeygenRequest{} } func (m *QueryGetKeygenRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenRequest) ProtoMessage() {} func (*QueryGetKeygenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{41} + return fileDescriptor_dcb801e455adaee4, []int{39} } func (m *QueryGetKeygenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1970,7 +1882,7 @@ func (m *QueryGetKeygenResponse) Reset() { *m = QueryGetKeygenResponse{} func (m *QueryGetKeygenResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenResponse) ProtoMessage() {} func (*QueryGetKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{42} + return fileDescriptor_dcb801e455adaee4, []int{40} } func (m *QueryGetKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2013,7 +1925,7 @@ func (m *QueryShowObserverCountRequest) Reset() { *m = QueryShowObserver func (m *QueryShowObserverCountRequest) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountRequest) ProtoMessage() {} func (*QueryShowObserverCountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{43} + return fileDescriptor_dcb801e455adaee4, []int{41} } func (m *QueryShowObserverCountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2050,7 +1962,7 @@ func (m *QueryShowObserverCountResponse) Reset() { *m = QueryShowObserve func (m *QueryShowObserverCountResponse) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountResponse) ProtoMessage() {} func (*QueryShowObserverCountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{44} + return fileDescriptor_dcb801e455adaee4, []int{42} } func (m *QueryShowObserverCountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2094,7 +2006,7 @@ func (m *QueryBlameByIdentifierRequest) Reset() { *m = QueryBlameByIdent func (m *QueryBlameByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierRequest) ProtoMessage() {} func (*QueryBlameByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{45} + return fileDescriptor_dcb801e455adaee4, []int{43} } func (m *QueryBlameByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2138,7 +2050,7 @@ func (m *QueryBlameByIdentifierResponse) Reset() { *m = QueryBlameByIden func (m *QueryBlameByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierResponse) ProtoMessage() {} func (*QueryBlameByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{46} + return fileDescriptor_dcb801e455adaee4, []int{44} } func (m *QueryBlameByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2182,7 +2094,7 @@ func (m *QueryAllBlameRecordsRequest) Reset() { *m = QueryAllBlameRecord func (m *QueryAllBlameRecordsRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsRequest) ProtoMessage() {} func (*QueryAllBlameRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{47} + return fileDescriptor_dcb801e455adaee4, []int{45} } func (m *QueryAllBlameRecordsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2227,7 +2139,7 @@ func (m *QueryAllBlameRecordsResponse) Reset() { *m = QueryAllBlameRecor func (m *QueryAllBlameRecordsResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsResponse) ProtoMessage() {} func (*QueryAllBlameRecordsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{48} + return fileDescriptor_dcb801e455adaee4, []int{46} } func (m *QueryAllBlameRecordsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2279,7 +2191,7 @@ func (m *QueryBlameByChainAndNonceRequest) Reset() { *m = QueryBlameByCh func (m *QueryBlameByChainAndNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceRequest) ProtoMessage() {} func (*QueryBlameByChainAndNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{49} + return fileDescriptor_dcb801e455adaee4, []int{47} } func (m *QueryBlameByChainAndNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2330,7 +2242,7 @@ func (m *QueryBlameByChainAndNonceResponse) Reset() { *m = QueryBlameByC func (m *QueryBlameByChainAndNonceResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceResponse) ProtoMessage() {} func (*QueryBlameByChainAndNonceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{50} + return fileDescriptor_dcb801e455adaee4, []int{48} } func (m *QueryBlameByChainAndNonceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2374,7 +2286,7 @@ func (m *QueryAllBlockHeaderRequest) Reset() { *m = QueryAllBlockHeaderR func (m *QueryAllBlockHeaderRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlockHeaderRequest) ProtoMessage() {} func (*QueryAllBlockHeaderRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{51} + return fileDescriptor_dcb801e455adaee4, []int{49} } func (m *QueryAllBlockHeaderRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2419,7 +2331,7 @@ func (m *QueryAllBlockHeaderResponse) Reset() { *m = QueryAllBlockHeader func (m *QueryAllBlockHeaderResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlockHeaderResponse) ProtoMessage() {} func (*QueryAllBlockHeaderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{52} + return fileDescriptor_dcb801e455adaee4, []int{50} } func (m *QueryAllBlockHeaderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2470,7 +2382,7 @@ func (m *QueryGetBlockHeaderByHashRequest) Reset() { *m = QueryGetBlockH func (m *QueryGetBlockHeaderByHashRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderByHashRequest) ProtoMessage() {} func (*QueryGetBlockHeaderByHashRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{53} + return fileDescriptor_dcb801e455adaee4, []int{51} } func (m *QueryGetBlockHeaderByHashRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2514,7 +2426,7 @@ func (m *QueryGetBlockHeaderByHashResponse) Reset() { *m = QueryGetBlock func (m *QueryGetBlockHeaderByHashResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderByHashResponse) ProtoMessage() {} func (*QueryGetBlockHeaderByHashResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{54} + return fileDescriptor_dcb801e455adaee4, []int{52} } func (m *QueryGetBlockHeaderByHashResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2558,7 +2470,7 @@ func (m *QueryGetBlockHeaderStateRequest) Reset() { *m = QueryGetBlockHe func (m *QueryGetBlockHeaderStateRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderStateRequest) ProtoMessage() {} func (*QueryGetBlockHeaderStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{55} + return fileDescriptor_dcb801e455adaee4, []int{53} } func (m *QueryGetBlockHeaderStateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2602,7 +2514,7 @@ func (m *QueryGetBlockHeaderStateResponse) Reset() { *m = QueryGetBlockH func (m *QueryGetBlockHeaderStateResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetBlockHeaderStateResponse) ProtoMessage() {} func (*QueryGetBlockHeaderStateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dcb801e455adaee4, []int{56} + return fileDescriptor_dcb801e455adaee4, []int{54} } func (m *QueryGetBlockHeaderStateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2664,10 +2576,8 @@ func init() { proto.RegisterType((*QueryBallotByIdentifierRequest)(nil), "zetachain.zetacore.observer.QueryBallotByIdentifierRequest") proto.RegisterType((*VoterList)(nil), "zetachain.zetacore.observer.VoterList") proto.RegisterType((*QueryBallotByIdentifierResponse)(nil), "zetachain.zetacore.observer.QueryBallotByIdentifierResponse") - proto.RegisterType((*QueryObserversByChainRequest)(nil), "zetachain.zetacore.observer.QueryObserversByChainRequest") - proto.RegisterType((*QueryObserversByChainResponse)(nil), "zetachain.zetacore.observer.QueryObserversByChainResponse") - proto.RegisterType((*QueryAllObserverMappersRequest)(nil), "zetachain.zetacore.observer.QueryAllObserverMappersRequest") - proto.RegisterType((*QueryAllObserverMappersResponse)(nil), "zetachain.zetacore.observer.QueryAllObserverMappersResponse") + proto.RegisterType((*QueryObserverSet)(nil), "zetachain.zetacore.observer.QueryObserverSet") + proto.RegisterType((*QueryObserverSetResponse)(nil), "zetachain.zetacore.observer.QueryObserverSetResponse") proto.RegisterType((*QuerySupportedChains)(nil), "zetachain.zetacore.observer.QuerySupportedChains") proto.RegisterType((*QuerySupportedChainsResponse)(nil), "zetachain.zetacore.observer.QuerySupportedChainsResponse") proto.RegisterType((*QueryGetCoreParamsForChainRequest)(nil), "zetachain.zetacore.observer.QueryGetCoreParamsForChainRequest") @@ -2701,170 +2611,164 @@ func init() { func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 2593 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xdd, 0x6f, 0x1c, 0x57, - 0x15, 0xcf, 0xc4, 0xb5, 0x63, 0x1f, 0xdb, 0x89, 0x7d, 0xe3, 0x34, 0xc9, 0x38, 0x71, 0xdc, 0x9b, - 0xa6, 0x49, 0xec, 0x64, 0xb7, 0x71, 0x4a, 0x9b, 0x34, 0x71, 0x5a, 0x6f, 0x48, 0xec, 0x7c, 0x34, - 0x49, 0xd7, 0xa6, 0x45, 0x29, 0xb0, 0xcc, 0xee, 0x5e, 0xef, 0x4e, 0x3b, 0x9e, 0xd9, 0xce, 0x8c, - 0x5d, 0x6f, 0x8d, 0x05, 0xe2, 0xb1, 0xe2, 0xa1, 0x12, 0x12, 0xbc, 0xf6, 0x05, 0xde, 0x40, 0xa8, - 0x12, 0x02, 0x09, 0xf1, 0x00, 0x2f, 0xf4, 0x01, 0xa1, 0x22, 0x24, 0x04, 0x0f, 0xa0, 0x2a, 0x81, - 0xbf, 0x03, 0x34, 0x77, 0xce, 0xcc, 0xdc, 0xf9, 0xd8, 0xd9, 0xbb, 0xee, 0xf6, 0x69, 0x67, 0xee, - 0xbd, 0xe7, 0xdc, 0xdf, 0xef, 0xdc, 0xaf, 0xf3, 0x9b, 0xbd, 0x30, 0x65, 0x55, 0x1d, 0x66, 0x6f, - 0x31, 0xbb, 0xf8, 0xfe, 0x26, 0xb3, 0xdb, 0x85, 0x96, 0x6d, 0xb9, 0x16, 0x99, 0xfe, 0x90, 0xb9, - 0x5a, 0xad, 0xa9, 0xe9, 0x66, 0x81, 0x3f, 0x59, 0x36, 0x2b, 0x04, 0x0d, 0xd5, 0xc3, 0x35, 0x6b, - 0x63, 0xc3, 0x32, 0x8b, 0xfe, 0x8f, 0x6f, 0xa1, 0xce, 0xd5, 0x2c, 0x67, 0xc3, 0x72, 0x8a, 0x55, - 0xcd, 0x61, 0xbe, 0xab, 0xe2, 0xd6, 0xa5, 0x2a, 0x73, 0xb5, 0x4b, 0xc5, 0x96, 0xd6, 0xd0, 0x4d, - 0xcd, 0xd5, 0xc3, 0xb6, 0x53, 0x0d, 0xab, 0x61, 0xf1, 0xc7, 0xa2, 0xf7, 0x84, 0xa5, 0x27, 0x1a, - 0x96, 0xd5, 0x30, 0x58, 0x51, 0x6b, 0xe9, 0x45, 0xcd, 0x34, 0x2d, 0x97, 0x9b, 0x38, 0x58, 0x7b, - 0x24, 0xc4, 0x59, 0xd5, 0x0c, 0xc3, 0x72, 0x03, 0x57, 0x51, 0xb1, 0xa1, 0x6d, 0x30, 0x2c, 0x9d, - 0x16, 0x4a, 0xad, 0xda, 0x7b, 0x95, 0x26, 0xd3, 0xea, 0xcc, 0x4e, 0x55, 0x72, 0x82, 0x15, 0xd3, - 0x32, 0x6b, 0x2c, 0xe8, 0xe6, 0x54, 0x54, 0x69, 0x5b, 0x8e, 0xe3, 0xb7, 0x58, 0x37, 0xb4, 0x46, - 0x1a, 0xc7, 0x7b, 0xac, 0xdd, 0x60, 0x66, 0xca, 0xa9, 0x69, 0xd5, 0x59, 0x45, 0xab, 0xd5, 0xac, - 0x4d, 0x33, 0x00, 0x79, 0x34, 0xac, 0x0c, 0x1e, 0x52, 0xce, 0x5a, 0x9a, 0xad, 0x6d, 0x04, 0x7d, - 0x9c, 0x8c, 0x8a, 0x99, 0x59, 0xd7, 0xcd, 0x46, 0x1c, 0x23, 0x09, 0xab, 0x5d, 0x07, 0xcb, 0xe8, - 0x02, 0xa8, 0x6f, 0x7a, 0x41, 0x5f, 0x66, 0xee, 0x4d, 0x0f, 0xf3, 0x03, 0x6e, 0x50, 0x66, 0xef, - 0x6f, 0x32, 0xc7, 0x25, 0x53, 0x30, 0xa8, 0x9b, 0x75, 0xb6, 0x7d, 0x4c, 0x99, 0x55, 0xce, 0x8d, - 0x94, 0xfd, 0x17, 0x6a, 0xc1, 0x74, 0xa6, 0x8d, 0xd3, 0xb2, 0x4c, 0x87, 0x91, 0x47, 0x30, 0x2a, - 0x14, 0x73, 0xd3, 0xd1, 0x85, 0x73, 0x85, 0x9c, 0x99, 0x51, 0x10, 0xda, 0x97, 0x9e, 0xf9, 0xec, - 0xdf, 0xa7, 0xf6, 0x95, 0x45, 0x17, 0xb4, 0x8e, 0x20, 0x97, 0x0c, 0x23, 0x03, 0xe4, 0x6d, 0x80, - 0x68, 0xa6, 0x60, 0x77, 0x2f, 0x14, 0xfc, 0x69, 0x55, 0xf0, 0xa6, 0x55, 0xc1, 0x9f, 0xa1, 0x38, - 0xad, 0x0a, 0x8f, 0xb4, 0x06, 0x43, 0xdb, 0xb2, 0x60, 0x49, 0x7f, 0xab, 0x20, 0xaf, 0x64, 0x37, - 0x9d, 0x78, 0x0d, 0x7c, 0x49, 0x5e, 0x64, 0x39, 0x86, 0x7c, 0x3f, 0x47, 0x7e, 0xb6, 0x2b, 0x72, - 0x1f, 0x4e, 0x0c, 0xfa, 0x3a, 0x9c, 0x08, 0x90, 0x3f, 0xf2, 0x47, 0xfe, 0xab, 0x09, 0xd1, 0x1f, - 0x14, 0x38, 0xd9, 0xa1, 0x23, 0x0c, 0xd2, 0xdb, 0x70, 0x30, 0x3e, 0xf7, 0x30, 0x4e, 0x73, 0xb9, - 0x71, 0x8a, 0xf9, 0xc2, 0x48, 0x8d, 0xb7, 0xc4, 0xc2, 0xfe, 0xc5, 0x6a, 0x11, 0x66, 0x39, 0x85, - 0x78, 0x9f, 0x6d, 0x3e, 0x2e, 0x41, 0xbc, 0x8e, 0xc3, 0xb0, 0xbf, 0x82, 0xf5, 0x3a, 0x8f, 0xd6, - 0x40, 0xf9, 0x00, 0x7f, 0xbf, 0x53, 0xa7, 0xdf, 0x83, 0xe7, 0x72, 0xcc, 0x73, 0xa2, 0xa0, 0xf4, - 0x21, 0x0a, 0x74, 0x0a, 0x48, 0xb0, 0xf4, 0xd6, 0x56, 0x57, 0x11, 0x2e, 0x7d, 0x08, 0x87, 0x63, - 0xa5, 0x88, 0xe2, 0x0a, 0x0c, 0xac, 0xad, 0xae, 0x62, 0xd7, 0xb3, 0xb9, 0x5d, 0xaf, 0xad, 0xae, - 0x62, 0x87, 0x9e, 0x09, 0xbd, 0x05, 0xc7, 0x43, 0x87, 0x8e, 0xb3, 0x54, 0xaf, 0xdb, 0xcc, 0x09, - 0x27, 0xd3, 0x39, 0x98, 0xa8, 0xea, 0x6e, 0xcd, 0xd2, 0xcd, 0x4a, 0x18, 0xa4, 0xfd, 0x3c, 0x48, - 0x07, 0xb1, 0xfc, 0x26, 0xc6, 0xea, 0xf5, 0x68, 0x73, 0x11, 0xdd, 0x20, 0xbc, 0x09, 0x18, 0x60, - 0x6e, 0x13, 0xb7, 0x16, 0xef, 0xd1, 0x2b, 0xa9, 0xba, 0x35, 0xee, 0x6c, 0xa4, 0xec, 0x3d, 0xd2, - 0x8f, 0x14, 0x98, 0x4b, 0xbb, 0x28, 0xb5, 0x6f, 0xeb, 0xa6, 0x66, 0xe8, 0x1f, 0xb2, 0xfa, 0x0a, - 0xd3, 0x1b, 0x4d, 0x37, 0x80, 0xb6, 0x00, 0x47, 0xd6, 0x83, 0x9a, 0x8a, 0xc7, 0xb2, 0xd2, 0xe4, - 0xf5, 0x38, 0x88, 0x87, 0xc3, 0xca, 0xc7, 0xcc, 0xd5, 0x7c, 0xd3, 0x1e, 0xe8, 0xbc, 0x09, 0xf3, - 0x52, 0x58, 0x7a, 0xe0, 0xf7, 0x5d, 0x78, 0x96, 0xbb, 0x5c, 0x73, 0x9c, 0x15, 0xdd, 0x71, 0x2d, - 0xbb, 0xdd, 0xef, 0x25, 0xfb, 0x33, 0x05, 0x8e, 0xa6, 0xba, 0x40, 0x84, 0x4b, 0x30, 0xec, 0x3a, - 0x4e, 0xc5, 0xd0, 0x1d, 0x17, 0x97, 0xa9, 0xec, 0x2c, 0x39, 0xe0, 0x3a, 0xce, 0x7d, 0xdd, 0x71, - 0xfb, 0xb7, 0x2c, 0x7f, 0xae, 0xc0, 0xa4, 0xbf, 0xb0, 0x6c, 0x6b, 0x8b, 0x75, 0x5f, 0x88, 0xe4, - 0x28, 0x1c, 0x70, 0xb7, 0x2b, 0x4d, 0xcd, 0x69, 0x62, 0x40, 0x87, 0xdc, 0xed, 0x15, 0xcd, 0x69, - 0x92, 0xd3, 0x30, 0xd8, 0xb2, 0x2d, 0x6b, 0xfd, 0xd8, 0x00, 0x47, 0x33, 0x5e, 0xc0, 0x7c, 0xe3, - 0x91, 0x57, 0x58, 0xf6, 0xeb, 0xc8, 0x49, 0x00, 0x3c, 0xe2, 0x3d, 0x07, 0xcf, 0x70, 0x07, 0x23, - 0xbc, 0x84, 0xfb, 0x38, 0x0e, 0xc3, 0xee, 0x76, 0xc5, 0x3f, 0xfb, 0x06, 0xfd, 0x7e, 0xdd, 0xed, - 0x3b, 0xfc, 0xf4, 0x9b, 0xc3, 0x25, 0x88, 0x38, 0x31, 0x94, 0x53, 0x30, 0xb8, 0xa5, 0x19, 0x88, - 0x72, 0xb8, 0xec, 0xbf, 0x84, 0xcb, 0xf5, 0x11, 0x3f, 0xa5, 0x83, 0xe5, 0xfa, 0x4d, 0x5c, 0xae, - 0x41, 0x69, 0x38, 0x1a, 0x43, 0xfe, 0x69, 0x8e, 0xa3, 0x7d, 0x3a, 0x7f, 0xb3, 0xe0, 0x4d, 0x71, - 0x38, 0xd0, 0x90, 0x36, 0x61, 0x8a, 0x7b, 0x5e, 0xd1, 0x9c, 0xb7, 0x2c, 0x97, 0xd5, 0x83, 0x30, - 0xce, 0xc3, 0xa4, 0x9f, 0xfd, 0x54, 0xf4, 0x3a, 0x33, 0x5d, 0x7d, 0x5d, 0x67, 0x36, 0x4e, 0xcc, - 0x09, 0xbf, 0xe2, 0x4e, 0x58, 0x4e, 0x4e, 0xc3, 0xf8, 0x96, 0xe5, 0x32, 0xbb, 0xa2, 0xf9, 0x33, - 0x1c, 0xc3, 0x3b, 0xc6, 0x0b, 0x71, 0xd6, 0xd3, 0x97, 0xe0, 0x48, 0xa2, 0x27, 0x64, 0x31, 0x0d, - 0x23, 0x4d, 0xcd, 0xa9, 0x78, 0x8d, 0x83, 0x60, 0x0c, 0x37, 0xb1, 0x11, 0x7d, 0x03, 0x66, 0xb8, - 0x55, 0x89, 0xf7, 0x59, 0x6a, 0x47, 0xbd, 0xee, 0x05, 0x29, 0x75, 0x61, 0xc4, 0xf3, 0x6b, 0xf3, - 0x99, 0x98, 0x82, 0xad, 0xa4, 0x61, 0x93, 0x12, 0x8c, 0x78, 0xef, 0x15, 0xb7, 0xdd, 0x62, 0x9c, - 0xd7, 0xc1, 0x85, 0x33, 0xb9, 0x61, 0xf6, 0xfc, 0xaf, 0xb5, 0x5b, 0xac, 0x3c, 0xbc, 0x85, 0x4f, - 0xf4, 0x37, 0xfb, 0xe1, 0x54, 0x47, 0x16, 0x18, 0x85, 0x9e, 0x02, 0x7e, 0x03, 0x86, 0x38, 0x48, - 0x2f, 0xd2, 0x03, 0x7c, 0x99, 0x77, 0x43, 0xc4, 0x19, 0x97, 0xd1, 0x8a, 0xbc, 0x0d, 0x13, 0x7e, - 0x2d, 0x5f, 0x49, 0x3e, 0xb7, 0x01, 0xce, 0xed, 0x42, 0xae, 0xa7, 0x87, 0x91, 0x11, 0xa7, 0x78, - 0xc8, 0x8a, 0x17, 0x90, 0x07, 0x30, 0x8e, 0x2c, 0x1c, 0x57, 0x73, 0x37, 0x1d, 0xbe, 0x4e, 0x0e, - 0x2e, 0x9c, 0xcf, 0xf5, 0xea, 0x47, 0x65, 0x95, 0x1b, 0x94, 0xc7, 0xaa, 0xc2, 0x1b, 0xbd, 0x87, - 0x69, 0xca, 0x43, 0x6c, 0x9b, 0x3c, 0x76, 0xe7, 0x61, 0x52, 0x24, 0xc2, 0x7b, 0x08, 0xa2, 0x26, - 0x54, 0x70, 0x1b, 0xba, 0x88, 0xa9, 0x48, 0xda, 0x19, 0x8e, 0xc1, 0x09, 0x18, 0x09, 0x40, 0xf9, - 0x59, 0xc8, 0x48, 0x39, 0x2a, 0xa0, 0xb3, 0x38, 0x15, 0x97, 0x0c, 0x23, 0xf0, 0xf0, 0x86, 0xd6, - 0x6a, 0x31, 0x3b, 0x5c, 0xa6, 0x6d, 0x1c, 0xe6, 0xac, 0x16, 0xd8, 0xc5, 0x5b, 0x41, 0xe4, 0x99, - 0x5d, 0xd9, 0xf0, 0xeb, 0x70, 0x23, 0x9d, 0x97, 0x88, 0x7c, 0xe0, 0x2f, 0x08, 0x7c, 0xe8, 0x9f, - 0x3e, 0x8b, 0xeb, 0x78, 0x75, 0xb3, 0xd5, 0xb2, 0x6c, 0x97, 0xd5, 0x39, 0x33, 0x87, 0xde, 0xc2, - 0x00, 0x26, 0xca, 0x43, 0x3c, 0x67, 0x60, 0x88, 0x77, 0x19, 0xa0, 0x08, 0xf7, 0x3e, 0x3f, 0x32, - 0x58, 0x49, 0x6f, 0x60, 0x0e, 0xe3, 0x25, 0xf0, 0x96, 0xcd, 0xfc, 0xad, 0xe4, 0xb6, 0x65, 0xcb, - 0xe6, 0x40, 0x26, 0xd0, 0x3c, 0x7b, 0x04, 0xb3, 0x02, 0xa3, 0x1e, 0xeb, 0x4a, 0x6c, 0x53, 0x3b, - 0x9b, 0x9f, 0x2f, 0x87, 0xde, 0xca, 0x50, 0x0b, 0x9f, 0xe9, 0x74, 0x94, 0x8e, 0x08, 0x2d, 0x70, - 0x98, 0xde, 0x15, 0x14, 0x8c, 0x50, 0x89, 0x20, 0xee, 0x67, 0x81, 0x98, 0x97, 0x04, 0xc1, 0x57, - 0x99, 0x08, 0x44, 0x50, 0x4b, 0x0f, 0xac, 0x3a, 0x5b, 0xf2, 0xd5, 0x5a, 0xbe, 0x5a, 0x7a, 0x37, - 0x52, 0x4b, 0x31, 0x1b, 0x04, 0x78, 0x0f, 0xc6, 0x44, 0xe5, 0x27, 0x25, 0x97, 0x44, 0x3f, 0xa3, - 0x66, 0xf4, 0x22, 0x0a, 0xa5, 0x0c, 0x7c, 0xfd, 0x4a, 0x29, 0x3e, 0x15, 0x84, 0x52, 0x16, 0xa5, - 0xbb, 0x30, 0x2a, 0x14, 0x4b, 0x09, 0xa5, 0x18, 0x23, 0xe1, 0xa5, 0x7f, 0xf9, 0x45, 0xb0, 0xde, - 0xbd, 0x69, 0x12, 0x2a, 0xf4, 0xdb, 0x9e, 0x40, 0x0f, 0x26, 0xd2, 0x0f, 0x14, 0x5c, 0xf0, 0x59, - 0x4d, 0x90, 0xda, 0xb7, 0x61, 0x22, 0xa9, 0xef, 0x31, 0x90, 0xf9, 0x5b, 0x6d, 0xc2, 0x1f, 0x1e, - 0xdb, 0x87, 0x6a, 0xf1, 0x62, 0x7a, 0x14, 0x4f, 0xd5, 0x65, 0xe6, 0xde, 0xe3, 0x5f, 0x09, 0x02, - 0x6c, 0xdf, 0xc0, 0x3c, 0x51, 0xa8, 0x40, 0x44, 0xd7, 0x60, 0xc8, 0xff, 0xa0, 0x20, 0x95, 0x35, - 0xa0, 0x31, 0x9a, 0xd0, 0x53, 0xb8, 0x87, 0xae, 0x36, 0xad, 0x0f, 0x82, 0x3d, 0xe9, 0xa6, 0x30, - 0x65, 0xbc, 0x98, 0xcc, 0x74, 0x6a, 0x81, 0x00, 0xbe, 0x03, 0x87, 0x0d, 0xcd, 0x71, 0x2b, 0xe1, - 0x46, 0x28, 0xce, 0xe3, 0x42, 0x2e, 0x9a, 0xfb, 0x9a, 0xe3, 0xc6, 0x9d, 0x4e, 0x1a, 0xc9, 0x22, - 0x7a, 0x17, 0x31, 0x96, 0x0c, 0x6d, 0x83, 0x65, 0xa5, 0x0c, 0xe7, 0x61, 0x82, 0x7f, 0xc3, 0x49, - 0x1f, 0xb5, 0x87, 0x78, 0xb9, 0x90, 0x30, 0xd4, 0x82, 0xfc, 0x23, 0xed, 0x2b, 0x4c, 0xc2, 0x00, - 0x9d, 0x99, 0xeb, 0x16, 0x92, 0xa0, 0xf9, 0xe7, 0x9d, 0xd7, 0xdc, 0xcb, 0x1d, 0xbd, 0xae, 0xcc, - 0x75, 0x8b, 0xb2, 0x68, 0x75, 0xf8, 0x75, 0xac, 0x66, 0xd9, 0xf5, 0xbe, 0x6b, 0xf1, 0x5f, 0x29, - 0x91, 0xe8, 0x8f, 0xf7, 0x83, 0x54, 0x96, 0x13, 0x54, 0x06, 0xe4, 0xa8, 0xe0, 0xdc, 0x8c, 0x08, - 0xf5, 0x6f, 0x0d, 0xae, 0xa2, 0xf4, 0xc6, 0xf0, 0xf3, 0xe3, 0x62, 0xc9, 0xac, 0x73, 0x6d, 0x2b, - 0x91, 0xf1, 0x4f, 0xc1, 0x20, 0x57, 0xd3, 0x28, 0xcf, 0xfc, 0x17, 0xba, 0x8e, 0x87, 0x59, 0xb6, - 0xd3, 0x0e, 0xc3, 0x3a, 0xd0, 0xfb, 0xb0, 0x0a, 0x7b, 0x6b, 0x89, 0xeb, 0x04, 0xfe, 0x6d, 0xb0, - 0xdf, 0xa3, 0xfa, 0x89, 0x22, 0xce, 0x1e, 0xa1, 0x9b, 0x50, 0xd3, 0x8f, 0x8b, 0x9f, 0x26, 0x83, - 0x83, 0xfe, 0x70, 0x70, 0xd0, 0x8b, 0x36, 0x63, 0xd5, 0xe8, 0xa5, 0x8f, 0x1f, 0x50, 0x96, 0x70, - 0x14, 0x97, 0x99, 0x2b, 0xf4, 0x56, 0xf2, 0xa4, 0x40, 0x33, 0x08, 0x47, 0x5c, 0x5e, 0x79, 0xe1, - 0x18, 0x13, 0xe4, 0x15, 0x7d, 0x27, 0x4a, 0x40, 0x32, 0x5c, 0x20, 0xd5, 0x97, 0x61, 0x4c, 0xa4, - 0x8a, 0x41, 0xcd, 0x64, 0x3a, 0x2a, 0x30, 0xa5, 0xd7, 0xa3, 0x6d, 0x5c, 0x68, 0xe3, 0xa5, 0xa0, - 0x12, 0x93, 0x8c, 0x7e, 0x3f, 0x93, 0x1d, 0x5a, 0x23, 0xb2, 0x77, 0x80, 0x88, 0xc8, 0x78, 0x76, - 0xcc, 0x10, 0xdf, 0xc5, 0x2e, 0xb3, 0x2a, 0xe1, 0x72, 0xa2, 0x9a, 0x28, 0x59, 0xf8, 0xdf, 0x79, - 0x18, 0xe4, 0x08, 0xc8, 0xc7, 0x0a, 0x0c, 0xf9, 0x89, 0x07, 0x29, 0xe6, 0x7a, 0x4d, 0x6b, 0x4c, - 0xf5, 0x45, 0x79, 0x03, 0x9f, 0x14, 0x3d, 0xfd, 0xc3, 0xbf, 0xfd, 0xe7, 0xc7, 0xfb, 0x4f, 0x92, - 0xe9, 0xa2, 0xd7, 0xfe, 0x22, 0x37, 0x2d, 0x26, 0xbe, 0x33, 0x93, 0xdf, 0x2b, 0x30, 0x1c, 0x48, - 0x3e, 0x72, 0xa9, 0x7b, 0x1f, 0x09, 0x21, 0xaa, 0x2e, 0xf4, 0x62, 0x82, 0xc0, 0xee, 0x72, 0x60, - 0x5f, 0x27, 0xa5, 0x4c, 0x60, 0xa1, 0xd8, 0x2c, 0xee, 0xa4, 0x14, 0xd7, 0x6e, 0x71, 0x27, 0x26, - 0x09, 0x77, 0xc9, 0xdf, 0x15, 0x20, 0x69, 0xd9, 0x46, 0xae, 0x75, 0x87, 0xd5, 0x51, 0xb2, 0xaa, - 0xd7, 0xf7, 0x66, 0x8c, 0xec, 0x6e, 0x71, 0x76, 0xaf, 0x91, 0xc5, 0x4c, 0x76, 0x48, 0xa9, 0xda, - 0x16, 0x58, 0x65, 0x11, 0x25, 0x7f, 0x51, 0x60, 0x22, 0xa9, 0x84, 0xc8, 0xd5, 0xee, 0xc8, 0x3a, - 0x48, 0x31, 0xf5, 0xd5, 0xbd, 0x98, 0x22, 0xa5, 0x9b, 0x9c, 0xd2, 0x22, 0xb9, 0x96, 0x49, 0x29, - 0x94, 0x60, 0x1e, 0x2b, 0xbf, 0x6e, 0x27, 0xa5, 0xfa, 0x76, 0xc9, 0x1f, 0x15, 0x20, 0x69, 0xe5, - 0x25, 0x33, 0x52, 0x1d, 0x15, 0x9d, 0xcc, 0x48, 0x75, 0x16, 0x7b, 0xf4, 0x12, 0xa7, 0x35, 0x4f, - 0xce, 0x67, 0xd2, 0xd2, 0x0c, 0xa3, 0x92, 0xd4, 0x82, 0xe4, 0x17, 0x0a, 0x1c, 0x4a, 0x68, 0x35, - 0x99, 0x55, 0x93, 0x30, 0x51, 0xaf, 0xf6, 0x6c, 0x12, 0x82, 0xbe, 0xc0, 0x41, 0xbf, 0x40, 0x9e, - 0xcf, 0x04, 0xed, 0x24, 0xb0, 0xfd, 0x4b, 0x81, 0x23, 0x99, 0xa2, 0x8e, 0xdc, 0xe8, 0x0e, 0x21, - 0x4f, 0x4d, 0xaa, 0xaf, 0xed, 0xd9, 0x5e, 0x6a, 0x52, 0x35, 0x98, 0x5b, 0xa9, 0x19, 0x3a, 0x33, - 0x5d, 0x54, 0x7a, 0x95, 0x75, 0xcb, 0x0e, 0x66, 0x57, 0xb0, 0xd5, 0xef, 0x92, 0x5f, 0x2a, 0x30, - 0x1e, 0xeb, 0x86, 0xbc, 0xdc, 0x23, 0xae, 0x80, 0xcf, 0x2b, 0x3d, 0xdb, 0x49, 0x0d, 0x08, 0xe7, - 0x11, 0xe9, 0x55, 0xf2, 0xa9, 0x12, 0xd3, 0x52, 0x44, 0xae, 0xdb, 0xb4, 0xf6, 0x53, 0xaf, 0xf4, - 0x6e, 0x88, 0x80, 0x5f, 0xe4, 0x80, 0xe7, 0xc8, 0xb9, 0x4c, 0xc0, 0x82, 0xfa, 0x2c, 0xee, 0x70, - 0xc1, 0xbb, 0xeb, 0xcd, 0xfa, 0x83, 0x82, 0xa7, 0x25, 0xc3, 0x90, 0xc1, 0x9d, 0xa9, 0x59, 0x65, - 0x70, 0x67, 0xab, 0x50, 0x7a, 0x8e, 0xe3, 0xa6, 0x64, 0xb6, 0x1b, 0x6e, 0xf2, 0x3b, 0x05, 0x0e, - 0x25, 0x04, 0x9a, 0xcc, 0x3e, 0xd3, 0x51, 0x49, 0xca, 0xec, 0x33, 0x9d, 0x35, 0x26, 0xbd, 0xc8, - 0x81, 0x9f, 0x25, 0x67, 0x32, 0x81, 0x27, 0xe5, 0x27, 0xf9, 0x89, 0x02, 0x43, 0xbe, 0xac, 0x23, - 0x0b, 0x52, 0xfd, 0xc6, 0x94, 0xa5, 0x7a, 0xb9, 0x27, 0x1b, 0xa9, 0x5c, 0xc1, 0x17, 0x97, 0xe4, - 0x4f, 0x0a, 0x4c, 0xa6, 0x64, 0x23, 0x91, 0x38, 0x58, 0x3a, 0xa9, 0x51, 0xf5, 0xda, 0x9e, 0x6c, - 0x11, 0xf3, 0x55, 0x8e, 0xf9, 0x32, 0xb9, 0x24, 0x62, 0x0e, 0xbc, 0x08, 0x5b, 0x62, 0xd3, 0xfa, - 0x20, 0xa1, 0x65, 0xc9, 0x5f, 0x15, 0x98, 0x4c, 0x49, 0x46, 0x19, 0x26, 0x9d, 0x34, 0xab, 0x0c, - 0x93, 0x8e, 0x1a, 0xb5, 0xcb, 0x56, 0xe8, 0xeb, 0x9c, 0x64, 0xc6, 0x90, 0x10, 0xc8, 0xbb, 0x5e, - 0x26, 0x47, 0x96, 0x99, 0x9b, 0x10, 0x8f, 0x44, 0x6e, 0xbd, 0x65, 0xe8, 0x5a, 0x99, 0x43, 0xaa, - 0x83, 0x52, 0xa5, 0x0b, 0x9c, 0xd0, 0x05, 0x32, 0xd7, 0x71, 0x4f, 0xf4, 0x4e, 0x57, 0x9f, 0x83, - 0x8d, 0x40, 0xbf, 0x50, 0xe0, 0x08, 0x77, 0xe6, 0x24, 0x34, 0x1f, 0x59, 0x94, 0x8e, 0x6d, 0x96, - 0x00, 0x55, 0x6f, 0xec, 0xd5, 0x1c, 0xc9, 0xac, 0x70, 0x32, 0x25, 0xf2, 0x7a, 0xfe, 0xe8, 0xf8, - 0x4b, 0x58, 0x33, 0xeb, 0xfe, 0x3f, 0xc4, 0xc2, 0x29, 0x55, 0xdc, 0xe1, 0x25, 0xbb, 0xde, 0xbe, - 0x14, 0x0e, 0x91, 0x20, 0xe4, 0x5e, 0x91, 0x0c, 0x74, 0x52, 0xa3, 0xaa, 0x57, 0x7a, 0x37, 0xec, - 0x71, 0x80, 0x04, 0x61, 0x4a, 0xfe, 0xa9, 0xc0, 0x54, 0x96, 0xbe, 0x93, 0x19, 0x9f, 0x1c, 0x69, - 0xa9, 0xde, 0xd8, 0xab, 0x39, 0x72, 0x29, 0x71, 0x2e, 0xd7, 0xc9, 0xab, 0x1d, 0xb9, 0xc4, 0xb4, - 0x5d, 0xb5, 0xcd, 0x35, 0xac, 0xb7, 0x84, 0x02, 0x3d, 0xbb, 0x4b, 0xfe, 0xab, 0x80, 0x9a, 0x21, - 0x10, 0x83, 0xbc, 0xfb, 0x7a, 0xaf, 0x10, 0x45, 0x71, 0xaa, 0x2e, 0xee, 0xd1, 0x5a, 0x4a, 0x2e, - 0xa5, 0xf8, 0x71, 0xed, 0x1a, 0x4d, 0x48, 0xbd, 0x2e, 0xe6, 0x4b, 0x3f, 0x52, 0x60, 0x90, 0xff, - 0xcf, 0x49, 0x0a, 0x12, 0x7a, 0x52, 0xf8, 0xe3, 0x56, 0x2d, 0x4a, 0xb7, 0x47, 0xd8, 0x94, 0xc3, - 0x3e, 0x41, 0xd4, 0x6c, 0xf9, 0xc9, 0x41, 0x60, 0xfa, 0x16, 0xfd, 0xf9, 0x2e, 0x99, 0xbe, 0xa5, - 0xee, 0x30, 0x48, 0xa6, 0x6f, 0xe9, 0x4b, 0x0b, 0x12, 0xe9, 0x9b, 0xeb, 0x38, 0x81, 0xde, 0x24, - 0x3f, 0xdd, 0x0f, 0x33, 0xf9, 0xb7, 0x05, 0xc8, 0x72, 0x8f, 0x48, 0x3a, 0xdd, 0x7d, 0x50, 0x57, - 0xbe, 0xbc, 0x23, 0xe4, 0x58, 0xe5, 0x1c, 0xbf, 0x45, 0x1e, 0xcb, 0x70, 0xac, 0x34, 0xf9, 0xa5, - 0x02, 0xbd, 0xa6, 0x19, 0xc5, 0x9d, 0xcc, 0xcb, 0x17, 0xbb, 0xc5, 0x9d, 0xe4, 0x05, 0x8b, 0x5d, - 0xf2, 0x91, 0xc2, 0x2f, 0xa7, 0xc8, 0x7c, 0xd8, 0x88, 0xdd, 0x75, 0x91, 0xf9, 0xb0, 0x11, 0xbf, - 0x06, 0x43, 0x67, 0x39, 0x1d, 0x95, 0x1c, 0xcb, 0xa4, 0xe3, 0x81, 0xf8, 0x44, 0x01, 0x88, 0xae, - 0x47, 0x10, 0x89, 0x94, 0x28, 0x75, 0x5f, 0x43, 0x7d, 0xa9, 0x37, 0x23, 0xc4, 0x76, 0x96, 0x63, - 0x7b, 0x8e, 0x9c, 0xca, 0xc4, 0xe6, 0x46, 0x98, 0x7e, 0xad, 0xc0, 0x44, 0xec, 0x7e, 0x90, 0x97, - 0x55, 0xcb, 0x1d, 0xb9, 0x59, 0x37, 0xc2, 0x64, 0xf4, 0x7d, 0xa7, 0x3b, 0x5e, 0x74, 0x8e, 0x83, - 0x7e, 0x9e, 0xd0, 0xec, 0xa5, 0x1a, 0xbb, 0xb6, 0xf5, 0x67, 0x05, 0xa6, 0xb2, 0xae, 0x4a, 0xc9, - 0x9c, 0x02, 0x39, 0x37, 0xb4, 0x64, 0x4e, 0x81, 0xbc, 0x1b, 0x5a, 0xf4, 0x6b, 0x9c, 0x43, 0x91, - 0x5c, 0xec, 0xce, 0x41, 0xdc, 0x10, 0x3d, 0x3d, 0x26, 0xde, 0xe0, 0x93, 0x94, 0x81, 0xa9, 0x4b, - 0x8b, 0x92, 0x7a, 0x2c, 0xe3, 0x1a, 0x62, 0x17, 0x3d, 0x56, 0x8b, 0x2c, 0x62, 0x7a, 0x4c, 0xf0, - 0x24, 0xaf, 0xc7, 0xf6, 0x86, 0x3b, 0xfb, 0xfa, 0x64, 0x17, 0x3d, 0x26, 0xe0, 0x2e, 0xdd, 0xf9, - 0xec, 0xc9, 0x8c, 0xf2, 0xf9, 0x93, 0x19, 0xe5, 0x8b, 0x27, 0x33, 0xca, 0xc7, 0x4f, 0x67, 0xf6, - 0x7d, 0xfe, 0x74, 0x66, 0xdf, 0x3f, 0x9e, 0xce, 0xec, 0x7b, 0x5c, 0x6c, 0xe8, 0x6e, 0x73, 0xb3, - 0x5a, 0xa8, 0x59, 0x1b, 0x99, 0x59, 0xfc, 0xb6, 0xb0, 0x76, 0xda, 0x2d, 0xe6, 0x54, 0x87, 0xf8, - 0x2d, 0xd7, 0xcb, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x98, 0x37, 0x26, 0xae, 0x2c, 0x00, - 0x00, + // 2512 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x6f, 0xdc, 0xc6, + 0x15, 0x37, 0xad, 0x48, 0x91, 0x9e, 0x24, 0x5b, 0x1e, 0xcb, 0xb1, 0x4d, 0xd9, 0xb2, 0x4c, 0xc7, + 0xb1, 0x2c, 0xdb, 0xcb, 0x58, 0xce, 0x87, 0xe3, 0xaf, 0x44, 0xeb, 0xda, 0x92, 0x1d, 0xd7, 0x76, + 0x76, 0xdd, 0xa6, 0x70, 0xda, 0xb2, 0xdc, 0xdd, 0xd1, 0x2e, 0x93, 0x15, 0xb9, 0x21, 0x47, 0x8a, + 0x36, 0xaa, 0xd0, 0xa2, 0x47, 0xa3, 0x87, 0x00, 0x05, 0xda, 0x5b, 0x91, 0x4b, 0x7b, 0x6b, 0x51, + 0x04, 0x28, 0x5a, 0xa0, 0xe8, 0xa1, 0xa7, 0xe6, 0xd0, 0x43, 0x8a, 0x02, 0x45, 0x7b, 0x68, 0x11, + 0xd8, 0xed, 0xff, 0x51, 0x70, 0xf8, 0x48, 0x0e, 0x3f, 0x96, 0x3b, 0xab, 0xa8, 0x27, 0x2d, 0x67, + 0xe6, 0xbd, 0xf9, 0xfd, 0xde, 0x7c, 0xbc, 0xf7, 0x13, 0x09, 0xd3, 0x4e, 0xcd, 0xa3, 0xee, 0x06, + 0x75, 0xf5, 0x0f, 0xd7, 0xa9, 0xdb, 0x2d, 0x75, 0x5c, 0x87, 0x39, 0x64, 0xe6, 0x63, 0xca, 0xcc, + 0x7a, 0xcb, 0xb4, 0xec, 0x12, 0xff, 0xe5, 0xb8, 0xb4, 0x14, 0x0e, 0x54, 0x0f, 0xd6, 0x9d, 0xb5, + 0x35, 0xc7, 0xd6, 0x83, 0x3f, 0x81, 0x85, 0xba, 0x50, 0x77, 0xbc, 0x35, 0xc7, 0xd3, 0x6b, 0xa6, + 0x47, 0x03, 0x57, 0xfa, 0xc6, 0xc5, 0x1a, 0x65, 0xe6, 0x45, 0xbd, 0x63, 0x36, 0x2d, 0xdb, 0x64, + 0x56, 0x34, 0x76, 0xba, 0xe9, 0x34, 0x1d, 0xfe, 0x53, 0xf7, 0x7f, 0x61, 0xeb, 0xb1, 0xa6, 0xe3, + 0x34, 0xdb, 0x54, 0x37, 0x3b, 0x96, 0x6e, 0xda, 0xb6, 0xc3, 0xb8, 0x89, 0x87, 0xbd, 0x87, 0x22, + 0x9c, 0x35, 0xb3, 0xdd, 0x76, 0x58, 0xe8, 0x2a, 0x6e, 0x6e, 0x9b, 0x6b, 0x14, 0x5b, 0x67, 0x84, + 0x56, 0xa7, 0xfe, 0x81, 0xd1, 0xa2, 0x66, 0x83, 0xba, 0x99, 0x4e, 0x4e, 0xd0, 0xb0, 0x1d, 0xbb, + 0x4e, 0xc3, 0x69, 0x4e, 0xc4, 0x9d, 0xae, 0xe3, 0x79, 0xc1, 0x88, 0xd5, 0xb6, 0xd9, 0xcc, 0xe2, + 0xf8, 0x80, 0x76, 0x9b, 0xd4, 0xce, 0x38, 0xb5, 0x9d, 0x06, 0x35, 0xcc, 0x7a, 0xdd, 0x59, 0xb7, + 0x43, 0x90, 0x87, 0xa3, 0xce, 0xf0, 0x47, 0xc6, 0x59, 0xc7, 0x74, 0xcd, 0xb5, 0x70, 0x8e, 0xe3, + 0x71, 0x33, 0xb5, 0x1b, 0x96, 0xdd, 0x4c, 0x62, 0x24, 0x51, 0x37, 0xf3, 0xb0, 0x4d, 0x5b, 0x04, + 0xf5, 0x1d, 0x3f, 0xe8, 0xcb, 0x94, 0xdd, 0xf4, 0x31, 0xdf, 0xe7, 0x06, 0x15, 0xfa, 0xe1, 0x3a, + 0xf5, 0x18, 0x99, 0x86, 0x61, 0xcb, 0x6e, 0xd0, 0xcd, 0x23, 0xca, 0x9c, 0x32, 0x3f, 0x56, 0x09, + 0x1e, 0x34, 0x07, 0x66, 0x72, 0x6d, 0xbc, 0x8e, 0x63, 0x7b, 0x94, 0x3c, 0x84, 0x71, 0xa1, 0x99, + 0x9b, 0x8e, 0x2f, 0xce, 0x97, 0x0a, 0x76, 0x46, 0x49, 0x18, 0x5f, 0x7e, 0xee, 0xf3, 0x7f, 0x9f, + 0xd8, 0x53, 0x11, 0x5d, 0x68, 0x0d, 0x04, 0xb9, 0xd4, 0x6e, 0xe7, 0x80, 0xbc, 0x0d, 0x10, 0xef, + 0x14, 0x9c, 0xee, 0xa5, 0x52, 0xb0, 0xad, 0x4a, 0xfe, 0xb6, 0x2a, 0x05, 0x3b, 0x14, 0xb7, 0x55, + 0xe9, 0xa1, 0xd9, 0xa4, 0x68, 0x5b, 0x11, 0x2c, 0xb5, 0xdf, 0x2b, 0xc8, 0x2b, 0x3d, 0x4d, 0x2f, + 0x5e, 0x43, 0x5f, 0x91, 0x17, 0x59, 0x4e, 0x20, 0xdf, 0xcb, 0x91, 0x9f, 0xe9, 0x8b, 0x3c, 0x80, + 0x93, 0x80, 0xbe, 0x0a, 0xc7, 0x42, 0xe4, 0x0f, 0x83, 0x95, 0xff, 0xff, 0x84, 0xe8, 0x4f, 0x0a, + 0x1c, 0xef, 0x31, 0x11, 0x06, 0xe9, 0x5d, 0xd8, 0x97, 0xdc, 0x7b, 0x18, 0xa7, 0x85, 0xc2, 0x38, + 0x25, 0x7c, 0x61, 0xa4, 0x26, 0x3b, 0x62, 0xe3, 0xee, 0xc5, 0xea, 0x3a, 0xcc, 0x71, 0x0a, 0xc9, + 0x39, 0xbb, 0x7c, 0x5d, 0xc2, 0x78, 0x1d, 0x85, 0xd1, 0xe0, 0x04, 0x5b, 0x0d, 0x1e, 0xad, 0xa1, + 0xca, 0xf3, 0xfc, 0xf9, 0x4e, 0x43, 0xfb, 0x3e, 0x9c, 0x2c, 0x30, 0x2f, 0x88, 0x82, 0xb2, 0x0b, + 0x51, 0xd0, 0xa6, 0x81, 0x84, 0x47, 0xef, 0x51, 0xb5, 0x8a, 0x70, 0xb5, 0x07, 0x70, 0x30, 0xd1, + 0x8a, 0x28, 0x2e, 0xc3, 0xd0, 0xa3, 0x6a, 0x15, 0xa7, 0x9e, 0x2b, 0x9c, 0xfa, 0x51, 0xb5, 0x8a, + 0x13, 0xfa, 0x26, 0xda, 0x2d, 0x38, 0x1a, 0x39, 0xf4, 0xbc, 0xa5, 0x46, 0xc3, 0xa5, 0x5e, 0xb4, + 0x99, 0xe6, 0x61, 0xaa, 0x66, 0xb1, 0xba, 0x63, 0xd9, 0x46, 0x14, 0xa4, 0xbd, 0x3c, 0x48, 0xfb, + 0xb0, 0xfd, 0x26, 0xc6, 0xea, 0xad, 0xf8, 0x72, 0x11, 0xdd, 0x20, 0xbc, 0x29, 0x18, 0xa2, 0xac, + 0x85, 0x57, 0x8b, 0xff, 0xd3, 0x6f, 0xa9, 0xb1, 0x3a, 0x77, 0x36, 0x56, 0xf1, 0x7f, 0x6a, 0x4f, + 0x14, 0x58, 0xc8, 0xba, 0x28, 0x77, 0x6f, 0x5b, 0xb6, 0xd9, 0xb6, 0x3e, 0xa6, 0x8d, 0x15, 0x6a, + 0x35, 0x5b, 0x2c, 0x84, 0xb6, 0x08, 0x87, 0x56, 0xc3, 0x1e, 0xc3, 0x67, 0x69, 0xb4, 0x78, 0x3f, + 0x2e, 0xe2, 0xc1, 0xa8, 0xf3, 0x31, 0x65, 0x66, 0x60, 0x3a, 0x00, 0x9d, 0x77, 0xe0, 0x9c, 0x14, + 0x96, 0x01, 0xf8, 0x7d, 0x0f, 0x5e, 0xe0, 0x2e, 0x1f, 0x79, 0xde, 0x8a, 0xe5, 0x31, 0xc7, 0xed, + 0xee, 0xf6, 0x91, 0xfd, 0x85, 0x02, 0x87, 0x33, 0x53, 0x20, 0xc2, 0x25, 0x18, 0x65, 0x9e, 0x67, + 0xb4, 0x2d, 0x8f, 0xe1, 0x31, 0x95, 0xdd, 0x25, 0xcf, 0x33, 0xcf, 0xbb, 0x67, 0x79, 0x6c, 0xf7, + 0x8e, 0xe5, 0x2f, 0x15, 0x38, 0x10, 0x1c, 0x2c, 0xd7, 0xd9, 0xa0, 0xfd, 0x0f, 0x22, 0x39, 0x0c, + 0xcf, 0xb3, 0x4d, 0xa3, 0x65, 0x7a, 0x2d, 0x0c, 0xe8, 0x08, 0xdb, 0x5c, 0x31, 0xbd, 0x16, 0x39, + 0x05, 0xc3, 0x1d, 0xd7, 0x71, 0x56, 0x8f, 0x0c, 0x71, 0x34, 0x93, 0x25, 0xac, 0x37, 0x1e, 0xfa, + 0x8d, 0x95, 0xa0, 0x8f, 0x1c, 0x07, 0xc0, 0x14, 0xef, 0x3b, 0x78, 0x8e, 0x3b, 0x18, 0xe3, 0x2d, + 0xdc, 0xc7, 0x51, 0x18, 0x65, 0x9b, 0x46, 0x90, 0xfb, 0x86, 0x83, 0x79, 0xd9, 0xe6, 0x1d, 0x9e, + 0xfd, 0x16, 0xf0, 0x08, 0x22, 0x4e, 0x0c, 0xe5, 0x34, 0x0c, 0x6f, 0x98, 0x6d, 0x44, 0x39, 0x5a, + 0x09, 0x1e, 0xa2, 0xe3, 0xfa, 0x90, 0x67, 0xe9, 0xf0, 0xb8, 0x7e, 0x0b, 0x8f, 0x6b, 0xd8, 0x1a, + 0xad, 0xc6, 0x48, 0x90, 0xcd, 0x71, 0xb5, 0x4f, 0x15, 0x5f, 0x16, 0x7c, 0x28, 0x2e, 0x07, 0x1a, + 0x6a, 0x2d, 0x98, 0xe6, 0x9e, 0x57, 0x4c, 0xef, 0x9b, 0x0e, 0xa3, 0x8d, 0x30, 0x8c, 0xe7, 0xe0, + 0x40, 0x50, 0xfd, 0x18, 0x56, 0x83, 0xda, 0xcc, 0x5a, 0xb5, 0xa8, 0x8b, 0x1b, 0x73, 0x2a, 0xe8, + 0xb8, 0x13, 0xb5, 0x93, 0x53, 0x30, 0xb9, 0xe1, 0x30, 0xea, 0x1a, 0x66, 0xb0, 0xc3, 0x31, 0xbc, + 0x13, 0xbc, 0x11, 0x77, 0xbd, 0xf6, 0x0a, 0x1c, 0x4a, 0xcd, 0x84, 0x2c, 0x66, 0x60, 0xac, 0x65, + 0x7a, 0x86, 0x3f, 0x38, 0x0c, 0xc6, 0x68, 0x0b, 0x07, 0x69, 0x5f, 0x87, 0x59, 0x6e, 0x55, 0xe6, + 0x73, 0x96, 0xbb, 0xf1, 0xac, 0x3b, 0x41, 0xaa, 0x31, 0x18, 0xf3, 0xfd, 0xba, 0x7c, 0x27, 0x66, + 0x60, 0x2b, 0x59, 0xd8, 0xa4, 0x0c, 0x63, 0xfe, 0xb3, 0xc1, 0xba, 0x1d, 0xca, 0x79, 0xed, 0x5b, + 0x3c, 0x5d, 0x18, 0x66, 0xdf, 0xff, 0xa3, 0x6e, 0x87, 0x56, 0x46, 0x37, 0xf0, 0x97, 0xf6, 0xbb, + 0xbd, 0x70, 0xa2, 0x27, 0x0b, 0x8c, 0xc2, 0x40, 0x01, 0xbf, 0x01, 0x23, 0x1c, 0xa4, 0x1f, 0xe9, + 0x21, 0x7e, 0xcc, 0xfb, 0x21, 0xe2, 0x8c, 0x2b, 0x68, 0x45, 0xde, 0x85, 0xa9, 0xa0, 0x97, 0x9f, + 0xa4, 0x80, 0xdb, 0x10, 0xe7, 0x76, 0xbe, 0xd0, 0xd3, 0x83, 0xd8, 0x88, 0x53, 0xdc, 0xef, 0x24, + 0x1b, 0xc8, 0x7d, 0x98, 0x44, 0x16, 0x1e, 0x33, 0xd9, 0xba, 0xc7, 0xcf, 0xc9, 0xbe, 0xc5, 0xb3, + 0x85, 0x5e, 0x83, 0xa8, 0x54, 0xb9, 0x41, 0x65, 0xa2, 0x26, 0x3c, 0x69, 0x04, 0xa6, 0x78, 0xe0, + 0x1e, 0xe0, 0xd8, 0x2a, 0x65, 0xda, 0x65, 0x38, 0x92, 0x6e, 0x8b, 0xa2, 0x78, 0x0c, 0xc6, 0x42, + 0xb7, 0x41, 0x1d, 0x31, 0x56, 0x89, 0x1b, 0xb4, 0x17, 0x70, 0xb3, 0x57, 0xd7, 0x3b, 0x1d, 0xc7, + 0x65, 0xb4, 0xc1, 0xef, 0x69, 0x4f, 0xbb, 0x85, 0xc5, 0x50, 0xaa, 0x3d, 0xf2, 0x7a, 0x1a, 0x46, + 0x38, 0xf6, 0xb0, 0x34, 0x89, 0x2e, 0x88, 0x20, 0x87, 0x63, 0xa7, 0x76, 0x03, 0x13, 0xbd, 0x5f, + 0xe5, 0x3a, 0x2e, 0x0d, 0xce, 0xdb, 0x6d, 0xc7, 0x95, 0x2d, 0x14, 0x6c, 0xd0, 0x8a, 0xec, 0x11, + 0xcc, 0x0a, 0x8c, 0xfb, 0xe1, 0x33, 0x12, 0x27, 0xff, 0x4c, 0x71, 0x51, 0x19, 0x79, 0xab, 0x40, + 0x3d, 0xfa, 0xad, 0xcd, 0xc4, 0x39, 0x5b, 0x18, 0x81, 0x57, 0xce, 0xfb, 0x42, 0x99, 0x2f, 0x74, + 0x22, 0x88, 0x7b, 0x79, 0x20, 0xce, 0x49, 0x82, 0xe0, 0x5b, 0x51, 0x04, 0x22, 0x48, 0x8a, 0xfb, + 0x4e, 0x83, 0x2e, 0x05, 0x92, 0xa6, 0x58, 0x52, 0xbc, 0x1f, 0x4b, 0x8a, 0x84, 0x0d, 0x02, 0x7c, + 0x1b, 0x26, 0x44, 0x79, 0x24, 0xa5, 0x29, 0x44, 0x3f, 0xe3, 0x76, 0xfc, 0x20, 0xaa, 0x89, 0x1c, + 0x7c, 0xbb, 0x95, 0x77, 0x3f, 0x13, 0xd4, 0x44, 0x1e, 0xa5, 0xbb, 0x30, 0x2e, 0x34, 0x4b, 0xa9, + 0x89, 0x04, 0x23, 0xe1, 0x61, 0xf7, 0x92, 0xf0, 0x1c, 0xde, 0xcf, 0xfe, 0x36, 0x89, 0x64, 0xec, + 0x6d, 0x5f, 0xc5, 0x86, 0x1b, 0xe9, 0x87, 0x0a, 0x5e, 0x7e, 0x79, 0x43, 0x90, 0xda, 0x77, 0x60, + 0x2a, 0x2d, 0x82, 0x31, 0x90, 0xc5, 0xf7, 0x51, 0xca, 0x1f, 0xe6, 0xb6, 0xfd, 0xf5, 0x64, 0xb3, + 0x76, 0x18, 0x53, 0xcf, 0x32, 0x65, 0x6f, 0x73, 0x29, 0x1d, 0x62, 0xfb, 0x06, 0x16, 0x53, 0x42, + 0x07, 0x22, 0xba, 0x0a, 0x23, 0x81, 0xea, 0x96, 0x4a, 0xad, 0x68, 0x8c, 0x26, 0xda, 0x09, 0xd4, + 0x3c, 0xd5, 0x96, 0xf3, 0x51, 0x78, 0x4b, 0xdd, 0x14, 0xb6, 0x8c, 0x1f, 0x93, 0xd9, 0x5e, 0x23, + 0x10, 0xc0, 0x77, 0xe1, 0x60, 0xdb, 0xf4, 0x98, 0x11, 0xce, 0x61, 0x88, 0xfb, 0xb8, 0x54, 0x88, + 0xe6, 0x9e, 0xe9, 0xb1, 0xa4, 0xd3, 0x03, 0xed, 0x74, 0x93, 0x76, 0x17, 0x31, 0x96, 0xdb, 0xe6, + 0x1a, 0xcd, 0xcb, 0xab, 0x67, 0x61, 0x8a, 0xff, 0xa3, 0x23, 0x9b, 0x8f, 0xf6, 0xf3, 0x76, 0x21, + 0xab, 0xd6, 0xc3, 0x24, 0x9d, 0xf5, 0x15, 0x55, 0x2a, 0x80, 0xce, 0xec, 0x55, 0x07, 0x49, 0x68, + 0xc5, 0x49, 0xc1, 0x1f, 0xee, 0x17, 0x58, 0xfe, 0x54, 0xf6, 0xaa, 0xa3, 0xd1, 0xf8, 0x74, 0x04, + 0x7d, 0xb4, 0xee, 0xb8, 0x8d, 0x5d, 0x17, 0xac, 0xbf, 0x51, 0x62, 0x65, 0x9c, 0x9c, 0x07, 0xa9, + 0x2c, 0xa7, 0xa8, 0x0c, 0xc9, 0x51, 0xc1, 0xbd, 0x19, 0x13, 0xda, 0xbd, 0x33, 0x58, 0x45, 0x7d, + 0x8a, 0xe1, 0xe7, 0xe9, 0x62, 0xc9, 0x6e, 0x70, 0x01, 0x28, 0x51, 0x16, 0x4f, 0xc3, 0x30, 0x97, + 0x9c, 0xa8, 0x61, 0x82, 0x07, 0x6d, 0x15, 0x93, 0x59, 0xbe, 0xd3, 0x1e, 0xcb, 0x3a, 0x34, 0xf8, + 0xb2, 0x0a, 0x77, 0x6b, 0x99, 0x17, 0xd3, 0xfc, 0x1f, 0x68, 0xbb, 0xbd, 0xaa, 0x9f, 0x2a, 0xe2, + 0xee, 0x11, 0xa6, 0x89, 0x84, 0xef, 0xa4, 0xf8, 0xff, 0xbb, 0x30, 0xd1, 0x1f, 0x0c, 0x13, 0xbd, + 0x68, 0x33, 0x51, 0x8b, 0x1f, 0x76, 0xf1, 0xbf, 0x0c, 0x4b, 0xb8, 0x8a, 0xcb, 0x94, 0x09, 0xb3, + 0x95, 0xfd, 0x7a, 0xb9, 0x15, 0x86, 0x23, 0xa9, 0x41, 0xfc, 0x70, 0x4c, 0x08, 0x1a, 0x44, 0x7b, + 0x2f, 0x2e, 0x40, 0x72, 0x5c, 0x20, 0xd5, 0xd7, 0x60, 0x42, 0xa4, 0x8a, 0x41, 0xcd, 0x65, 0x3a, + 0x2e, 0x30, 0xd5, 0xae, 0xc5, 0xd7, 0xb8, 0x30, 0xc6, 0xaf, 0xd3, 0x24, 0x36, 0x99, 0xf6, 0x83, + 0x5c, 0x76, 0x68, 0x8d, 0xc8, 0xde, 0x03, 0x22, 0x22, 0xe3, 0x25, 0x24, 0x45, 0x7c, 0x17, 0xfa, + 0xec, 0xaa, 0x94, 0xcb, 0xa9, 0x5a, 0xaa, 0x65, 0xf1, 0xc9, 0x3c, 0x0c, 0x73, 0x04, 0xe4, 0x13, + 0x05, 0x46, 0x82, 0xc2, 0x83, 0xe8, 0x85, 0x5e, 0xb3, 0x42, 0x4c, 0x7d, 0x59, 0xde, 0x20, 0x20, + 0xa5, 0x9d, 0xfa, 0xd1, 0xdf, 0xfe, 0xf3, 0x93, 0xbd, 0xc7, 0xc9, 0x8c, 0xee, 0x8f, 0xbf, 0xc0, + 0x4d, 0xf5, 0xd4, 0x3f, 0x63, 0xc9, 0x1f, 0x15, 0x18, 0x0d, 0x75, 0x11, 0xb9, 0xd8, 0x7f, 0x8e, + 0x94, 0x5a, 0x53, 0x17, 0x07, 0x31, 0x41, 0x60, 0x77, 0x39, 0xb0, 0xaf, 0x91, 0x72, 0x2e, 0xb0, + 0x48, 0x91, 0xe9, 0x5b, 0x19, 0x59, 0xb2, 0xad, 0x6f, 0x25, 0x74, 0xd3, 0x36, 0xf9, 0xbb, 0x02, + 0x24, 0xab, 0x6d, 0xc8, 0xd5, 0xfe, 0xb0, 0x7a, 0xea, 0x3a, 0xf5, 0xda, 0xce, 0x8c, 0x91, 0xdd, + 0x2d, 0xce, 0xee, 0x4d, 0x72, 0x3d, 0x97, 0x1d, 0x52, 0xaa, 0x75, 0x05, 0x56, 0x79, 0x44, 0xc9, + 0xcf, 0x15, 0x18, 0x17, 0x74, 0x06, 0xb9, 0xd0, 0x1f, 0x94, 0x30, 0x5c, 0x7d, 0x75, 0xa0, 0xe1, + 0x11, 0xf8, 0xb3, 0x1c, 0xfc, 0x29, 0x72, 0x32, 0x17, 0x7c, 0x54, 0x11, 0x78, 0x94, 0x91, 0x5f, + 0x29, 0xb0, 0x3f, 0x25, 0x5b, 0x64, 0x36, 0x50, 0xca, 0x44, 0x7d, 0x63, 0x60, 0x93, 0x08, 0xec, + 0x79, 0x0e, 0xf6, 0x25, 0xf2, 0x62, 0x2e, 0x58, 0x2f, 0x85, 0xed, 0x5f, 0x0a, 0x1c, 0xca, 0xd5, + 0x37, 0xe4, 0x46, 0x7f, 0x08, 0x45, 0xc2, 0x4a, 0x7d, 0x73, 0xc7, 0xf6, 0x48, 0xe4, 0x26, 0x27, + 0x72, 0x9d, 0x5c, 0xcd, 0x25, 0xd2, 0xa4, 0xcc, 0xa8, 0xb7, 0x2d, 0x6a, 0x33, 0x14, 0x3d, 0xc6, + 0xaa, 0xe3, 0x06, 0xff, 0xff, 0xd3, 0xb7, 0xc2, 0x5b, 0x6f, 0x9b, 0xfc, 0x5a, 0x81, 0xc9, 0xc4, + 0x34, 0xe4, 0xb5, 0x01, 0x71, 0x85, 0x7c, 0x5e, 0x1f, 0xd8, 0x4e, 0x6a, 0x41, 0x38, 0x8f, 0x58, + 0xba, 0x91, 0xcf, 0x94, 0x84, 0xac, 0x20, 0x72, 0xd3, 0x66, 0x65, 0x90, 0x7a, 0x79, 0x70, 0x43, + 0x04, 0xfc, 0x32, 0x07, 0xbc, 0x40, 0xe6, 0x73, 0x01, 0x0b, 0x42, 0x4c, 0xdf, 0xe2, 0xda, 0x6f, + 0xdb, 0xdf, 0xf5, 0xfb, 0x04, 0x4f, 0x4b, 0xed, 0xb6, 0x0c, 0xee, 0x5c, 0xf9, 0x26, 0x83, 0x3b, + 0x5f, 0x90, 0x69, 0xf3, 0x1c, 0xb7, 0x46, 0xe6, 0xfa, 0xe1, 0x26, 0x7f, 0x50, 0x60, 0x7f, 0x4a, + 0xab, 0xc8, 0x5c, 0x8e, 0x3d, 0x45, 0x95, 0xcc, 0xe5, 0xd8, 0x5b, 0x6e, 0x69, 0x17, 0x38, 0xf0, + 0x33, 0xe4, 0x74, 0x2e, 0xf0, 0xb4, 0x12, 0x23, 0x3f, 0x55, 0x60, 0x24, 0x50, 0x38, 0x64, 0x51, + 0x6a, 0xde, 0x84, 0xc8, 0x52, 0x2f, 0x0d, 0x64, 0x23, 0x95, 0x36, 0x03, 0x9d, 0x45, 0xfe, 0xac, + 0xc0, 0x81, 0x8c, 0x82, 0x22, 0x57, 0x24, 0xee, 0xb2, 0x1e, 0xc2, 0x4c, 0xbd, 0xba, 0x23, 0x5b, + 0xc4, 0xfc, 0x06, 0xc7, 0x7c, 0x89, 0x5c, 0x14, 0x31, 0x87, 0x5e, 0x84, 0x2b, 0xb1, 0xe5, 0x7c, + 0x94, 0x92, 0x75, 0xe4, 0xaf, 0x0a, 0x1c, 0xc8, 0xa8, 0x27, 0x19, 0x26, 0xbd, 0xe4, 0x9b, 0x0c, + 0x93, 0x9e, 0x72, 0xad, 0xcf, 0x55, 0x18, 0x94, 0xfc, 0xe9, 0xe4, 0x99, 0xd2, 0x8a, 0xdb, 0x7e, + 0x51, 0x43, 0x96, 0x29, 0x4b, 0xe9, 0x28, 0x22, 0x77, 0xde, 0x72, 0x24, 0x9e, 0x4c, 0x92, 0xea, + 0x21, 0xda, 0xb4, 0x45, 0x4e, 0xe8, 0x3c, 0x59, 0xe8, 0x79, 0x27, 0x9a, 0xed, 0xb6, 0x11, 0x70, + 0x70, 0x11, 0xe8, 0x97, 0x0a, 0x1c, 0xe2, 0xce, 0xbc, 0x94, 0xfc, 0x21, 0xd7, 0xa5, 0x63, 0x9b, + 0xa7, 0xc5, 0xd4, 0x1b, 0x3b, 0x35, 0x47, 0x32, 0x2b, 0x9c, 0x4c, 0x99, 0xbc, 0x55, 0xbc, 0x3a, + 0xc1, 0x11, 0x36, 0xed, 0x46, 0xf0, 0x46, 0x51, 0xc8, 0x52, 0xfa, 0x16, 0x6f, 0xd9, 0xf6, 0xef, + 0xa5, 0x68, 0x89, 0x04, 0x4d, 0xf3, 0xba, 0x64, 0xa0, 0xd3, 0x72, 0x4d, 0xbd, 0x3c, 0xb8, 0xe1, + 0x80, 0x0b, 0x24, 0x68, 0x34, 0xf2, 0x4f, 0x05, 0xa6, 0xf3, 0xa4, 0x8e, 0xcc, 0xfa, 0x14, 0xa8, + 0x2c, 0xf5, 0xc6, 0x4e, 0xcd, 0x91, 0x4b, 0x99, 0x73, 0xb9, 0x46, 0xae, 0xf4, 0xe4, 0x92, 0x90, + 0x39, 0xb5, 0x2e, 0x97, 0x73, 0xfe, 0x11, 0x0a, 0xa5, 0xdd, 0x36, 0xf9, 0xaf, 0x02, 0x6a, 0x8e, + 0x56, 0xc2, 0x2d, 0x41, 0xae, 0x0d, 0x0a, 0x51, 0xd4, 0x69, 0xea, 0xf5, 0x1d, 0x5a, 0x4b, 0x29, + 0x87, 0x0c, 0x3f, 0x2e, 0xe3, 0xe2, 0x0d, 0x69, 0x35, 0xc4, 0x7a, 0xe9, 0xc7, 0x0a, 0x0c, 0xf3, + 0xf7, 0x62, 0xa4, 0x24, 0x21, 0xad, 0x84, 0x17, 0x7d, 0xaa, 0x2e, 0x3d, 0x1e, 0x61, 0x6b, 0x1c, + 0xf6, 0x31, 0xa2, 0xe6, 0x2b, 0x31, 0x0e, 0x02, 0xcb, 0xb7, 0xf8, 0x65, 0xad, 0x64, 0xf9, 0x96, + 0x79, 0xe7, 0x2d, 0x59, 0xbe, 0x65, 0x5f, 0x72, 0x4b, 0x94, 0x6f, 0xcc, 0xf3, 0x42, 0xe9, 0x45, + 0x7e, 0xb6, 0x17, 0x66, 0x8b, 0xdf, 0x2e, 0x93, 0xe5, 0x01, 0x91, 0xf4, 0x7a, 0x57, 0xae, 0xae, + 0x7c, 0x75, 0x47, 0xc8, 0xb1, 0xc6, 0x39, 0x7e, 0x9b, 0x3c, 0x96, 0xe1, 0x68, 0xb4, 0xf8, 0x4b, + 0x68, 0xab, 0x6e, 0xb6, 0xf5, 0xad, 0xdc, 0x97, 0xf5, 0xdb, 0xfa, 0x56, 0xfa, 0x85, 0xfc, 0x36, + 0x79, 0xa2, 0xf0, 0x8f, 0x19, 0x64, 0x34, 0x7e, 0xe2, 0xdb, 0x08, 0x19, 0x8d, 0x9f, 0xfc, 0x6c, + 0x42, 0x9b, 0xe3, 0x74, 0x54, 0x72, 0x24, 0x97, 0x8e, 0x0f, 0xe2, 0x53, 0x05, 0x20, 0x7e, 0x9d, + 0x4e, 0x24, 0x4a, 0xa2, 0xcc, 0xfb, 0x7d, 0xf5, 0x95, 0xc1, 0x8c, 0x10, 0xdb, 0x19, 0x8e, 0xed, + 0x24, 0x39, 0x91, 0x8b, 0x8d, 0xc5, 0x98, 0x7e, 0xab, 0xc0, 0x54, 0xe2, 0x7b, 0x12, 0xbf, 0xaa, + 0x96, 0x4b, 0xb9, 0x79, 0x5f, 0x10, 0xa9, 0x57, 0x76, 0x62, 0x8a, 0xa0, 0x17, 0x38, 0xe8, 0x17, + 0x89, 0x96, 0x7f, 0x54, 0x13, 0x9f, 0xf9, 0xfc, 0x45, 0x81, 0xe9, 0xbc, 0x4f, 0x6b, 0x64, 0xb2, + 0x40, 0xc1, 0x17, 0x3d, 0x32, 0x59, 0xa0, 0xe8, 0x8b, 0x1e, 0xed, 0x55, 0xce, 0x41, 0x27, 0x17, + 0xfa, 0x73, 0x10, 0x2f, 0x44, 0x5f, 0x8f, 0x89, 0x5f, 0x7c, 0x49, 0xca, 0xc0, 0xcc, 0x47, 0x6e, + 0x92, 0x7a, 0x2c, 0xe7, 0xb3, 0xb5, 0x3e, 0x7a, 0xac, 0x1e, 0x5b, 0x24, 0xf4, 0x98, 0xe0, 0x49, + 0x5e, 0x8f, 0xed, 0x0c, 0x77, 0xfe, 0xe7, 0x76, 0x7d, 0xf4, 0x98, 0x80, 0xbb, 0x7c, 0xe7, 0xf3, + 0xa7, 0xb3, 0xca, 0x17, 0x4f, 0x67, 0x95, 0x2f, 0x9f, 0xce, 0x2a, 0x9f, 0x3c, 0x9b, 0xdd, 0xf3, + 0xc5, 0xb3, 0xd9, 0x3d, 0xff, 0x78, 0x36, 0xbb, 0xe7, 0xb1, 0xde, 0xb4, 0x58, 0x6b, 0xbd, 0x56, + 0xaa, 0x3b, 0x6b, 0xb9, 0x55, 0xfc, 0xa6, 0x70, 0x76, 0xba, 0x1d, 0xea, 0xd5, 0x46, 0xf8, 0x57, + 0x91, 0x97, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xb7, 0x2c, 0x68, 0xde, 0x2a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2886,8 +2790,7 @@ type QueryClient interface { // Queries a list of VoterByIdentifier items. BallotByIdentifier(ctx context.Context, in *QueryBallotByIdentifierRequest, opts ...grpc.CallOption) (*QueryBallotByIdentifierResponse, error) // Queries a list of ObserversByChainAndType items. - ObserversByChain(ctx context.Context, in *QueryObserversByChainRequest, opts ...grpc.CallOption) (*QueryObserversByChainResponse, error) - AllObserverMappers(ctx context.Context, in *QueryAllObserverMappersRequest, opts ...grpc.CallOption) (*QueryAllObserverMappersResponse, error) + ObserverSet(ctx context.Context, in *QueryObserverSet, opts ...grpc.CallOption) (*QueryObserverSetResponse, error) SupportedChains(ctx context.Context, in *QuerySupportedChains, opts ...grpc.CallOption) (*QuerySupportedChainsResponse, error) // Queries a list of GetClientParamsForChain items. GetCoreParamsForChain(ctx context.Context, in *QueryGetCoreParamsForChainRequest, opts ...grpc.CallOption) (*QueryGetCoreParamsForChainResponse, error) @@ -2962,18 +2865,9 @@ func (c *queryClient) BallotByIdentifier(ctx context.Context, in *QueryBallotByI return out, nil } -func (c *queryClient) ObserversByChain(ctx context.Context, in *QueryObserversByChainRequest, opts ...grpc.CallOption) (*QueryObserversByChainResponse, error) { - out := new(QueryObserversByChainResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/ObserversByChain", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *queryClient) AllObserverMappers(ctx context.Context, in *QueryAllObserverMappersRequest, opts ...grpc.CallOption) (*QueryAllObserverMappersResponse, error) { - out := new(QueryAllObserverMappersResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/AllObserverMappers", in, out, opts...) +func (c *queryClient) ObserverSet(ctx context.Context, in *QueryObserverSet, opts ...grpc.CallOption) (*QueryObserverSetResponse, error) { + out := new(QueryObserverSetResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/ObserverSet", in, out, opts...) if err != nil { return nil, err } @@ -3196,8 +3090,7 @@ type QueryServer interface { // Queries a list of VoterByIdentifier items. BallotByIdentifier(context.Context, *QueryBallotByIdentifierRequest) (*QueryBallotByIdentifierResponse, error) // Queries a list of ObserversByChainAndType items. - ObserversByChain(context.Context, *QueryObserversByChainRequest) (*QueryObserversByChainResponse, error) - AllObserverMappers(context.Context, *QueryAllObserverMappersRequest) (*QueryAllObserverMappersResponse, error) + ObserverSet(context.Context, *QueryObserverSet) (*QueryObserverSetResponse, error) SupportedChains(context.Context, *QuerySupportedChains) (*QuerySupportedChainsResponse, error) // Queries a list of GetClientParamsForChain items. GetCoreParamsForChain(context.Context, *QueryGetCoreParamsForChainRequest) (*QueryGetCoreParamsForChainResponse, error) @@ -3250,11 +3143,8 @@ func (*UnimplementedQueryServer) HasVoted(ctx context.Context, req *QueryHasVote func (*UnimplementedQueryServer) BallotByIdentifier(ctx context.Context, req *QueryBallotByIdentifierRequest) (*QueryBallotByIdentifierResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method BallotByIdentifier not implemented") } -func (*UnimplementedQueryServer) ObserversByChain(ctx context.Context, req *QueryObserversByChainRequest) (*QueryObserversByChainResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ObserversByChain not implemented") -} -func (*UnimplementedQueryServer) AllObserverMappers(ctx context.Context, req *QueryAllObserverMappersRequest) (*QueryAllObserverMappersResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AllObserverMappers not implemented") +func (*UnimplementedQueryServer) ObserverSet(ctx context.Context, req *QueryObserverSet) (*QueryObserverSetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ObserverSet not implemented") } func (*UnimplementedQueryServer) SupportedChains(ctx context.Context, req *QuerySupportedChains) (*QuerySupportedChainsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SupportedChains not implemented") @@ -3384,38 +3274,20 @@ func _Query_BallotByIdentifier_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _Query_ObserversByChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryObserversByChainRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).ObserversByChain(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/zetachain.zetacore.observer.Query/ObserversByChain", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).ObserversByChain(ctx, req.(*QueryObserversByChainRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Query_AllObserverMappers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAllObserverMappersRequest) +func _Query_ObserverSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryObserverSet) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).AllObserverMappers(ctx, in) + return srv.(QueryServer).ObserverSet(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/zetachain.zetacore.observer.Query/AllObserverMappers", + FullMethod: "/zetachain.zetacore.observer.Query/ObserverSet", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).AllObserverMappers(ctx, req.(*QueryAllObserverMappersRequest)) + return srv.(QueryServer).ObserverSet(ctx, req.(*QueryObserverSet)) } return interceptor(ctx, in, info, handler) } @@ -3851,12 +3723,8 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_BallotByIdentifier_Handler, }, { - MethodName: "ObserversByChain", - Handler: _Query_ObserversByChain_Handler, - }, - { - MethodName: "AllObserverMappers", - Handler: _Query_AllObserverMappers_Handler, + MethodName: "ObserverSet", + Handler: _Query_ObserverSet_Handler, }, { MethodName: "SupportedChains", @@ -4859,7 +4727,7 @@ func (m *QueryBallotByIdentifierResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } -func (m *QueryObserversByChainRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryObserverSet) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4869,27 +4737,20 @@ func (m *QueryObserversByChainRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryObserversByChainRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryObserverSet) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryObserversByChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryObserverSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.ObservationChain) > 0 { - i -= len(m.ObservationChain) - copy(dAtA[i:], m.ObservationChain) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ObservationChain))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } -func (m *QueryObserversByChainResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryObserverSetResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4899,12 +4760,12 @@ func (m *QueryObserversByChainResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryObserversByChainResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryObserverSetResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryObserversByChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryObserverSetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4921,66 +4782,6 @@ func (m *QueryObserversByChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *QueryAllObserverMappersRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryAllObserverMappersRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryAllObserverMappersRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryAllObserverMappersResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryAllObserverMappersResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryAllObserverMappersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ObserverMappers) > 0 { - for iNdEx := len(m.ObserverMappers) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ObserverMappers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *QuerySupportedChains) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6291,20 +6092,16 @@ func (m *QueryBallotByIdentifierResponse) Size() (n int) { return n } -func (m *QueryObserversByChainRequest) Size() (n int) { +func (m *QueryObserverSet) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.ObservationChain) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } return n } -func (m *QueryObserversByChainResponse) Size() (n int) { +func (m *QueryObserverSetResponse) Size() (n int) { if m == nil { return 0 } @@ -6319,30 +6116,6 @@ func (m *QueryObserversByChainResponse) Size() (n int) { return n } -func (m *QueryAllObserverMappersRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryAllObserverMappersResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ObserverMappers) > 0 { - for _, e := range m.ObserverMappers { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } - } - return n -} - func (m *QuerySupportedChains) Size() (n int) { if m == nil { return 0 @@ -9078,7 +8851,7 @@ func (m *QueryBallotByIdentifierResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { +func (m *QueryObserverSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9101,44 +8874,12 @@ func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryObserversByChainRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryObserverSet: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryObserversByChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryObserverSet: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObservationChain", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ObservationChain = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -9160,7 +8901,7 @@ func (m *QueryObserversByChainRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { +func (m *QueryObserverSetResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9183,10 +8924,10 @@ func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryObserversByChainResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryObserverSetResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryObserversByChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryObserverSetResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -9242,140 +8983,6 @@ func (m *QueryObserversByChainResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllObserverMappersRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryAllObserverMappersRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllObserverMappersRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryAllObserverMappersResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryAllObserverMappersResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllObserverMappersResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObserverMappers", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ObserverMappers = append(m.ObserverMappers, &ObserverMapper{}) - if err := m.ObserverMappers[len(m.ObserverMappers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *QuerySupportedChains) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index 91f2afabd8..8d99fcea64 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -181,74 +181,20 @@ func local_request_Query_BallotByIdentifier_0(ctx context.Context, marshaler run } -func request_Query_ObserversByChain_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryObserversByChainRequest +func request_Query_ObserverSet_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryObserverSet var metadata runtime.ServerMetadata - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["observation_chain"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "observation_chain") - } - - protoReq.ObservationChain, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "observation_chain", err) - } - - msg, err := client.ObserversByChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_ObserversByChain_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryObserversByChainRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["observation_chain"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "observation_chain") - } - - protoReq.ObservationChain, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "observation_chain", err) - } - - msg, err := server.ObserversByChain(ctx, &protoReq) - return msg, metadata, err - -} - -func request_Query_AllObserverMappers_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryAllObserverMappersRequest - var metadata runtime.ServerMetadata - - msg, err := client.AllObserverMappers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ObserverSet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_AllObserverMappers_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryAllObserverMappersRequest +func local_request_Query_ObserverSet_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryObserverSet var metadata runtime.ServerMetadata - msg, err := server.AllObserverMappers(ctx, &protoReq) + msg, err := server.ObserverSet(ctx, &protoReq) return msg, metadata, err } @@ -1254,7 +1200,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_ObserversByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_ObserverSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -1265,7 +1211,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_ObserversByChain_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_ObserverSet_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -1273,30 +1219,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_ObserversByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_AllObserverMappers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_AllObserverMappers_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_AllObserverMappers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_ObserverSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -1930,7 +1853,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_ObserversByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_ObserverSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -1939,34 +1862,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_ObserversByChain_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_ObserverSet_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_ObserversByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_Query_AllObserverMappers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_AllObserverMappers_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_AllObserverMappers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_ObserverSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2440,9 +2343,7 @@ var ( pattern_Query_BallotByIdentifier_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "ballot_by_identifier", "ballot_identifier"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ObserversByChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "observers_by_chain", "observation_chain"}, "", runtime.AssumeColonVerbOpt(false))) - - pattern_Query_AllObserverMappers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "all_observer_mappers"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ObserverSet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "observer_set"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_SupportedChains_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "supportedChains"}, "", runtime.AssumeColonVerbOpt(false))) @@ -2498,9 +2399,7 @@ var ( forward_Query_BallotByIdentifier_0 = runtime.ForwardResponseMessage - forward_Query_ObserversByChain_0 = runtime.ForwardResponseMessage - - forward_Query_AllObserverMappers_0 = runtime.ForwardResponseMessage + forward_Query_ObserverSet_0 = runtime.ForwardResponseMessage forward_Query_SupportedChains_0 = runtime.ForwardResponseMessage diff --git a/x/observer/types/test_data.go b/x/observer/types/test_data.go index bac2ae27a5..3a43ca4306 100644 --- a/x/observer/types/test_data.go +++ b/x/observer/types/test_data.go @@ -1,33 +1,9 @@ package types import ( - "strconv" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto" - "github.com/zeta-chain/zetacore/common" ) -const PrefixOutput = "Output1" - -func CreateObserverMapperList(items int, chain common.Chain) (list []*ObserverMapper) { - SetConfig(false) - for i := 0; i < items; i++ { - mapper := &ObserverMapper{ - Index: "Index" + strconv.Itoa(i), - ObserverChain: &chain, - ObserverList: []string{ - sdk.AccAddress(crypto.AddressHash([]byte(PrefixOutput + strconv.Itoa(i)))).String(), - sdk.AccAddress(crypto.AddressHash([]byte(PrefixOutput + strconv.Itoa(i+1)))).String(), - sdk.AccAddress(crypto.AddressHash([]byte(PrefixOutput + strconv.Itoa(i+2)))).String(), - sdk.AccAddress(crypto.AddressHash([]byte(PrefixOutput + strconv.Itoa(i+3)))).String(), - }, - } - list = append(list, mapper) - } - return -} - const ( AccountAddressPrefix = "zeta" ) diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 435e9cbcc9..761d233829 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -350,7 +350,7 @@ func (signer *BTCSigner) TryProcessOutTx( logger.Info().Msgf("Key-sign success: %d => %s, nonce %d", cctx.InboundTxParams.SenderChainId, btcClient.chain.ChainName, outboundTxTssNonce) // FIXME: add prometheus metrics - _, err = zetaBridge.GetObserverList(btcClient.chain) + _, err = zetaBridge.GetObserverList() if err != nil { logger.Warn().Err(err).Msgf("unable to get observer list: chain %d observation %s", outboundTxTssNonce, observertypes.ObservationType_OutBoundTx.String()) } diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index a0297a29b7..7882104cd5 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -546,7 +546,7 @@ func (signer *EVMSigner) TryProcessOutTx( } logger.Info().Msgf("Key-sign success: %d => %s, nonce %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce) - _, err = zetaBridge.GetObserverList(*toChain) + _, err = zetaBridge.GetObserverList() if err != nil { logger.Warn().Err(err).Msgf("unable to get observer list: chain %d observation %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, observertypes.ObservationType_OutBoundTx.String()) diff --git a/zetaclient/interfaces.go b/zetaclient/interfaces.go index 91e4af65f1..30ef360930 100644 --- a/zetaclient/interfaces.go +++ b/zetaclient/interfaces.go @@ -84,7 +84,7 @@ type ZetaCoreBridger interface { GetCctxByNonce(chainID int64, nonce uint64) (*crosschaintypes.CrossChainTx, error) GetAllOutTxTrackerByChain(chainID int64, order Order) ([]crosschaintypes.OutTxTracker, error) GetCrosschainFlags() (observertypes.CrosschainFlags, error) - GetObserverList(chain common.Chain) ([]string, error) + GetObserverList() ([]string, error) GetKeyGen() (*observertypes.Keygen, error) GetBtcTssAddress() (string, error) GetInboundTrackersForChain(chainID int64) ([]crosschaintypes.InTxTracker, error) diff --git a/zetaclient/query.go b/zetaclient/query.go index 0a786bba6e..edc6e76d0e 100644 --- a/zetaclient/query.go +++ b/zetaclient/query.go @@ -112,12 +112,12 @@ func (b *ZetaCoreBridge) GetCctxByNonce(chainID int64, nonce uint64) (*types.Cro return resp.CrossChainTx, nil } -func (b *ZetaCoreBridge) GetObserverList(chain common.Chain) ([]string, error) { +func (b *ZetaCoreBridge) GetObserverList() ([]string, error) { var err error client := observertypes.NewQueryClient(b.grpcConn) for i := 0; i <= DefaultRetryCount; i++ { - resp, err := client.ObserversByChain(context.Background(), &observertypes.QueryObserversByChainRequest{ObservationChain: chain.ChainName.String()}) + resp, err := client.ObserverSet(context.Background(), &observertypes.QueryObserverSet{}) if err == nil { return resp.Observers, nil } From aeb88bef73a086a0be934f91af807d73f7e2bcfc Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 8 Jan 2024 18:58:07 -0600 Subject: [PATCH 06/67] fix: relax header length basic check (#1525) * relax header length basic check BSC network may have larger header "error":"/zetachain.zetacore.observer.MsgAddBlockHeader invalid msg | invalid block header (header too long (2223)): invalid request * update changelog --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + common/headers.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index eeb890d260..0e922b8ce2 100644 --- a/changelog.md +++ b/changelog.md @@ -26,6 +26,7 @@ * add check to verify new tss has been produced when triggering tss funds migration * fix Athens-3 log print issue - avoid posting uncessary outtx confirmation * fix docker build issues with version: golang:1.20-alpine3.18 +* [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta ### Refactoring diff --git a/common/headers.go b/common/headers.go index f230367001..528bcffb78 100644 --- a/common/headers.go +++ b/common/headers.go @@ -101,7 +101,7 @@ func (h HeaderData) Validate(blockHash []byte, chainID int64, height int64) erro // validateEthereumHeader performs a basic validation of the Ethereum header func validateEthereumHeader(headerBytes []byte, blockHash []byte, height int64) error { // on ethereum the block header is ~538 bytes in RLP encoding - if len(headerBytes) > 1024 { + if len(headerBytes) > 4096 { return fmt.Errorf("header too long (%d)", len(headerBytes)) } From 20e0d93f66cc66e18341ffe8a105c3096b42c370 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 9 Jan 2024 01:37:39 -0600 Subject: [PATCH 07/67] fix: post block headers only for enabled EVM chains (#1497) * post block headers only for enabled EVM chains * update changelog.md * post block header for supported chains only --- changelog.md | 1 + zetaclient/evm_client.go | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 0e922b8ce2..4c357b65d8 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ ### Fixes +* [1496](https://github.com/zeta-chain/node/issues/1496) - post block header for enabled EVM chains only * [1518](https://github.com/zeta-chain/node/pull/1518) - Avoid duplicate keysign if an outTx is already pending * fix Code4rena issue - zetaclients potentially miss inTx when PostSend (or other RPC) fails * fix go-staticcheck warnings for zetaclient diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 2675b79250..3cba7744da 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -1045,9 +1045,11 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64) uint64 { for bn := startBlock; bn <= toBlock; bn++ { // post new block header (if any) to zetacore and ignore error // TODO: consider having a independent ticker(from TSS scaning) for posting block headers - err := ob.postBlockHeader(toBlock) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting block header") + if common.IsHeaderSupportedEvmChain(ob.chain.ChainId) { // post block header for supported chains + err := ob.postBlockHeader(toBlock) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting block header") + } } // TODO: we can track the total number of 'getBlockByNumber' RPC calls made From e6ccc5be11ab9a18ea4a9f68519f89bc5bd21212 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Tue, 9 Jan 2024 09:11:10 -0800 Subject: [PATCH 08/67] refactor(observer): put data from observerParams in coreParams (cherry picked) (#1436) * add observer params in core params * change msgUpdateCoreParamsLogic * add remove core params * replace GetChainFromChainID * refactor GetSupportedChains * refactor ballot fetching * update tests * update changelog * update mocks * fix keeper tests * add core params in genesis state * add test core params function * observer by chains * set core params in smoke test * fix test * prepare migrate function * fix smoke tests * add migrator * fix lint * fix build * fix default core params * add zeta in default core params * fix core param validate * remove develop * rename core params in chain params * remove debugging code --- changelog.md | 1 + cmd/zetaclientd/debug.go | 20 +- cmd/zetaclientd/start_utils.go | 6 +- cmd/zetaclientd/utils.go | 4 +- cmd/zetae2e/local/local.go | 1 + common/chain.go | 8 - .../smoketest/txserver/zeta_tx_server.go | 44 -- .../scripts/start-zetaclientd-genesis.sh | 2 +- .../cli/zetacored/zetacored_query_observer.md | 4 +- ...cored_query_observer_list-chain-params.md} | 8 +- ...cored_query_observer_show-chain-params.md} | 8 +- docs/cli/zetacored/zetacored_tx_observer.md | 3 +- ...acored_tx_observer_remove-chain-params.md} | 8 +- ...tacored_tx_observer_update-chain-params.md | 52 ++ docs/openapi/openapi.swagger.yaml | 66 +- docs/spec/observer/messages.md | 23 +- proto/observer/genesis.proto | 2 +- proto/observer/params.proto | 21 +- proto/observer/query.proto | 24 +- proto/observer/tx.proto | 16 +- testutil/keeper/mocks/crosschain/account.go | 2 +- testutil/keeper/mocks/crosschain/bank.go | 2 +- testutil/keeper/mocks/crosschain/fungible.go | 2 +- testutil/keeper/mocks/crosschain/observer.go | 56 +- testutil/keeper/mocks/crosschain/staking.go | 2 +- testutil/keeper/mocks/fungible/account.go | 2 +- testutil/keeper/mocks/fungible/bank.go | 2 +- testutil/keeper/mocks/fungible/evm.go | 2 +- testutil/keeper/mocks/fungible/observer.go | 37 +- testutil/network/genesis_state.go | 28 +- testutil/sample/observer.go | 39 +- testutil/sample/sample.go | 10 + typescript/observer/genesis_pb.d.ts | 6 +- typescript/observer/params_pb.d.ts | 65 +- typescript/observer/query_pb.d.ts | 74 +- typescript/observer/tx_pb.d.ts | 86 ++- .../client/integrationtests/cli_helpers.go | 4 +- x/crosschain/keeper/cctx_utils.go | 2 +- x/crosschain/keeper/evm_hooks.go | 11 +- x/crosschain/keeper/foreign_coins.go | 2 +- x/crosschain/keeper/gas_payment.go | 8 +- x/crosschain/keeper/gas_payment_test.go | 204 +----- x/crosschain/keeper/keeper_test.go | 1 - .../keeper/msg_server_add_to_intx_tracker.go | 2 +- .../msg_server_add_to_intx_tracker_test.go | 19 +- .../keeper/msg_server_add_to_outtx_tracker.go | 2 +- .../keeper/msg_server_gas_price_voter.go | 2 +- .../msg_server_migrate_tss_funds_test.go | 18 +- x/crosschain/keeper/msg_server_update_tss.go | 2 +- .../keeper/msg_server_update_tss_test.go | 76 ++- .../keeper/msg_server_vote_inbound_tx.go | 13 +- .../keeper/msg_server_vote_outbound_tx.go | 2 +- .../keeper/msg_server_whitelist_erc20.go | 6 +- .../keeper/msg_server_whitelist_erc20_test.go | 1 + x/crosschain/keeper/utils_test.go | 236 +++++++ x/crosschain/keeper/verify_proof.go | 12 +- x/crosschain/types/errors.go | 2 +- x/crosschain/types/expected_keepers.go | 4 +- x/emissions/types/expected_keepers.go | 2 +- .../keeper/grpc_query_gas_stability_pool.go | 2 +- x/fungible/types/expected_keepers.go | 5 +- x/observer/client/cli/query.go | 4 +- ...y_core_params.go => query_chain_params.go} | 20 +- x/observer/client/cli/tx.go | 3 +- .../client/cli/tx_remove_chain_params.go | 44 ++ ...re_params.go => tx_update_chain_params.go} | 16 +- x/observer/genesis.go | 29 +- x/observer/genesis_test.go | 2 +- x/observer/keeper/chain_params.go | 73 ++ x/observer/keeper/chain_params_test.go | 78 +++ x/observer/keeper/grpc_query_chain_params.go | 46 ++ x/observer/keeper/grpc_query_core_params.go | 40 -- .../keeper/grpc_query_supported_chain.go | 2 +- x/observer/keeper/hooks.go | 1 + x/observer/keeper/migrator.go | 2 +- .../keeper/msg_server_add_blame_vote.go | 2 +- .../keeper/msg_server_add_block_header.go | 6 +- .../msg_server_add_block_header_test.go | 19 + .../keeper/msg_server_remove_chain_params.go | 39 ++ .../msg_server_remove_chain_params_test.go | 133 ++++ .../keeper/msg_server_update_chain_params.go | 40 ++ .../msg_server_update_chain_params_test.go | 115 ++++ .../keeper/msg_server_update_core_params.go | 39 -- .../keeper/msg_server_update_observer.go | 2 + .../keeper/msg_server_update_observer_test.go | 1 + x/observer/keeper/params.go | 34 - x/observer/keeper/pending_nonces.go | 2 +- x/observer/keeper/utils.go | 20 +- x/observer/keeper/utils_test.go | 31 + x/observer/migrations/v4/migrate.go | 47 +- x/observer/migrations/v4/migrate_test.go | 83 ++- x/observer/types/chain_params.go | 321 +++++++++ ...re_params_test.go => chain_params_test.go} | 110 +-- x/observer/types/codec.go | 6 +- x/observer/types/core_params.go | 156 ----- x/observer/types/core_params_test.go | 32 - x/observer/types/errors.go | 10 +- x/observer/types/genesis.go | 4 +- x/observer/types/genesis.pb.go | 99 ++- x/observer/types/genesis_test.go | 13 +- x/observer/types/keys.go | 9 +- .../types/message_remove_chain_params.go | 56 ++ .../types/message_remove_chain_params_test.go | 54 ++ .../types/message_update_chain_params.go | 53 ++ .../types/message_update_chain_params_test.go | 53 ++ .../types/message_update_core_params.go | 112 ---- x/observer/types/params.go | 66 +- x/observer/types/params.pb.go | 412 ++++++++---- x/observer/types/query.pb.go | 601 +++++++++-------- x/observer/types/query.pb.gw.go | 56 +- x/observer/types/tx.pb.go | 634 ++++++++++++++---- zetaclient/bitcoin_client.go | 26 +- zetaclient/config/types.go | 99 +-- zetaclient/evm_client.go | 38 +- zetaclient/inbound_tracker.go | 11 +- zetaclient/interfaces.go | 4 +- zetaclient/query.go | 36 +- zetaclient/zetacore_bridge.go | 25 +- zetaclient/zetacore_observer.go | 27 +- 119 files changed, 3560 insertions(+), 1910 deletions(-) rename docs/cli/zetacored/{zetacored_query_observer_list-core-params.md => zetacored_query_observer_list-chain-params.md} (85%) rename docs/cli/zetacored/{zetacored_query_observer_show-core-params.md => zetacored_query_observer_show-chain-params.md} (83%) rename docs/cli/zetacored/{zetacored_tx_observer_update-client-params.md => zetacored_tx_observer_remove-chain-params.md} (93%) create mode 100644 docs/cli/zetacored/zetacored_tx_observer_update-chain-params.md create mode 100644 x/crosschain/keeper/utils_test.go rename x/observer/client/cli/{query_core_params.go => query_chain_params.go} (69%) create mode 100644 x/observer/client/cli/tx_remove_chain_params.go rename x/observer/client/cli/{tx_update_core_params.go => tx_update_chain_params.go} (72%) create mode 100644 x/observer/keeper/chain_params.go create mode 100644 x/observer/keeper/chain_params_test.go create mode 100644 x/observer/keeper/grpc_query_chain_params.go delete mode 100644 x/observer/keeper/grpc_query_core_params.go create mode 100644 x/observer/keeper/msg_server_remove_chain_params.go create mode 100644 x/observer/keeper/msg_server_remove_chain_params_test.go create mode 100644 x/observer/keeper/msg_server_update_chain_params.go create mode 100644 x/observer/keeper/msg_server_update_chain_params_test.go delete mode 100644 x/observer/keeper/msg_server_update_core_params.go create mode 100644 x/observer/types/chain_params.go rename x/observer/types/{message_update_core_params_test.go => chain_params_test.go} (51%) delete mode 100644 x/observer/types/core_params.go delete mode 100644 x/observer/types/core_params_test.go create mode 100644 x/observer/types/message_remove_chain_params.go create mode 100644 x/observer/types/message_remove_chain_params_test.go create mode 100644 x/observer/types/message_update_chain_params.go create mode 100644 x/observer/types/message_update_chain_params_test.go delete mode 100644 x/observer/types/message_update_core_params.go diff --git a/changelog.md b/changelog.md index 4c357b65d8..4562c21d66 100644 --- a/changelog.md +++ b/changelog.md @@ -41,6 +41,7 @@ * Add pagination to queries which iterate over large data sets InTxTrackerAll ,PendingNoncesAll ,AllBlameRecord ,TssHistory * GetTssAddress now returns only the current tss address for ETH and BTC * Add a new query GetTssAddressesByFinalizedBlockHeight to get any other tss addresses for a finalized block height +* Move observer params into core params * Remove chain id from the index for observer mapper and rename it to observer set. * Add logger to smoke tests * [1521](https://github.com/zeta-chain/node/pull/1521) - replace go-tss lib version with one that reverts back to thorchain tss-lib diff --git a/cmd/zetaclientd/debug.go b/cmd/zetaclientd/debug.go index f2624cc762..1bbb2a7934 100644 --- a/cmd/zetaclientd/debug.go +++ b/cmd/zetaclientd/debug.go @@ -73,7 +73,7 @@ func DebugCmd() *cobra.Command { if err != nil { return err } - coreParams, err := bridge.GetCoreParams() + chainParams, err := bridge.GetChainParams() if err != nil { return err } @@ -115,19 +115,19 @@ func DebugCmd() *cobra.Command { return fmt.Errorf("tx is still pending") } - for _, chainCoreParams := range coreParams { - if chainCoreParams.ChainId == chainID { - ob.WithParams(observertypes.CoreParams{ + for _, chainParams := range chainParams { + if chainParams.ChainId == chainID { + ob.WithParams(observertypes.ChainParams{ ChainId: chainID, - ConnectorContractAddress: chainCoreParams.ConnectorContractAddress, - ZetaTokenContractAddress: chainCoreParams.ZetaTokenContractAddress, - Erc20CustodyContractAddress: chainCoreParams.Erc20CustodyContractAddress, + ConnectorContractAddress: chainParams.ConnectorContractAddress, + ZetaTokenContractAddress: chainParams.ZetaTokenContractAddress, + Erc20CustodyContractAddress: chainParams.Erc20CustodyContractAddress, }) - cfg.EVMChainConfigs[chainID].ZetaTokenContractAddress = chainCoreParams.ZetaTokenContractAddress + cfg.EVMChainConfigs[chainID].ZetaTokenContractAddress = chainParams.ZetaTokenContractAddress ob.SetConfig(cfg) - if strings.EqualFold(tx.To().Hex(), chainCoreParams.ConnectorContractAddress) { + if strings.EqualFold(tx.To().Hex(), chainParams.ConnectorContractAddress) { coinType = common.CoinType_Zeta - } else if strings.EqualFold(tx.To().Hex(), chainCoreParams.Erc20CustodyContractAddress) { + } else if strings.EqualFold(tx.To().Hex(), chainParams.Erc20CustodyContractAddress) { coinType = common.CoinType_ERC20 } else if strings.EqualFold(tx.To().Hex(), tssEthAddress) { coinType = common.CoinType_Gas diff --git a/cmd/zetaclientd/start_utils.go b/cmd/zetaclientd/start_utils.go index 6367a5e2d8..1fcdc1945e 100644 --- a/cmd/zetaclientd/start_utils.go +++ b/cmd/zetaclientd/start_utils.go @@ -68,9 +68,9 @@ func maskCfg(cfg *config.Config) string { maskedCfg.EVMChainConfigs = map[int64]*config.EVMConfig{} for key, val := range cfg.EVMChainConfigs { maskedCfg.EVMChainConfigs[key] = &config.EVMConfig{ - CoreParams: val.CoreParams, - Chain: val.Chain, - Endpoint: val.Endpoint, + ChainParams: val.ChainParams, + Chain: val.Chain, + Endpoint: val.Endpoint, } } diff --git a/cmd/zetaclientd/utils.go b/cmd/zetaclientd/utils.go index d583228d48..9b17b1ef80 100644 --- a/cmd/zetaclientd/utils.go +++ b/cmd/zetaclientd/utils.go @@ -55,8 +55,8 @@ func CreateSignerMap( if evmConfig.Chain.IsZetaChain() { continue } - mpiAddress := ethcommon.HexToAddress(evmConfig.CoreParams.ConnectorContractAddress) - erc20CustodyAddress := ethcommon.HexToAddress(evmConfig.CoreParams.Erc20CustodyContractAddress) + mpiAddress := ethcommon.HexToAddress(evmConfig.ChainParams.ConnectorContractAddress) + erc20CustodyAddress := ethcommon.HexToAddress(evmConfig.ChainParams.Erc20CustodyContractAddress) signer, err := zetaclient.NewEVMSigner(evmConfig.Chain, evmConfig.Endpoint, tss, config.GetConnectorABI(), config.GetERC20CustodyABI(), mpiAddress, erc20CustodyAddress, logger, ts) if err != nil { logger.Error().Err(err).Msgf("NewEVMSigner error for chain %s", evmConfig.Chain.String()) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index bf3fa42540..754f856aa6 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -155,6 +155,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // setting up the networks logger.Print("⚙️ setting up networks") startTime := time.Now() + deployerRunner.SetTSSAddresses() deployerRunner.SetupEVM(contractsDeployed) deployerRunner.SetZEVMContracts() diff --git a/common/chain.go b/common/chain.go index fe19b302bf..ee2b26d855 100644 --- a/common/chain.go +++ b/common/chain.go @@ -189,14 +189,6 @@ func GetChainFromChainID(chainID int64) *Chain { return nil } -func GetChainNameFromChainID(chainID int64) (string, error) { - chain := GetChainFromChainID(chainID) - if chain == nil { - return "", fmt.Errorf("chain %d not found", chainID) - } - return chain.GetChainName().String(), nil -} - func GetBTCChainParams(chainID int64) (*chaincfg.Params, error) { switch chainID { case 18444: diff --git a/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go b/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go index 04e89f2c9f..f742641b38 100644 --- a/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go +++ b/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go @@ -262,50 +262,6 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr str return uniswapV2FactoryAddr, uniswapV2RouterAddr, usdtZRC20Addr, nil } -// InitializeCoreParams sets the core params with local Goerli and BtcRegtest chains enabled -func (zts ZetaTxServer) InitializeCoreParams(account, zetaTokenAddr, connectorAddr, erc20CustodyAddr string) error { - // set goerli localnet core params - goerliCoreParams := &observertypes.CoreParams{ - ChainId: common.GoerliLocalnetChain().ChainId, - ConfirmationCount: 2, - ZetaTokenContractAddress: zetaTokenAddr, - ConnectorContractAddress: connectorAddr, - Erc20CustodyContractAddress: erc20CustodyAddr, - InTxTicker: 2, - OutTxTicker: 2, - WatchUtxoTicker: 0, - GasPriceTicker: 5, - OutboundTxScheduleInterval: 2, - OutboundTxScheduleLookahead: 5, - } - - if err := zts.UpdateCoreParams(account, goerliCoreParams); err != nil { - return fmt.Errorf("failed to set core params for bitcoin: %s", err.Error()) - } - - return nil -} - -// UpdateCoreParams updates the core params -func (zts ZetaTxServer) UpdateCoreParams(account string, cp *observertypes.CoreParams) error { - // retrieve account - acc, err := zts.clientCtx.Keyring.Key(account) - if err != nil { - return err - } - addr, err := acc.GetAddress() - if err != nil { - return err - } - - _, err = zts.BroadcastTx(account, observertypes.NewMsgUpdateCoreParams(addr.String(), cp)) - if err != nil { - return fmt.Errorf("failed to set core params for bitcoin: %s", err.Error()) - } - - return nil -} - // newCodec returns the codec for msg server func newCodec() (*codec.ProtoCodec, codectypes.InterfaceRegistry) { interfaceRegistry := codectypes.NewInterfaceRegistry() diff --git a/contrib/localnet/scripts/start-zetaclientd-genesis.sh b/contrib/localnet/scripts/start-zetaclientd-genesis.sh index ec1b9f305c..1109acaf37 100755 --- a/contrib/localnet/scripts/start-zetaclientd-genesis.sh +++ b/contrib/localnet/scripts/start-zetaclientd-genesis.sh @@ -17,7 +17,7 @@ node="zetacore$num" #mv /root/tss/$HOSTNAME /root/.tss echo "Wait for zetacore to exchange genesis file" -sleep 30 +sleep 40 operator=$(cat $HOME/.zetacored/os.json | jq '.ObserverAddress' ) operatorAddress=$(echo "$operator" | tr -d '"') echo "operatorAddress: $operatorAddress" diff --git a/docs/cli/zetacored/zetacored_query_observer.md b/docs/cli/zetacored/zetacored_query_observer.md index 4b6679e5df..47e5951c7c 100644 --- a/docs/cli/zetacored/zetacored_query_observer.md +++ b/docs/cli/zetacored/zetacored_query_observer.md @@ -30,8 +30,8 @@ zetacored query observer [flags] * [zetacored query observer list-blame](zetacored_query_observer_list-blame.md) - Query AllBlameRecords * [zetacored query observer list-blame-by-msg](zetacored_query_observer_list-blame-by-msg.md) - Query AllBlameRecords * [zetacored query observer list-chain-nonces](zetacored_query_observer_list-chain-nonces.md) - list all chainNonces +* [zetacored query observer list-chain-params](zetacored_query_observer_list-chain-params.md) - Query GetChainParams * [zetacored query observer list-chains](zetacored_query_observer_list-chains.md) - list all SupportedChains -* [zetacored query observer list-core-params](zetacored_query_observer_list-core-params.md) - Query GetCoreParams * [zetacored query observer list-node-account](zetacored_query_observer_list-node-account.md) - list all NodeAccount * [zetacored query observer list-observer-set](zetacored_query_observer_list-observer-set.md) - Query observer set * [zetacored query observer list-pending-nonces](zetacored_query_observer_list-pending-nonces.md) - shows a chainNonces @@ -40,7 +40,7 @@ zetacored query observer [flags] * [zetacored query observer show-ballot](zetacored_query_observer_show-ballot.md) - Query BallotByIdentifier * [zetacored query observer show-blame](zetacored_query_observer_show-blame.md) - Query BlameByIdentifier * [zetacored query observer show-chain-nonces](zetacored_query_observer_show-chain-nonces.md) - shows a chainNonces -* [zetacored query observer show-core-params](zetacored_query_observer_show-core-params.md) - Query GetCoreParamsForChain +* [zetacored query observer show-chain-params](zetacored_query_observer_show-chain-params.md) - Query GetChainParamsForChain * [zetacored query observer show-crosschain-flags](zetacored_query_observer_show-crosschain-flags.md) - shows the crosschain flags * [zetacored query observer show-keygen](zetacored_query_observer_show-keygen.md) - shows keygen * [zetacored query observer show-node-account](zetacored_query_observer_show-node-account.md) - shows a NodeAccount diff --git a/docs/cli/zetacored/zetacored_query_observer_list-core-params.md b/docs/cli/zetacored/zetacored_query_observer_list-chain-params.md similarity index 85% rename from docs/cli/zetacored/zetacored_query_observer_list-core-params.md rename to docs/cli/zetacored/zetacored_query_observer_list-chain-params.md index 4375476625..d655176ef6 100644 --- a/docs/cli/zetacored/zetacored_query_observer_list-core-params.md +++ b/docs/cli/zetacored/zetacored_query_observer_list-chain-params.md @@ -1,9 +1,9 @@ -# query observer list-core-params +# query observer list-chain-params -Query GetCoreParams +Query GetChainParams ``` -zetacored query observer list-core-params [flags] +zetacored query observer list-chain-params [flags] ``` ### Options @@ -12,7 +12,7 @@ zetacored query observer list-core-params [flags] --grpc-addr string the gRPC endpoint to use for this chain --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS --height int Use a specific height to query state at (this can error if the node is pruning state) - -h, --help help for list-core-params + -h, --help help for list-chain-params --node string [host]:[port] to Tendermint RPC interface for this chain -o, --output string Output format (text|json) ``` diff --git a/docs/cli/zetacored/zetacored_query_observer_show-core-params.md b/docs/cli/zetacored/zetacored_query_observer_show-chain-params.md similarity index 83% rename from docs/cli/zetacored/zetacored_query_observer_show-core-params.md rename to docs/cli/zetacored/zetacored_query_observer_show-chain-params.md index ea5651d15e..606024c4a6 100644 --- a/docs/cli/zetacored/zetacored_query_observer_show-core-params.md +++ b/docs/cli/zetacored/zetacored_query_observer_show-chain-params.md @@ -1,9 +1,9 @@ -# query observer show-core-params +# query observer show-chain-params -Query GetCoreParamsForChain +Query GetChainParamsForChain ``` -zetacored query observer show-core-params [chain-id] [flags] +zetacored query observer show-chain-params [chain-id] [flags] ``` ### Options @@ -12,7 +12,7 @@ zetacored query observer show-core-params [chain-id] [flags] --grpc-addr string the gRPC endpoint to use for this chain --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS --height int Use a specific height to query state at (this can error if the node is pruning state) - -h, --help help for show-core-params + -h, --help help for show-chain-params --node string [host]:[port] to Tendermint RPC interface for this chain -o, --output string Output format (text|json) ``` diff --git a/docs/cli/zetacored/zetacored_tx_observer.md b/docs/cli/zetacored/zetacored_tx_observer.md index 72bcc4c47a..5340a1041a 100644 --- a/docs/cli/zetacored/zetacored_tx_observer.md +++ b/docs/cli/zetacored/zetacored_tx_observer.md @@ -28,7 +28,8 @@ zetacored tx observer [flags] * [zetacored tx observer add-blame-vote](zetacored_tx_observer_add-blame-vote.md) - Broadcast message add-blame-vote * [zetacored tx observer add-observer](zetacored_tx_observer_add-observer.md) - Broadcast message add-observer * [zetacored tx observer encode](zetacored_tx_observer_encode.md) - Encode a json string into hex -* [zetacored tx observer update-client-params](zetacored_tx_observer_update-client-params.md) - Broadcast message updateClientParams +* [zetacored tx observer remove-chain-params](zetacored_tx_observer_remove-chain-params.md) - Broadcast message to remove chain params +* [zetacored tx observer update-chain-params](zetacored_tx_observer_update-chain-params.md) - Broadcast message updateChainParams * [zetacored tx observer update-crosschain-flags](zetacored_tx_observer_update-crosschain-flags.md) - Update crosschain flags * [zetacored tx observer update-keygen](zetacored_tx_observer_update-keygen.md) - command to update the keygen block via a group proposal * [zetacored tx observer update-observer](zetacored_tx_observer_update-observer.md) - Broadcast message add-observer diff --git a/docs/cli/zetacored/zetacored_tx_observer_update-client-params.md b/docs/cli/zetacored/zetacored_tx_observer_remove-chain-params.md similarity index 93% rename from docs/cli/zetacored/zetacored_tx_observer_update-client-params.md rename to docs/cli/zetacored/zetacored_tx_observer_remove-chain-params.md index e1505b3bfc..8aa627e56f 100644 --- a/docs/cli/zetacored/zetacored_tx_observer_update-client-params.md +++ b/docs/cli/zetacored/zetacored_tx_observer_remove-chain-params.md @@ -1,9 +1,9 @@ -# tx observer update-client-params +# tx observer remove-chain-params -Broadcast message updateClientParams +Broadcast message to remove chain params ``` -zetacored tx observer update-client-params [chain-id] [client-params.json] [flags] +zetacored tx observer remove-chain-params [chain-id] [flags] ``` ### Options @@ -21,7 +21,7 @@ zetacored tx observer update-client-params [chain-id] [client-params.json] [flag --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) - -h, --help help for update-client-params + -h, --help help for remove-chain-params --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used --ledger Use a connected Ledger device diff --git a/docs/cli/zetacored/zetacored_tx_observer_update-chain-params.md b/docs/cli/zetacored/zetacored_tx_observer_update-chain-params.md new file mode 100644 index 0000000000..49e73e71d2 --- /dev/null +++ b/docs/cli/zetacored/zetacored_tx_observer_update-chain-params.md @@ -0,0 +1,52 @@ +# tx observer update-chain-params + +Broadcast message updateChainParams + +``` +zetacored tx observer update-chain-params [chain-id] [client-params.json] [flags] +``` + +### Options + +``` + -a, --account-number uint The account number of the signing account (offline mode only) + --aux Generate aux signer data instead of sending a tx + -b, --broadcast-mode string Transaction broadcasting mode (sync|async|block) + --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) + --fee-granter string Fee granter grants fees for the transaction + --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer + --fees string Fees to pay along with transaction; eg: 10uatom + --from string Name or address of private key with which to sign + --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) + --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) + --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) + --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) + -h, --help help for update-chain-params + --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) + --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used + --ledger Use a connected Ledger device + --node string [host]:[port] to tendermint rpc interface for this chain + --note string Note to add a description to the transaction (previously --memo) + --offline Offline mode (does not allow any online functionality) + -o, --output string Output format (text|json) + -s, --sequence uint The sequence number of the signing account (offline mode only) + --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature + --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height + --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator + -y, --yes Skip tx broadcasting prompt confirmation +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored tx observer](zetacored_tx_observer.md) - observer transactions subcommands + diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 23743e4e66..6d8b1c4e18 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27762,40 +27762,40 @@ paths: format: int64 tags: - Query - /zeta-chain/observer/get_client_params_for_chain/{chain_id}: + /zeta-chain/observer/get_chain_params: get: - summary: Queries a list of GetClientParamsForChain items. - operationId: Query_GetCoreParamsForChain + summary: Queries a list of GetChainParams items. + operationId: Query_GetChainParams responses: "200": description: A successful response. schema: - $ref: '#/definitions/observerQueryGetCoreParamsForChainResponse' + $ref: '#/definitions/observerQueryGetChainParamsResponse' default: description: An unexpected error response. schema: $ref: '#/definitions/googlerpcStatus' - parameters: - - name: chain_id - in: path - required: true - type: string - format: int64 tags: - Query - /zeta-chain/observer/get_core_params: + /zeta-chain/observer/get_chain_params_for_chain/{chain_id}: get: - summary: Queries a list of GetCoreParams items. - operationId: Query_GetCoreParams + summary: Queries a list of GetChainParamsForChain items. + operationId: Query_GetChainParamsForChain responses: "200": description: A successful response. schema: - $ref: '#/definitions/observerQueryGetCoreParamsResponse' + $ref: '#/definitions/observerQueryGetChainParamsForChainResponse' default: description: An unexpected error response. schema: $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: path + required: true + type: string + format: int64 tags: - Query /zeta-chain/observer/get_tss_address: @@ -51287,9 +51287,12 @@ definitions: finalizedHeight: type: string format: uint64 - observerCoreParams: + observerChainParams: type: object properties: + chain_id: + type: string + format: int64 confirmation_count: type: string format: uint64 @@ -51311,23 +51314,26 @@ definitions: type: string erc20_custody_contract_address: type: string - chain_id: - type: string - format: int64 outbound_tx_schedule_interval: type: string format: int64 outbound_tx_schedule_lookahead: type: string format: int64 - observerCoreParamsList: + ballot_threshold: + type: string + min_observer_delegation: + type: string + is_supported: + type: boolean + observerChainParamsList: type: object properties: - core_params: + chain_params: type: array items: type: object - $ref: '#/definitions/observerCoreParams' + $ref: '#/definitions/observerChainParams' observerCrosschainFlags: type: object properties: @@ -51396,7 +51402,9 @@ definitions: type: object observerMsgAddObserverResponse: type: object - observerMsgUpdateCoreParamsResponse: + observerMsgRemoveChainParamsResponse: + type: object + observerMsgUpdateChainParamsResponse: type: object observerMsgUpdateCrosschainFlagsResponse: type: object @@ -51456,6 +51464,7 @@ definitions: type: string is_supported: type: boolean + title: 'Deprecated: Use ChainParamsList' observerObserverUpdateReason: type: string enum: @@ -51576,16 +51585,16 @@ definitions: properties: ChainNonces: $ref: '#/definitions/observerChainNonces' - observerQueryGetCoreParamsForChainResponse: + observerQueryGetChainParamsForChainResponse: type: object properties: - core_params: - $ref: '#/definitions/observerCoreParams' - observerQueryGetCoreParamsResponse: + chain_params: + $ref: '#/definitions/observerChainParams' + observerQueryGetChainParamsResponse: type: object properties: - core_params: - $ref: '#/definitions/observerCoreParamsList' + chain_params: + $ref: '#/definitions/observerChainParamsList' observerQueryGetCrosschainFlagsResponse: type: object properties: @@ -51843,6 +51852,7 @@ definitions: items: type: object $ref: '#/definitions/observerObserverParams' + title: 'Deprecated: Use ChainParamsList' admin_policy: type: array items: diff --git a/docs/spec/observer/messages.md b/docs/spec/observer/messages.md index 66bf781d9a..63e75cbe7c 100644 --- a/docs/spec/observer/messages.md +++ b/docs/spec/observer/messages.md @@ -15,6 +15,7 @@ message MsgAddObserver { ## MsgUpdateObserver +UpdateObserver handles updating an observer address Authorized: admin policy group 2 (admin update), old observer address (if the reason is that the observer was tombstoned). @@ -27,20 +28,28 @@ message MsgUpdateObserver { } ``` -## MsgUpdateCoreParams +## MsgUpdateChainParams -UpdateCoreParams updates core parameters for a specific chain. Core parameters include -confirmation count, outbound transaction schedule interval, ZETA token, +UpdateChainParams updates chain parameters for a specific chain, or add a new one. +Chain parameters include: confirmation count, outbound transaction schedule interval, ZETA token, connector and ERC20 custody contract addresses, etc. +Only the admin policy account is authorized to broadcast this message. + +```proto +message MsgUpdateChainParams { + string creator = 1; + ChainParams chainParams = 2; +} +``` -Throws an error if the chain ID is not supported. +## MsgRemoveChainParams -Only the admin policy account is authorized to broadcast this message. +RemoveChainParams removes chain parameters for a specific chain. ```proto -message MsgUpdateCoreParams { +message MsgRemoveChainParams { string creator = 1; - CoreParams coreParams = 2; + int64 chain_id = 2; } ``` diff --git a/proto/observer/genesis.proto b/proto/observer/genesis.proto index b8aaef283d..2501c5120f 100644 --- a/proto/observer/genesis.proto +++ b/proto/observer/genesis.proto @@ -25,7 +25,7 @@ message GenesisState { Params params = 5; Keygen keygen = 6; LastObserverCount last_observer_count = 7; - CoreParamsList core_params_list = 8 [(gogoproto.nullable) = false]; + ChainParamsList chain_params_list = 8 [(gogoproto.nullable) = false]; TSS tss = 9; repeated TSS tss_history = 10 [(gogoproto.nullable) = false]; repeated TssFundMigratorInfo tss_fund_migrators = 11 [(gogoproto.nullable) = false]; diff --git a/proto/observer/params.proto b/proto/observer/params.proto index 4d403b99d0..7ad2d5ebf2 100644 --- a/proto/observer/params.proto +++ b/proto/observer/params.proto @@ -7,10 +7,11 @@ import "observer/observer.proto"; option go_package = "github.com/zeta-chain/zetacore/x/observer/types"; -message CoreParamsList { - repeated CoreParams core_params = 1; +message ChainParamsList { + repeated ChainParams chain_params = 1; } -message CoreParams { +message ChainParams { + int64 chain_id = 11; uint64 confirmation_count = 1; uint64 gas_price_ticker = 2; uint64 in_tx_ticker = 3; @@ -19,11 +20,20 @@ message CoreParams { string zeta_token_contract_address = 8; string connector_contract_address = 9; string erc20_custody_contract_address = 10; - int64 chain_id = 11; int64 outbound_tx_schedule_interval = 12; int64 outbound_tx_schedule_lookahead = 13; + string ballot_threshold = 14 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string min_observer_delegation = 15 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bool is_supported = 16; } +// Deprecated: Use ChainParamsList message ObserverParams { common.Chain chain = 1; string ballot_threshold = 3 [ @@ -51,7 +61,10 @@ message Admin_Policy { // Params defines the parameters for the module. message Params { option (gogoproto.goproto_stringer) = false; + + // Deprecated: Use ChainParamsList repeated ObserverParams observer_params = 1; + repeated Admin_Policy admin_policy = 2; int64 ballot_maturity_blocks = 3; } diff --git a/proto/observer/query.proto b/proto/observer/query.proto index 2796372004..6fb0fc291d 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -43,14 +43,14 @@ service Query { option (google.api.http).get = "/zeta-chain/observer/supportedChains"; } - // Queries a list of GetClientParamsForChain items. - rpc GetCoreParamsForChain(QueryGetCoreParamsForChainRequest) returns (QueryGetCoreParamsForChainResponse) { - option (google.api.http).get = "/zeta-chain/observer/get_client_params_for_chain/{chain_id}"; + // Queries a list of GetChainParamsForChain items. + rpc GetChainParamsForChain(QueryGetChainParamsForChainRequest) returns (QueryGetChainParamsForChainResponse) { + option (google.api.http).get = "/zeta-chain/observer/get_chain_params_for_chain/{chain_id}"; } - // Queries a list of GetCoreParams items. - rpc GetCoreParams(QueryGetCoreParamsRequest) returns (QueryGetCoreParamsResponse) { - option (google.api.http).get = "/zeta-chain/observer/get_core_params"; + // Queries a list of GetChainParams items. + rpc GetChainParams(QueryGetChainParamsRequest) returns (QueryGetChainParamsResponse) { + option (google.api.http).get = "/zeta-chain/observer/get_chain_params"; } // Queries a nodeAccount by index. @@ -270,18 +270,18 @@ message QuerySupportedChainsResponse { repeated common.Chain chains = 1; } -message QueryGetCoreParamsForChainRequest { +message QueryGetChainParamsForChainRequest { int64 chain_id = 1; } -message QueryGetCoreParamsForChainResponse { - CoreParams core_params = 1; +message QueryGetChainParamsForChainResponse { + ChainParams chain_params = 1; } -message QueryGetCoreParamsRequest {} +message QueryGetChainParamsRequest {} -message QueryGetCoreParamsResponse { - CoreParamsList core_params = 1; +message QueryGetChainParamsResponse { + ChainParamsList chain_params = 1; } message QueryGetNodeAccountRequest { diff --git a/proto/observer/tx.proto b/proto/observer/tx.proto index 8198d12924..b67e8e0741 100644 --- a/proto/observer/tx.proto +++ b/proto/observer/tx.proto @@ -16,7 +16,8 @@ option go_package = "github.com/zeta-chain/zetacore/x/observer/types"; service Msg { rpc AddObserver(MsgAddObserver) returns (MsgAddObserverResponse); rpc UpdateObserver(MsgUpdateObserver) returns (MsgUpdateObserverResponse); - rpc UpdateCoreParams(MsgUpdateCoreParams) returns (MsgUpdateCoreParamsResponse); + rpc UpdateChainParams(MsgUpdateChainParams) returns (MsgUpdateChainParamsResponse); + rpc RemoveChainParams(MsgRemoveChainParams) returns (MsgRemoveChainParamsResponse); rpc AddBlameVote(MsgAddBlameVote) returns (MsgAddBlameVoteResponse); rpc UpdateCrosschainFlags(MsgUpdateCrosschainFlags) returns (MsgUpdateCrosschainFlagsResponse); rpc UpdateKeygen(MsgUpdateKeygen) returns (MsgUpdateKeygenResponse); @@ -41,12 +42,19 @@ message MsgAddBlockHeader { message MsgAddBlockHeaderResponse {} -message MsgUpdateCoreParams { +message MsgUpdateChainParams { string creator = 1; - CoreParams coreParams = 2; + ChainParams chainParams = 2; } -message MsgUpdateCoreParamsResponse {} +message MsgUpdateChainParamsResponse {} + +message MsgRemoveChainParams { + string creator = 1; + int64 chain_id = 2; +} + +message MsgRemoveChainParamsResponse {} message MsgAddObserver { string creator = 1; diff --git a/testutil/keeper/mocks/crosschain/account.go b/testutil/keeper/mocks/crosschain/account.go index c54fb001d8..274a79766d 100644 --- a/testutil/keeper/mocks/crosschain/account.go +++ b/testutil/keeper/mocks/crosschain/account.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/bank.go b/testutil/keeper/mocks/crosschain/bank.go index 76bacb53a8..278cccb833 100644 --- a/testutil/keeper/mocks/crosschain/bank.go +++ b/testutil/keeper/mocks/crosschain/bank.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index 69f51cc939..b40bd35c40 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index 369062b2fb..5000f37e03 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks @@ -377,24 +377,24 @@ func (_m *CrosschainObserverKeeper) GetChainNonces(ctx types.Context, index stri return r0, r1 } -// GetCoreParamsByChainID provides a mock function with given fields: ctx, chainID -func (_m *CrosschainObserverKeeper) GetCoreParamsByChainID(ctx types.Context, chainID int64) (*observertypes.CoreParams, bool) { +// GetChainParamsByChainID provides a mock function with given fields: ctx, chainID +func (_m *CrosschainObserverKeeper) GetChainParamsByChainID(ctx types.Context, chainID int64) (*observertypes.ChainParams, bool) { ret := _m.Called(ctx, chainID) if len(ret) == 0 { - panic("no return value specified for GetCoreParamsByChainID") + panic("no return value specified for GetChainParamsByChainID") } - var r0 *observertypes.CoreParams + var r0 *observertypes.ChainParams var r1 bool - if rf, ok := ret.Get(0).(func(types.Context, int64) (*observertypes.CoreParams, bool)); ok { + if rf, ok := ret.Get(0).(func(types.Context, int64) (*observertypes.ChainParams, bool)); ok { return rf(ctx, chainID) } - if rf, ok := ret.Get(0).(func(types.Context, int64) *observertypes.CoreParams); ok { + if rf, ok := ret.Get(0).(func(types.Context, int64) *observertypes.ChainParams); ok { r0 = rf(ctx, chainID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*observertypes.CoreParams) + r0 = ret.Get(0).(*observertypes.ChainParams) } } @@ -649,6 +649,46 @@ func (_m *CrosschainObserverKeeper) GetPreviousTSS(ctx types.Context) (observert return r0, r1 } +// GetSupportedChainFromChainID provides a mock function with given fields: ctx, chainID +func (_m *CrosschainObserverKeeper) GetSupportedChainFromChainID(ctx types.Context, chainID int64) *common.Chain { + ret := _m.Called(ctx, chainID) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedChainFromChainID") + } + + var r0 *common.Chain + if rf, ok := ret.Get(0).(func(types.Context, int64) *common.Chain); ok { + r0 = rf(ctx, chainID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*common.Chain) + } + } + + return r0 +} + +// GetSupportedChains provides a mock function with given fields: ctx +func (_m *CrosschainObserverKeeper) GetSupportedChains(ctx types.Context) []*common.Chain { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedChains") + } + + var r0 []*common.Chain + if rf, ok := ret.Get(0).(func(types.Context) []*common.Chain); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*common.Chain) + } + } + + return r0 +} + // GetTSS provides a mock function with given fields: ctx func (_m *CrosschainObserverKeeper) GetTSS(ctx types.Context) (observertypes.TSS, bool) { ret := _m.Called(ctx) diff --git a/testutil/keeper/mocks/crosschain/staking.go b/testutil/keeper/mocks/crosschain/staking.go index a72a747e5a..772bb09971 100644 --- a/testutil/keeper/mocks/crosschain/staking.go +++ b/testutil/keeper/mocks/crosschain/staking.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/account.go b/testutil/keeper/mocks/fungible/account.go index 0522e833b4..94b7a84d75 100644 --- a/testutil/keeper/mocks/fungible/account.go +++ b/testutil/keeper/mocks/fungible/account.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/bank.go b/testutil/keeper/mocks/fungible/bank.go index 5b9fb0dd04..d44da595c0 100644 --- a/testutil/keeper/mocks/fungible/bank.go +++ b/testutil/keeper/mocks/fungible/bank.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/evm.go b/testutil/keeper/mocks/fungible/evm.go index f42cc011a3..64c041b22d 100644 --- a/testutil/keeper/mocks/fungible/evm.go +++ b/testutil/keeper/mocks/fungible/evm.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks diff --git a/testutil/keeper/mocks/fungible/observer.go b/testutil/keeper/mocks/fungible/observer.go index 479fda3f80..a808da6d5f 100644 --- a/testutil/keeper/mocks/fungible/observer.go +++ b/testutil/keeper/mocks/fungible/observer.go @@ -1,10 +1,11 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.39.1. DO NOT EDIT. package mocks import ( mock "github.com/stretchr/testify/mock" + "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" types "github.com/cosmos/cosmos-sdk/types" @@ -63,24 +64,24 @@ func (_m *FungibleObserverKeeper) GetBallot(ctx types.Context, index string) (ob return r0, r1 } -// GetCoreParamsByChainID provides a mock function with given fields: ctx, chainID -func (_m *FungibleObserverKeeper) GetCoreParamsByChainID(ctx types.Context, chainID int64) (*observertypes.CoreParams, bool) { +// GetChainParamsByChainID provides a mock function with given fields: ctx, chainID +func (_m *FungibleObserverKeeper) GetChainParamsByChainID(ctx types.Context, chainID int64) (*observertypes.ChainParams, bool) { ret := _m.Called(ctx, chainID) if len(ret) == 0 { - panic("no return value specified for GetCoreParamsByChainID") + panic("no return value specified for GetChainParamsByChainID") } - var r0 *observertypes.CoreParams + var r0 *observertypes.ChainParams var r1 bool - if rf, ok := ret.Get(0).(func(types.Context, int64) (*observertypes.CoreParams, bool)); ok { + if rf, ok := ret.Get(0).(func(types.Context, int64) (*observertypes.ChainParams, bool)); ok { return rf(ctx, chainID) } - if rf, ok := ret.Get(0).(func(types.Context, int64) *observertypes.CoreParams); ok { + if rf, ok := ret.Get(0).(func(types.Context, int64) *observertypes.ChainParams); ok { r0 = rf(ctx, chainID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*observertypes.CoreParams) + r0 = ret.Get(0).(*observertypes.ChainParams) } } @@ -159,6 +160,26 @@ func (_m *FungibleObserverKeeper) GetParams(ctx types.Context) observertypes.Par return r0 } +// GetSupportedChains provides a mock function with given fields: ctx +func (_m *FungibleObserverKeeper) GetSupportedChains(ctx types.Context) []*common.Chain { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedChains") + } + + var r0 []*common.Chain + if rf, ok := ret.Get(0).(func(types.Context) []*common.Chain); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*common.Chain) + } + } + + return r0 +} + // SetBallot provides a mock function with given fields: ctx, ballot func (_m *FungibleObserverKeeper) SetBallot(ctx types.Context, ballot *observertypes.Ballot) { _m.Called(ctx, ballot) diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index 550b8190da..a88018e8f7 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -105,19 +105,21 @@ func SetupZetaGenesisState(t *testing.T, genesisState map[string]json.RawMessage func AddObserverData(t *testing.T, n int, genesisState map[string]json.RawMessage, codec codec.Codec, ballots []*observertypes.Ballot) *observertypes.GenesisState { state := observertypes.GenesisState{} assert.NoError(t, codec.UnmarshalJSON(genesisState[observertypes.ModuleName], &state)) + + // set chain params with chains all enabled + state.ChainParamsList = observertypes.GetDefaultChainParams() + for i := range state.ChainParamsList.ChainParams { + state.ChainParamsList.ChainParams[i].IsSupported = true + } + + // set params if len(ballots) > 0 { state.Ballots = ballots } - //params := observerTypes.DefaultParams() - //params.BallotMaturityBlocks = 3 state.Params.BallotMaturityBlocks = 3 state.Keygen = &observertypes.Keygen{BlockNumber: 10, GranteePubkeys: []string{}} - crosschainFlags := &observertypes.CrosschainFlags{ - IsInboundEnabled: true, - IsOutboundEnabled: true, - GasPriceIncreaseFlags: &observertypes.DefaultGasPriceIncreaseFlags, - BlockHeaderVerificationFlags: &observertypes.DefaultBlockHeaderVerificationFlags, - } + + // set tss tss := observertypes.TSS{ TssPubkey: "tssPubkey", TssParticipantList: []string{"tssParticipantList"}, @@ -126,9 +128,15 @@ func AddObserverData(t *testing.T, n int, genesisState map[string]json.RawMessag KeyGenZetaHeight: 1, } state.Tss = &tss - state.TssHistory = []observertypes.TSS{tss} + // set crosschain flags + crosschainFlags := &observertypes.CrosschainFlags{ + IsInboundEnabled: true, + IsOutboundEnabled: true, + GasPriceIncreaseFlags: &observertypes.DefaultGasPriceIncreaseFlags, + BlockHeaderVerificationFlags: &observertypes.DefaultBlockHeaderVerificationFlags, + } nullify.Fill(&crosschainFlags) state.CrosschainFlags = crosschainFlags @@ -136,8 +144,10 @@ func AddObserverData(t *testing.T, n int, genesisState map[string]json.RawMessag state.ChainNonces = append(state.ChainNonces, observertypes.ChainNonces{Creator: "ANY", Index: strconv.Itoa(i), Signers: []string{}}) } + // check genesis state validity assert.NoError(t, state.Validate()) + // marshal genesis state buf, err := codec.MarshalJSON(&state) assert.NoError(t, err) genesisState[observertypes.ModuleName] = buf diff --git a/testutil/sample/observer.go b/testutil/sample/observer.go index 0fdf820573..19b186e845 100644 --- a/testutil/sample/observer.go +++ b/testutil/sample/observer.go @@ -76,29 +76,44 @@ func LastObserverCount(lastChangeHeight int64) *types.LastObserverCount { } } -func CoreParams(chainID int64) *types.CoreParams { +func ChainParams(chainID int64) *types.ChainParams { r := newRandFromSeed(chainID) - return &types.CoreParams{ - ChainId: chainID, - ConfirmationCount: r.Uint64(), - GasPriceTicker: r.Uint64(), - InTxTicker: r.Uint64(), - OutTxTicker: r.Uint64(), - WatchUtxoTicker: r.Uint64(), + fiftyPercent, err := sdk.NewDecFromStr("0.5") + if err != nil { + return nil + } + + return &types.ChainParams{ + ChainId: chainID, + ConfirmationCount: r.Uint64(), + + GasPriceTicker: Uint64InRange(r, 1, 300), + InTxTicker: Uint64InRange(r, 1, 300), + OutTxTicker: Uint64InRange(r, 1, 300), + WatchUtxoTicker: Uint64InRange(r, 1, 300), ZetaTokenContractAddress: EthAddress().String(), ConnectorContractAddress: EthAddress().String(), Erc20CustodyContractAddress: EthAddress().String(), - OutboundTxScheduleInterval: r.Int63(), - OutboundTxScheduleLookahead: r.Int63(), + OutboundTxScheduleInterval: Int64InRange(r, 1, 100), + OutboundTxScheduleLookahead: Int64InRange(r, 1, 500), + BallotThreshold: fiftyPercent, + MinObserverDelegation: sdk.NewDec(r.Int63()), + IsSupported: false, } } -func CoreParamsList() (cpl types.CoreParamsList) { +func ChainParamsSupported(chainID int64) *types.ChainParams { + cp := ChainParams(chainID) + cp.IsSupported = true + return cp +} + +func ChainParamsList() (cpl types.ChainParamsList) { chainList := common.PrivnetChainList() for _, chain := range chainList { - cpl.CoreParams = append(cpl.CoreParams, CoreParams(chain.ChainId)) + cpl.ChainParams = append(cpl.ChainParams, ChainParams(chain.ChainId)) } return } diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 9085e7350c..37bb1883e4 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -129,3 +129,13 @@ func StringRandom(r *rand.Rand, length int) string { func Coins() sdk.Coins { return sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewInt(42))) } + +// Uint64InRange returns a sample uint64 in the given ranges +func Uint64InRange(r *rand.Rand, low, high uint64) uint64 { + return r.Uint64()%(high-low) + low +} + +// Int64InRange returns a sample int64 in the given ranges +func Int64InRange(r *rand.Rand, low, high int64) int64 { + return r.Int63()%(high-low) + low +} diff --git a/typescript/observer/genesis_pb.d.ts b/typescript/observer/genesis_pb.d.ts index 8325515c35..8d0726f3cc 100644 --- a/typescript/observer/genesis_pb.d.ts +++ b/typescript/observer/genesis_pb.d.ts @@ -9,7 +9,7 @@ import type { Ballot } from "./ballot_pb.js"; import type { LastObserverCount, ObserverSet } from "./observer_pb.js"; import type { NodeAccount } from "./node_account_pb.js"; import type { CrosschainFlags } from "./crosschain_flags_pb.js"; -import type { CoreParamsList, Params } from "./params_pb.js"; +import type { ChainParamsList, Params } from "./params_pb.js"; import type { Keygen } from "./keygen_pb.js"; import type { TSS } from "./tss_pb.js"; import type { TssFundMigratorInfo } from "./tss_funds_migrator_pb.js"; @@ -58,9 +58,9 @@ export declare class GenesisState extends Message { lastObserverCount?: LastObserverCount; /** - * @generated from field: zetachain.zetacore.observer.CoreParamsList core_params_list = 8; + * @generated from field: zetachain.zetacore.observer.ChainParamsList chain_params_list = 8; */ - coreParamsList?: CoreParamsList; + chainParamsList?: ChainParamsList; /** * @generated from field: zetachain.zetacore.observer.TSS tss = 9; diff --git a/typescript/observer/params_pb.d.ts b/typescript/observer/params_pb.d.ts index e4f67dc239..9825349298 100644 --- a/typescript/observer/params_pb.d.ts +++ b/typescript/observer/params_pb.d.ts @@ -23,33 +23,38 @@ export declare enum Policy_Type { } /** - * @generated from message zetachain.zetacore.observer.CoreParamsList + * @generated from message zetachain.zetacore.observer.ChainParamsList */ -export declare class CoreParamsList extends Message { +export declare class ChainParamsList extends Message { /** - * @generated from field: repeated zetachain.zetacore.observer.CoreParams core_params = 1; + * @generated from field: repeated zetachain.zetacore.observer.ChainParams chain_params = 1; */ - coreParams: CoreParams[]; + chainParams: ChainParams[]; - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.CoreParamsList"; + static readonly typeName = "zetachain.zetacore.observer.ChainParamsList"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): CoreParamsList; + static fromBinary(bytes: Uint8Array, options?: Partial): ChainParamsList; - static fromJson(jsonValue: JsonValue, options?: Partial): CoreParamsList; + static fromJson(jsonValue: JsonValue, options?: Partial): ChainParamsList; - static fromJsonString(jsonString: string, options?: Partial): CoreParamsList; + static fromJsonString(jsonString: string, options?: Partial): ChainParamsList; - static equals(a: CoreParamsList | PlainMessage | undefined, b: CoreParamsList | PlainMessage | undefined): boolean; + static equals(a: ChainParamsList | PlainMessage | undefined, b: ChainParamsList | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.CoreParams + * @generated from message zetachain.zetacore.observer.ChainParams */ -export declare class CoreParams extends Message { +export declare class ChainParams extends Message { + /** + * @generated from field: int64 chain_id = 11; + */ + chainId: bigint; + /** * @generated from field: uint64 confirmation_count = 1; */ @@ -90,11 +95,6 @@ export declare class CoreParams extends Message { */ erc20CustodyContractAddress: string; - /** - * @generated from field: int64 chain_id = 11; - */ - chainId: bigint; - /** * @generated from field: int64 outbound_tx_schedule_interval = 12; */ @@ -105,22 +105,39 @@ export declare class CoreParams extends Message { */ outboundTxScheduleLookahead: bigint; - constructor(data?: PartialMessage); + /** + * @generated from field: string ballot_threshold = 14; + */ + ballotThreshold: string; + + /** + * @generated from field: string min_observer_delegation = 15; + */ + minObserverDelegation: string; + + /** + * @generated from field: bool is_supported = 16; + */ + isSupported: boolean; + + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.CoreParams"; + static readonly typeName = "zetachain.zetacore.observer.ChainParams"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): CoreParams; + static fromBinary(bytes: Uint8Array, options?: Partial): ChainParams; - static fromJson(jsonValue: JsonValue, options?: Partial): CoreParams; + static fromJson(jsonValue: JsonValue, options?: Partial): ChainParams; - static fromJsonString(jsonString: string, options?: Partial): CoreParams; + static fromJsonString(jsonString: string, options?: Partial): ChainParams; - static equals(a: CoreParams | PlainMessage | undefined, b: CoreParams | PlainMessage | undefined): boolean; + static equals(a: ChainParams | PlainMessage | undefined, b: ChainParams | PlainMessage | undefined): boolean; } /** + * Deprecated: Use ChainParamsList + * * @generated from message zetachain.zetacore.observer.ObserverParams */ export declare class ObserverParams extends Message { @@ -195,6 +212,8 @@ export declare class Admin_Policy extends Message { */ export declare class Params extends Message { /** + * Deprecated: Use ChainParamsList + * * @generated from field: repeated zetachain.zetacore.observer.ObserverParams observer_params = 1; */ observerParams: ObserverParams[]; diff --git a/typescript/observer/query_pb.d.ts b/typescript/observer/query_pb.d.ts index 273f51c470..b346e34a87 100644 --- a/typescript/observer/query_pb.d.ts +++ b/typescript/observer/query_pb.d.ts @@ -10,7 +10,7 @@ import type { PageRequest, PageResponse } from "../cosmos/base/query/v1beta1/pag import type { PendingNonces } from "./pending_nonces_pb.js"; import type { TSS } from "./tss_pb.js"; import type { BlockHeader, Chain, Proof } from "../common/common_pb.js"; -import type { CoreParams, CoreParamsList, Params } from "./params_pb.js"; +import type { ChainParams, ChainParamsList, Params } from "./params_pb.js"; import type { BallotStatus, VoteType } from "./ballot_pb.js"; import type { LastObserverCount, ObservationType } from "./observer_pb.js"; import type { NodeAccount } from "./node_account_pb.js"; @@ -775,94 +775,94 @@ export declare class QuerySupportedChainsResponse extends Message { +export declare class QueryGetChainParamsForChainRequest extends Message { /** * @generated from field: int64 chain_id = 1; */ chainId: bigint; - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryGetCoreParamsForChainRequest"; + static readonly typeName = "zetachain.zetacore.observer.QueryGetChainParamsForChainRequest"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetCoreParamsForChainRequest; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetChainParamsForChainRequest; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetCoreParamsForChainRequest; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetChainParamsForChainRequest; - static fromJsonString(jsonString: string, options?: Partial): QueryGetCoreParamsForChainRequest; + static fromJsonString(jsonString: string, options?: Partial): QueryGetChainParamsForChainRequest; - static equals(a: QueryGetCoreParamsForChainRequest | PlainMessage | undefined, b: QueryGetCoreParamsForChainRequest | PlainMessage | undefined): boolean; + static equals(a: QueryGetChainParamsForChainRequest | PlainMessage | undefined, b: QueryGetChainParamsForChainRequest | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.QueryGetCoreParamsForChainResponse + * @generated from message zetachain.zetacore.observer.QueryGetChainParamsForChainResponse */ -export declare class QueryGetCoreParamsForChainResponse extends Message { +export declare class QueryGetChainParamsForChainResponse extends Message { /** - * @generated from field: zetachain.zetacore.observer.CoreParams core_params = 1; + * @generated from field: zetachain.zetacore.observer.ChainParams chain_params = 1; */ - coreParams?: CoreParams; + chainParams?: ChainParams; - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryGetCoreParamsForChainResponse"; + static readonly typeName = "zetachain.zetacore.observer.QueryGetChainParamsForChainResponse"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetCoreParamsForChainResponse; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetChainParamsForChainResponse; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetCoreParamsForChainResponse; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetChainParamsForChainResponse; - static fromJsonString(jsonString: string, options?: Partial): QueryGetCoreParamsForChainResponse; + static fromJsonString(jsonString: string, options?: Partial): QueryGetChainParamsForChainResponse; - static equals(a: QueryGetCoreParamsForChainResponse | PlainMessage | undefined, b: QueryGetCoreParamsForChainResponse | PlainMessage | undefined): boolean; + static equals(a: QueryGetChainParamsForChainResponse | PlainMessage | undefined, b: QueryGetChainParamsForChainResponse | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.QueryGetCoreParamsRequest + * @generated from message zetachain.zetacore.observer.QueryGetChainParamsRequest */ -export declare class QueryGetCoreParamsRequest extends Message { - constructor(data?: PartialMessage); +export declare class QueryGetChainParamsRequest extends Message { + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryGetCoreParamsRequest"; + static readonly typeName = "zetachain.zetacore.observer.QueryGetChainParamsRequest"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetCoreParamsRequest; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetChainParamsRequest; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetCoreParamsRequest; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetChainParamsRequest; - static fromJsonString(jsonString: string, options?: Partial): QueryGetCoreParamsRequest; + static fromJsonString(jsonString: string, options?: Partial): QueryGetChainParamsRequest; - static equals(a: QueryGetCoreParamsRequest | PlainMessage | undefined, b: QueryGetCoreParamsRequest | PlainMessage | undefined): boolean; + static equals(a: QueryGetChainParamsRequest | PlainMessage | undefined, b: QueryGetChainParamsRequest | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.QueryGetCoreParamsResponse + * @generated from message zetachain.zetacore.observer.QueryGetChainParamsResponse */ -export declare class QueryGetCoreParamsResponse extends Message { +export declare class QueryGetChainParamsResponse extends Message { /** - * @generated from field: zetachain.zetacore.observer.CoreParamsList core_params = 1; + * @generated from field: zetachain.zetacore.observer.ChainParamsList chain_params = 1; */ - coreParams?: CoreParamsList; + chainParams?: ChainParamsList; - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.QueryGetCoreParamsResponse"; + static readonly typeName = "zetachain.zetacore.observer.QueryGetChainParamsResponse"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetCoreParamsResponse; + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetChainParamsResponse; - static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetCoreParamsResponse; + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetChainParamsResponse; - static fromJsonString(jsonString: string, options?: Partial): QueryGetCoreParamsResponse; + static fromJsonString(jsonString: string, options?: Partial): QueryGetChainParamsResponse; - static equals(a: QueryGetCoreParamsResponse | PlainMessage | undefined, b: QueryGetCoreParamsResponse | PlainMessage | undefined): boolean; + static equals(a: QueryGetChainParamsResponse | PlainMessage | undefined, b: QueryGetChainParamsResponse | PlainMessage | undefined): boolean; } /** diff --git a/typescript/observer/tx_pb.d.ts b/typescript/observer/tx_pb.d.ts index 47e1512fbb..3684b24d01 100644 --- a/typescript/observer/tx_pb.d.ts +++ b/typescript/observer/tx_pb.d.ts @@ -7,7 +7,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialM import { Message, proto3 } from "@bufbuild/protobuf"; import type { ObserverUpdateReason } from "./observer_pb.js"; import type { HeaderData } from "../common/common_pb.js"; -import type { CoreParams } from "./params_pb.js"; +import type { ChainParams } from "./params_pb.js"; import type { Blame } from "./blame_pb.js"; import type { BlockHeaderVerificationFlags, GasPriceIncreaseFlags } from "./crosschain_flags_pb.js"; @@ -133,51 +133,99 @@ export declare class MsgAddBlockHeaderResponse extends Message { +export declare class MsgUpdateChainParams extends Message { /** * @generated from field: string creator = 1; */ creator: string; /** - * @generated from field: zetachain.zetacore.observer.CoreParams coreParams = 2; + * @generated from field: zetachain.zetacore.observer.ChainParams chainParams = 2; */ - coreParams?: CoreParams; + chainParams?: ChainParams; - constructor(data?: PartialMessage); + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.MsgUpdateCoreParams"; + static readonly typeName = "zetachain.zetacore.observer.MsgUpdateChainParams"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): MsgUpdateCoreParams; + static fromBinary(bytes: Uint8Array, options?: Partial): MsgUpdateChainParams; - static fromJson(jsonValue: JsonValue, options?: Partial): MsgUpdateCoreParams; + static fromJson(jsonValue: JsonValue, options?: Partial): MsgUpdateChainParams; - static fromJsonString(jsonString: string, options?: Partial): MsgUpdateCoreParams; + static fromJsonString(jsonString: string, options?: Partial): MsgUpdateChainParams; - static equals(a: MsgUpdateCoreParams | PlainMessage | undefined, b: MsgUpdateCoreParams | PlainMessage | undefined): boolean; + static equals(a: MsgUpdateChainParams | PlainMessage | undefined, b: MsgUpdateChainParams | PlainMessage | undefined): boolean; } /** - * @generated from message zetachain.zetacore.observer.MsgUpdateCoreParamsResponse + * @generated from message zetachain.zetacore.observer.MsgUpdateChainParamsResponse */ -export declare class MsgUpdateCoreParamsResponse extends Message { - constructor(data?: PartialMessage); +export declare class MsgUpdateChainParamsResponse extends Message { + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.observer.MsgUpdateCoreParamsResponse"; + static readonly typeName = "zetachain.zetacore.observer.MsgUpdateChainParamsResponse"; static readonly fields: FieldList; - static fromBinary(bytes: Uint8Array, options?: Partial): MsgUpdateCoreParamsResponse; + static fromBinary(bytes: Uint8Array, options?: Partial): MsgUpdateChainParamsResponse; - static fromJson(jsonValue: JsonValue, options?: Partial): MsgUpdateCoreParamsResponse; + static fromJson(jsonValue: JsonValue, options?: Partial): MsgUpdateChainParamsResponse; - static fromJsonString(jsonString: string, options?: Partial): MsgUpdateCoreParamsResponse; + static fromJsonString(jsonString: string, options?: Partial): MsgUpdateChainParamsResponse; - static equals(a: MsgUpdateCoreParamsResponse | PlainMessage | undefined, b: MsgUpdateCoreParamsResponse | PlainMessage | undefined): boolean; + static equals(a: MsgUpdateChainParamsResponse | PlainMessage | undefined, b: MsgUpdateChainParamsResponse | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.MsgRemoveChainParams + */ +export declare class MsgRemoveChainParams extends Message { + /** + * @generated from field: string creator = 1; + */ + creator: string; + + /** + * @generated from field: int64 chain_id = 2; + */ + chainId: bigint; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.MsgRemoveChainParams"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgRemoveChainParams; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgRemoveChainParams; + + static fromJsonString(jsonString: string, options?: Partial): MsgRemoveChainParams; + + static equals(a: MsgRemoveChainParams | PlainMessage | undefined, b: MsgRemoveChainParams | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.MsgRemoveChainParamsResponse + */ +export declare class MsgRemoveChainParamsResponse extends Message { + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.MsgRemoveChainParamsResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgRemoveChainParamsResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgRemoveChainParamsResponse; + + static fromJsonString(jsonString: string, options?: Partial): MsgRemoveChainParamsResponse; + + static equals(a: MsgRemoveChainParamsResponse | PlainMessage | undefined, b: MsgRemoveChainParamsResponse | PlainMessage | undefined): boolean; } /** diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 71c8a43a59..7daaf2ed7e 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -6,8 +6,6 @@ import ( "strconv" "testing" - fungiblecli "github.com/zeta-chain/zetacore/x/fungible/client/cli" - "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -19,11 +17,11 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/require" tmcli "github.com/tendermint/tendermint/libs/cli" - "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/testutil/network" "github.com/zeta-chain/zetacore/x/crosschain/client/cli" "github.com/zeta-chain/zetacore/x/crosschain/types" + fungiblecli "github.com/zeta-chain/zetacore/x/fungible/client/cli" ) func TxSignExec(clientCtx client.Context, from fmt.Stringer, filename string, extraArgs ...string) (testutil.BufferWriter, error) { diff --git a/x/crosschain/keeper/cctx_utils.go b/x/crosschain/keeper/cctx_utils.go index d257b7f18a..528139af69 100644 --- a/x/crosschain/keeper/cctx_utils.go +++ b/x/crosschain/keeper/cctx_utils.go @@ -18,7 +18,7 @@ import ( // UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. // It also updates the PendingNonces that is used to track the unfulfilled outbound txs. func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiveChainID) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, receiveChainID) if chain == nil { return zetaObserverTypes.ErrSupportedChains } diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 92fa5ffad5..85a7c1d8a0 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -123,7 +123,7 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W return fmt.Errorf("cannot find foreign coin with emittingContract address %s", event.Raw.Address.Hex()) } - receiverChain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(foreignCoin.ForeignChainId) + receiverChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, foreignCoin.ForeignChainId) senderChain, err := common.ZetaChainFromChainID(ctx.ChainID()) if err != nil { return fmt.Errorf("ProcessZRC20WithdrawalEvent: failed to convert chainID: %s", err.Error()) @@ -197,16 +197,17 @@ func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaC } receiverChainID := event.DestinationChainId - receiverChain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(receiverChainID.Int64()) + + receiverChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, receiverChainID.Int64()) if receiverChain == nil { return zetaObserverTypes.ErrSupportedChains } // Validation if we want to send ZETA to an external chain, but there is no ZETA token. - coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, receiverChain.ChainId) + chainParams, found := k.zetaObserverKeeper.GetChainParamsByChainID(ctx, receiverChain.ChainId) if !found { - return types.ErrNotFoundCoreParams + return types.ErrNotFoundChainParams } - if receiverChain.IsExternalChain() && coreParams.ZetaTokenContractAddress == "" { + if receiverChain.IsExternalChain() && chainParams.ZetaTokenContractAddress == "" { return types.ErrUnableToSendCoinType } toAddr := "0x" + hex.EncodeToString(event.DestinationAddress) diff --git a/x/crosschain/keeper/foreign_coins.go b/x/crosschain/keeper/foreign_coins.go index 44347c3156..1ceeb39bf7 100644 --- a/x/crosschain/keeper/foreign_coins.go +++ b/x/crosschain/keeper/foreign_coins.go @@ -6,7 +6,7 @@ import ( ) func (k Keeper) GetAllForeignCoins(ctx sdk.Context) ([]fungibleModuleTypes.ForeignCoins, error) { - chains := k.zetaObserverKeeper.GetParams(ctx).GetSupportedChains() + chains := k.zetaObserverKeeper.GetSupportedChains(ctx) var fCoins []fungibleModuleTypes.ForeignCoins for _, chain := range chains { fCoins = append(fCoins, k.fungibleKeeper.GetAllForeignCoinsForChain(ctx, chain.ChainId)...) diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go index 2fc2a13f12..7b7b82f9a2 100644 --- a/x/crosschain/keeper/gas_payment.go +++ b/x/crosschain/keeper/gas_payment.go @@ -93,7 +93,7 @@ func (k Keeper) PayGasNativeAndUpdateCctx( if cctx.InboundTxParams.CoinType != common.CoinType_Gas { return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in native gas with %s", cctx.InboundTxParams.CoinType.String()) } - if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + if chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, chainID); chain == nil { return zetaObserverTypes.ErrSupportedChains } @@ -140,7 +140,8 @@ func (k Keeper) PayGasInERC20AndUpdateCctx( if cctx.InboundTxParams.CoinType != common.CoinType_ERC20 { return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in erc20 with %s", cctx.InboundTxParams.CoinType.String()) } - if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + + if chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, chainID); chain == nil { return zetaObserverTypes.ErrSupportedChains } @@ -266,7 +267,8 @@ func (k Keeper) PayGasInZetaAndUpdateCctx( if cctx.InboundTxParams.CoinType != common.CoinType_Zeta { return cosmoserrors.Wrapf(types.ErrInvalidCoinType, "can't pay gas in zeta with %s", cctx.InboundTxParams.CoinType.String()) } - if chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(chainID); chain == nil { + + if chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, chainID); chain == nil { return zetaObserverTypes.ErrSupportedChains } diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go index 73fdebdde3..d0a702daf5 100644 --- a/x/crosschain/keeper/gas_payment_test.go +++ b/x/crosschain/keeper/gas_payment_test.go @@ -7,12 +7,7 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - "github.com/ethereum/go-ethereum/common" - evmkeeper "github.com/evmos/ethermint/x/evm/keeper" "github.com/stretchr/testify/require" - "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" - "github.com/zeta-chain/zetacore/cmd/zetacored/config" zetacommon "github.com/zeta-chain/zetacore/common" testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -22,193 +17,6 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -// get a valid eth chain id independently of the build flag -func getValidEthChainID(t *testing.T) int64 { - return getValidEthChain(t).ChainId -} - -// get a valid eth chain independently of the build flag -func getValidEthChain(_ *testing.T) *zetacommon.Chain { - goerli := zetacommon.GoerliLocalnetChain() - return &goerli -} - -// assert that a contract has been deployed by checking stored code is non-empty. -func assertContractDeployment(t *testing.T, k *evmkeeper.Keeper, ctx sdk.Context, contractAddress common.Address) { - acc := k.GetAccount(ctx, contractAddress) - require.NotNil(t, acc) - - code := k.GetCode(ctx, common.BytesToHash(acc.CodeHash)) - require.NotEmpty(t, code) -} - -// deploySystemContracts deploys the system contracts and returns their addresses. -func deploySystemContracts( - t *testing.T, - ctx sdk.Context, - k *fungiblekeeper.Keeper, - evmk *evmkeeper.Keeper, -) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { - var err error - - wzeta, err = k.DeployWZETA(ctx) - require.NoError(t, err) - require.NotEmpty(t, wzeta) - assertContractDeployment(t, evmk, ctx, wzeta) - - uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) - require.NoError(t, err) - require.NotEmpty(t, uniswapV2Factory) - assertContractDeployment(t, evmk, ctx, uniswapV2Factory) - - uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) - require.NoError(t, err) - require.NotEmpty(t, uniswapV2Router) - assertContractDeployment(t, evmk, ctx, uniswapV2Router) - - connector, err = k.DeployConnectorZEVM(ctx, wzeta) - require.NoError(t, err) - require.NotEmpty(t, connector) - assertContractDeployment(t, evmk, ctx, connector) - - systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) - require.NoError(t, err) - require.NotEmpty(t, systemContract) - assertContractDeployment(t, evmk, ctx, systemContract) - - return -} - -// setupGasCoin is a helper function to setup the gas coin for testing -func setupGasCoin( - t *testing.T, - ctx sdk.Context, - k *fungiblekeeper.Keeper, - evmk *evmkeeper.Keeper, - chainID int64, - assetName string, - symbol string, -) (zrc20 common.Address) { - addr, err := k.SetupChainGasCoinAndPool( - ctx, - chainID, - assetName, - symbol, - 8, - nil, - ) - require.NoError(t, err) - assertContractDeployment(t, evmk, ctx, addr) - return addr -} - -// deployZRC20 deploys a ZRC20 contract and returns its address -func deployZRC20( - t *testing.T, - ctx sdk.Context, - k *fungiblekeeper.Keeper, - evmk *evmkeeper.Keeper, - chainID int64, - assetName string, - assetAddress string, - symbol string, -) (zrc20 common.Address) { - addr, err := k.DeployZRC20Contract( - ctx, - assetName, - symbol, - 8, - chainID, - 0, - assetAddress, - big.NewInt(21_000), - ) - require.NoError(t, err) - assertContractDeployment(t, evmk, ctx, addr) - return addr -} - -// setupZRC20Pool setup a Uniswap pool with liquidity for the pair zeta/asset -func setupZRC20Pool( - t *testing.T, - ctx sdk.Context, - k *fungiblekeeper.Keeper, - bankKeeper bankkeeper.Keeper, - zrc20Addr common.Address, -) { - routerAddress, err := k.GetUniswapV2Router02Address(ctx) - require.NoError(t, err) - routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() - require.NoError(t, err) - - // enough for the small numbers used in test - liquidityAmount := big.NewInt(1e17) - - // mint some zrc20 and zeta - _, err = k.DepositZRC20(ctx, zrc20Addr, types.ModuleAddressEVM, liquidityAmount) - require.NoError(t, err) - err = bankKeeper.MintCoins( - ctx, - types.ModuleName, - sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(liquidityAmount))), - ) - require.NoError(t, err) - - // approve the router to spend the zeta - err = k.CallZRC20Approve( - ctx, - types.ModuleAddressEVM, - zrc20Addr, - routerAddress, - liquidityAmount, - false, - ) - require.NoError(t, err) - - // add the liquidity - //function addLiquidityETH( - // address token, - // uint amountTokenDesired, - // uint amountTokenMin, - // uint amountETHMin, - // address to, - // uint deadline - //) - _, err = k.CallEVM( - ctx, - *routerABI, - types.ModuleAddressEVM, - routerAddress, - liquidityAmount, - big.NewInt(5_000_000), - true, - false, - "addLiquidityETH", - zrc20Addr, - liquidityAmount, - fungiblekeeper.BigIntZero, - fungiblekeeper.BigIntZero, - types.ModuleAddressEVM, - liquidityAmount, - ) - require.NoError(t, err) -} - -func setAdminPolicies(ctx sdk.Context, zk testkeeper.ZetaKeepers, admin string) { - params := zk.ObserverKeeper.GetParams(ctx) - params.AdminPolicy = []*observertypes.Admin_Policy{ - { - PolicyType: observertypes.Policy_Type_group1, - Address: admin, - }, - { - PolicyType: observertypes.Policy_Type_group2, - Address: admin, - }, - } - zk.ObserverKeeper.SetParams(ctx, params) -} - var ( // gasLimit = big.NewInt(21_000) - value used in SetupChainGasCoinAndPool for gas limit initialization withdrawFee uint64 = 1000 @@ -226,6 +34,8 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") _, err := fungibleMsgServer.UpdateZRC20WithdrawFee( @@ -294,6 +104,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") @@ -325,6 +136,7 @@ func TestKeeper_PayGasNativeAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") _, err := fungibleMsgServer.UpdateZRC20WithdrawFee( @@ -369,6 +181,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { // deploy gas coin, erc20 and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) assetAddress := sample.EthAddress().String() deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") @@ -462,6 +275,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") @@ -493,6 +307,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { // deploy gas coin, erc20 and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) assetAddress := sample.EthAddress().String() deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") @@ -538,6 +353,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { // deploy gas coin, erc20 and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) assetAddress := sample.EthAddress().String() deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") @@ -593,6 +409,7 @@ func TestKeeper_PayGasInERC20AndUpdateCctx(t *testing.T) { // deploy gas coin, erc20 and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) assetAddress := sample.EthAddress().String() deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) gasZRC20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foo", "foo") @@ -663,6 +480,7 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") k.SetGasPrice(ctx, types.GasPrice{ @@ -751,6 +569,7 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") @@ -781,6 +600,7 @@ func TestKeeper_PayGasInZetaAndUpdateCctx(t *testing.T) { // deploy gas coin and set fee params chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar") k.SetGasPrice(ctx, types.GasPrice{ diff --git a/x/crosschain/keeper/keeper_test.go b/x/crosschain/keeper/keeper_test.go index d7ad574eb2..3a65063a16 100644 --- a/x/crosschain/keeper/keeper_test.go +++ b/x/crosschain/keeper/keeper_test.go @@ -16,7 +16,6 @@ import ( "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmdb "github.com/tendermint/tm-db" - "github.com/zeta-chain/zetacore/x/crosschain/types" fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" "github.com/zeta-chain/zetacore/x/observer/keeper" diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go index 2a241c7f23..53bd5bdc8b 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go @@ -16,7 +16,7 @@ import ( // Authorized: admin policy group 1, observer. func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToInTxTracker) (*types.MsgAddToInTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { return nil, observertypes.ErrSupportedChains } 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 d4102e0b17..7457068b38 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 @@ -78,9 +78,10 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { require.False(t, found) }) t.Run("fail normal user submit without proof", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k, ctx, _, zk := keepertest.CrosschainKeeper(t) tx_hash := "string" chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) msgServer := keeper.NewMsgServerImpl(*k) _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: sample.AccAddress(), @@ -101,6 +102,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { setAdminPolicies(ctx, zk, admin) tx_hash := "string" chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) msgServer := keeper.NewMsgServerImpl(*k) _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: admin, @@ -121,6 +123,7 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { setAdminPolicies(ctx, zk, admin) tx_hash := "string" chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) msgServer := keeper.NewMsgServerImpl(*k) _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: admin, @@ -141,15 +144,6 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { func setupVerificationParams(zk keepertest.ZetaKeepers, ctx sdk.Context, tx_index int64, chainID int64, header ethtypes.Header, headerRLP []byte, block *ethtypes.Block) { params := zk.ObserverKeeper.GetParams(ctx) - params.ObserverParams = append(params.ObserverParams, &observertypes.ObserverParams{ - Chain: &common.Chain{ - ChainId: chainID, - ChainName: common.ChainName_goerli_testnet, - }, - BallotThreshold: sdk.OneDec(), - MinObserverDelegation: sdk.OneDec(), - IsSupported: true, - }) zk.ObserverKeeper.SetParams(ctx, params) zk.ObserverKeeper.SetBlockHeader(ctx, common.BlockHeader{ Height: block.Number().Int64(), @@ -158,10 +152,13 @@ func setupVerificationParams(zk keepertest.ZetaKeepers, ctx sdk.Context, tx_inde ChainId: chainID, Header: common.NewEthereumHeader(headerRLP), }) - zk.ObserverKeeper.SetCoreParams(ctx, observertypes.CoreParamsList{CoreParams: []*observertypes.CoreParams{ + zk.ObserverKeeper.SetChainParamsList(ctx, observertypes.ChainParamsList{ChainParams: []*observertypes.ChainParams{ { ChainId: chainID, ConnectorContractAddress: block.Transactions()[tx_index].To().Hex(), + BallotThreshold: sdk.OneDec(), + MinObserverDelegation: sdk.OneDec(), + IsSupported: true, }, }}) zk.ObserverKeeper.SetCrosschainFlags(ctx, observertypes.CrosschainFlags{ diff --git a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go index 4817d3b75c..0af5fc9a2b 100644 --- a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go @@ -24,7 +24,7 @@ import ( // Authorized: admin policy group 1, observer. func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToOutTxTracker) (*types.MsgAddToOutTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { return nil, observertypes.ErrSupportedChains } diff --git a/x/crosschain/keeper/msg_server_gas_price_voter.go b/x/crosschain/keeper/msg_server_gas_price_voter.go index 2a8410a7e2..e91703d4ec 100644 --- a/x/crosschain/keeper/msg_server_gas_price_voter.go +++ b/x/crosschain/keeper/msg_server_gas_price_voter.go @@ -23,7 +23,7 @@ import ( func (k msgServer) GasPriceVoter(goCtx context.Context, msg *types.MsgGasPriceVoter) (*types.MsgGasPriceVoterResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { return nil, observertypes.ErrSupportedChains } diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go index ea272efba6..436a6b69c9 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -157,14 +157,18 @@ func setupTssMigrationParams( IsInboundEnabled: false, IsOutboundEnabled: true, }) - params := zk.ObserverKeeper.GetParamsIfExists(ctx) - params.ObserverParams = append(params.ObserverParams, &observertypes.ObserverParams{ - Chain: &chain, - BallotThreshold: sdk.NewDec(0), - MinObserverDelegation: sdk.OneDec(), - IsSupported: true, + + zk.ObserverKeeper.SetChainParamsList(ctx, observertypes.ChainParamsList{ + ChainParams: []*observertypes.ChainParams{ + { + ChainId: chain.ChainId, + BallotThreshold: sdk.NewDec(0), + MinObserverDelegation: sdk.OneDec(), + IsSupported: true, + }, + }, }) - zk.ObserverKeeper.SetParams(ctx, params) + currentTss := sample.Tss() newTss := sample.Tss() newTss.FinalizedZetaHeight = currentTss.FinalizedZetaHeight + 1 diff --git a/x/crosschain/keeper/msg_server_update_tss.go b/x/crosschain/keeper/msg_server_update_tss.go index d8b0dfddf8..b6c2198278 100644 --- a/x/crosschain/keeper/msg_server_update_tss.go +++ b/x/crosschain/keeper/msg_server_update_tss.go @@ -31,7 +31,7 @@ func (k msgServer) UpdateTssAddress(goCtx context.Context, msg *types.MsgUpdateT tssMigrators := k.zetaObserverKeeper.GetAllTssFundMigrators(ctx) // Each connected chain should have its own tss migrator - if len(k.zetaObserverKeeper.GetParams(ctx).GetSupportedChains()) != len(tssMigrators) { + if len(k.zetaObserverKeeper.GetSupportedChains(ctx)) != len(tssMigrators) { return nil, errorsmod.Wrap(types.ErrUnableToUpdateTss, "cannot update tss address not enough migrations have been created and completed") } // GetAllTssFundMigrators would return the migrators created for the current migration diff --git a/x/crosschain/keeper/msg_server_update_tss_test.go b/x/crosschain/keeper/msg_server_update_tss_test.go index 1d735c7c4e..9d1207d427 100644 --- a/x/crosschain/keeper/msg_server_update_tss_test.go +++ b/x/crosschain/keeper/msg_server_update_tss_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -22,7 +24,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSSHistory(ctx, tssNew) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { + for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -32,7 +34,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { cctx.CctxStatus.Status = crosschaintypes.CctxStatus_OutboundMined k.SetCrossChainTx(ctx, *cctx) } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssNew.TssPubkey, @@ -44,6 +46,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { migrators := k.GetObserverKeeper().GetAllTssFundMigrators(ctx) assert.Equal(t, 0, len(migrators)) }) + t.Run("new tss has not been added to tss history", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) admin := sample.AccAddress() @@ -53,7 +56,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { tssNew := sample.Tss() k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { + for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -63,7 +66,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { cctx.CctxStatus.Status = crosschaintypes.CctxStatus_OutboundMined k.SetCrossChainTx(ctx, *cctx) } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssNew.TssPubkey, @@ -73,8 +76,9 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { tss, found := k.GetObserverKeeper().GetTSS(ctx) assert.True(t, found) assert.Equal(t, tssOld, tss) - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) }) + t.Run("old tss pubkey provided", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) admin := sample.AccAddress() @@ -83,7 +87,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { tssOld := sample.Tss() k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { + for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -93,7 +97,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { cctx.CctxStatus.Status = crosschaintypes.CctxStatus_OutboundMined k.SetCrossChainTx(ctx, *cctx) } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssOld.TssPubkey, @@ -103,8 +107,9 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { tss, found := k.GetObserverKeeper().GetTSS(ctx) assert.True(t, found) assert.Equal(t, tssOld, tss) - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) }) + t.Run("unable to update tss when not enough migrators are present", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) admin := sample.AccAddress() @@ -112,33 +117,37 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) tssOld := sample.Tss() tssNew := sample.Tss() + k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSSHistory(ctx, tssNew) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { - index := chain.ChainName.String() + "_migration_tx_index" - k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ - ChainId: chain.ChainId, - MigrationCctxIndex: index, - }) - cctx := sample.CrossChainTx(t, index) - cctx.CctxStatus.Status = crosschaintypes.CctxStatus_OutboundMined - k.SetCrossChainTx(ctx, *cctx) - break - } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), 1) + setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) + + // set a single migrator while there are 2 supported chains + chain := k.GetObserverKeeper().GetSupportedChains(ctx)[0] + index := chain.ChainName.String() + "_migration_tx_index" + k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ + ChainId: chain.ChainId, + MigrationCctxIndex: index, + }) + cctx := sample.CrossChainTx(t, index) + cctx.CctxStatus.Status = crosschaintypes.CctxStatus_OutboundMined + k.SetCrossChainTx(ctx, *cctx) + + require.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), 1) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssNew.TssPubkey, }) - assert.ErrorContains(t, err, "cannot update tss address not enough migrations have been created and completed") - assert.ErrorIs(t, err, crosschaintypes.ErrUnableToUpdateTss) + require.ErrorContains(t, err, "cannot update tss address not enough migrations have been created and completed") + require.ErrorIs(t, err, crosschaintypes.ErrUnableToUpdateTss) tss, found := k.GetObserverKeeper().GetTSS(ctx) - assert.True(t, found) - assert.Equal(t, tssOld, tss) + require.True(t, found) + require.Equal(t, tssOld, tss) migrators := k.GetObserverKeeper().GetAllTssFundMigrators(ctx) assert.Equal(t, 1, len(migrators)) }) + t.Run("unable to update tss when pending cctx is present", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) admin := sample.AccAddress() @@ -146,10 +155,13 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) tssOld := sample.Tss() tssNew := sample.Tss() + k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSSHistory(ctx, tssNew) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { + setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) + + for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -159,7 +171,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { cctx.CctxStatus.Status = crosschaintypes.CctxStatus_PendingOutbound k.SetCrossChainTx(ctx, *cctx) } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssNew.TssPubkey, @@ -170,8 +182,9 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { assert.True(t, found) assert.Equal(t, tssOld, tss) migrators := k.GetObserverKeeper().GetAllTssFundMigrators(ctx) - assert.Equal(t, len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains()), len(migrators)) + assert.Equal(t, len(k.GetObserverKeeper().GetSupportedChains(ctx)), len(migrators)) }) + t.Run("unable to update tss cctx is not present", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) admin := sample.AccAddress() @@ -179,17 +192,20 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) tssOld := sample.Tss() tssNew := sample.Tss() + k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSSHistory(ctx, tssNew) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetParams(ctx).GetSupportedChains() { + setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) + + for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, MigrationCctxIndex: index, }) } - assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains())) + assert.Equal(t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), len(k.GetObserverKeeper().GetSupportedChains(ctx))) _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ Creator: admin, TssPubkey: tssNew.TssPubkey, @@ -200,6 +216,6 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { assert.True(t, found) assert.Equal(t, tssOld, tss) migrators := k.GetObserverKeeper().GetAllTssFundMigrators(ctx) - assert.Equal(t, len(k.GetObserverKeeper().GetParams(ctx).GetSupportedChains()), len(migrators)) + assert.Equal(t, len(k.GetObserverKeeper().GetSupportedChains(ctx)), len(migrators)) }) } diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx.go b/x/crosschain/keeper/msg_server_vote_inbound_tx.go index 0fc1b7bea6..50954d1a15 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx.go @@ -62,12 +62,13 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { return nil, types.ErrNotEnoughPermissions } + // GetChainFromChainID makes sure we are getting only supported chains , if a chain support has been turned on using gov proposal, this function returns nil - observationChain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.SenderChainId) + observationChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) if observationChain == nil { return nil, sdkerrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.SenderChainId, observationType.String())) } - receiverChain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ReceiverChain) + receiverChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ReceiverChain) if receiverChain == nil { return nil, sdkerrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.ReceiverChain, observationType.String())) } @@ -105,11 +106,11 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg // Validation if we want to send ZETA to external chain, but there is no ZETA token. if receiverChain.IsExternalChain() { - coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, receiverChain.ChainId) + chainParams, found := k.zetaObserverKeeper.GetChainParamsByChainID(ctx, receiverChain.ChainId) if !found { - return nil, types.ErrNotFoundCoreParams + return nil, types.ErrNotFoundChainParams } - if coreParams.ZetaTokenContractAddress == "" && msg.CoinType == common.CoinType_Zeta { + if chainParams.ZetaTokenContractAddress == "" && msg.CoinType == common.CoinType_Zeta { return nil, types.ErrUnableToSendCoinType } } @@ -138,7 +139,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg return &types.MsgVoteOnObservedInboundTxResponse{}, nil } else if err != nil && isContractReverted { // contract call reverted; should refund revertMessage := err.Error() - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(cctx.InboundTxParams.SenderChainId) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, cctx.InboundTxParams.SenderChainId) if chain == nil { cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, "invalid sender chain") return &types.MsgVoteOnObservedInboundTxResponse{}, nil diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index d3108c4c95..274bbdc695 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -65,7 +65,7 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms /* EDGE CASE : Params updated in during the finalization process i.e Inbound has been finalized but outbound is still pending */ - observationChain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.OutTxChain) + observationChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.OutTxChain) if observationChain == nil { return nil, observerTypes.ErrSupportedChains } diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20.go b/x/crosschain/keeper/msg_server_whitelist_erc20.go index 8f5ce26579..9dc082ec31 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20.go @@ -52,7 +52,7 @@ func (k msgServer) WhitelistERC20(goCtx context.Context, msg *types.MsgWhitelist return nil, errorsmod.Wrapf(types.ErrCannotFindTSSKeys, "Cannot create new admin cmd of type whitelistERC20") } - chain := k.zetaObserverKeeper.GetParams(ctx).GetChainFromChainID(msg.ChainId) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "chain id (%d) not supported", msg.ChainId) } @@ -90,9 +90,9 @@ func (k msgServer) WhitelistERC20(goCtx context.Context, msg *types.MsgWhitelist } // get necessary parameters to create the cctx - param, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId) + param, found := k.zetaObserverKeeper.GetChainParamsByChainID(ctx, msg.ChainId) if !found { - return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "core params not found for chain id (%d)", msg.ChainId) + return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "chain params not found for chain id (%d)", msg.ChainId) } medianGasPrice, isFound := k.GetMedianGasPriceInUint(ctx, msg.ChainId) if !isFound { diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20_test.go b/x/crosschain/keeper/msg_server_whitelist_erc20_test.go index 93b1e3d1b6..82cd292fb2 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20_test.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20_test.go @@ -22,6 +22,7 @@ func TestKeeper_WhitelistERC20(t *testing.T) { k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) admin := sample.AccAddress() setAdminPolicies(ctx, zk, admin) diff --git a/x/crosschain/keeper/utils_test.go b/x/crosschain/keeper/utils_test.go new file mode 100644 index 0000000000..83f37b2799 --- /dev/null +++ b/x/crosschain/keeper/utils_test.go @@ -0,0 +1,236 @@ +// This file contains helper functions for testing the crosschain module +package keeper_test + +import ( + "math/big" + "testing" + + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/common" + evmkeeper "github.com/evmos/ethermint/x/evm/keeper" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + zetacommon "github.com/zeta-chain/zetacore/common" + testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// getValidEthChainID get a valid eth chain id +func getValidEthChainID(t *testing.T) int64 { + return getValidEthChain(t).ChainId +} + +// getValidEthChain get a valid eth chain +func getValidEthChain(_ *testing.T) *zetacommon.Chain { + goerli := zetacommon.GoerliLocalnetChain() + return &goerli +} + +// getValidEthChainIDWithIndex get a valid eth chain id with index +func getValidEthChainIDWithIndex(t *testing.T, index int) int64 { + switch index { + case 0: + return zetacommon.GoerliLocalnetChain().ChainId + case 1: + return zetacommon.GoerliChain().ChainId + default: + require.Fail(t, "invalid index") + } + return 0 +} + +// assert that a contract has been deployed by checking stored code is non-empty. +func assertContractDeployment(t *testing.T, k *evmkeeper.Keeper, ctx sdk.Context, contractAddress common.Address) { + acc := k.GetAccount(ctx, contractAddress) + require.NotNil(t, acc) + + code := k.GetCode(ctx, common.BytesToHash(acc.CodeHash)) + require.NotEmpty(t, code) +} + +// deploySystemContracts deploys the system contracts and returns their addresses. +func deploySystemContracts( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, +) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { + var err error + + wzeta, err = k.DeployWZETA(ctx) + require.NoError(t, err) + require.NotEmpty(t, wzeta) + assertContractDeployment(t, evmk, ctx, wzeta) + + uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Factory) + assertContractDeployment(t, evmk, ctx, uniswapV2Factory) + + uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Router) + assertContractDeployment(t, evmk, ctx, uniswapV2Router) + + connector, err = k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, connector) + assertContractDeployment(t, evmk, ctx, connector) + + systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) + require.NoError(t, err) + require.NotEmpty(t, systemContract) + assertContractDeployment(t, evmk, ctx, systemContract) + + return +} + +// setupGasCoin is a helper function to setup the gas coin for testing +func setupGasCoin( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.SetupChainGasCoinAndPool( + ctx, + chainID, + assetName, + symbol, + 8, + nil, + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// deployZRC20 deploys a ZRC20 contract and returns its address +func deployZRC20( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk *evmkeeper.Keeper, + chainID int64, + assetName string, + assetAddress string, + symbol string, +) (zrc20 common.Address) { + addr, err := k.DeployZRC20Contract( + ctx, + assetName, + symbol, + 8, + chainID, + 0, + assetAddress, + big.NewInt(21_000), + ) + require.NoError(t, err) + assertContractDeployment(t, evmk, ctx, addr) + return addr +} + +// setupZRC20Pool setup a Uniswap pool with liquidity for the pair zeta/asset +func setupZRC20Pool( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + bankKeeper bankkeeper.Keeper, + zrc20Addr common.Address, +) { + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + require.NoError(t, err) + + // enough for the small numbers used in test + liquidityAmount := big.NewInt(1e17) + + // mint some zrc20 and zeta + _, err = k.DepositZRC20(ctx, zrc20Addr, types.ModuleAddressEVM, liquidityAmount) + require.NoError(t, err) + err = bankKeeper.MintCoins( + ctx, + types.ModuleName, + sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(liquidityAmount))), + ) + require.NoError(t, err) + + // approve the router to spend the zeta + err = k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20Addr, + routerAddress, + liquidityAmount, + false, + ) + require.NoError(t, err) + + // add the liquidity + //function addLiquidityETH( + // address token, + // uint amountTokenDesired, + // uint amountTokenMin, + // uint amountETHMin, + // address to, + // uint deadline + //) + _, err = k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + liquidityAmount, + big.NewInt(5_000_000), + true, + false, + "addLiquidityETH", + zrc20Addr, + liquidityAmount, + fungiblekeeper.BigIntZero, + fungiblekeeper.BigIntZero, + types.ModuleAddressEVM, + liquidityAmount, + ) + require.NoError(t, err) +} + +// setAdminPolicies sets the admin policies for the observer module with group 1 and 2 +func setAdminPolicies(ctx sdk.Context, zk testkeeper.ZetaKeepers, admin string) { + params := zk.ObserverKeeper.GetParams(ctx) + params.AdminPolicy = []*observertypes.Admin_Policy{ + { + PolicyType: observertypes.Policy_Type_group1, + Address: admin, + }, + { + PolicyType: observertypes.Policy_Type_group2, + Address: admin, + }, + } + zk.ObserverKeeper.SetParams(ctx, params) +} + +// setSupportedChain sets the supported chains for the observer module +func setSupportedChain(ctx sdk.Context, zk testkeeper.ZetaKeepers, chainIDs ...int64) { + chainParamsList := make([]*observertypes.ChainParams, len(chainIDs)) + for i, chainID := range chainIDs { + chainParams := sample.ChainParams(chainID) + chainParams.IsSupported = true + chainParamsList[i] = chainParams + } + zk.ObserverKeeper.SetChainParamsList(ctx, observertypes.ChainParamsList{ + ChainParams: chainParamsList, + }) +} diff --git a/x/crosschain/keeper/verify_proof.go b/x/crosschain/keeper/verify_proof.go index 34e03ae3ff..a2d6464855 100644 --- a/x/crosschain/keeper/verify_proof.go +++ b/x/crosschain/keeper/verify_proof.go @@ -69,20 +69,20 @@ func (k Keeper) VerifyEVMInTxBody(ctx sdk.Context, msg *types.MsgAddToInTxTracke } switch msg.CoinType { case common.CoinType_Zeta: - coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId) + chainParams, found := k.zetaObserverKeeper.GetChainParamsByChainID(ctx, msg.ChainId) if !found { - return types.ErrUnsupportedChain.Wrapf("core params not found for chain %d", msg.ChainId) + return types.ErrUnsupportedChain.Wrapf("chain params not found for chain %d", msg.ChainId) } - if txx.To().Hex() != coreParams.ConnectorContractAddress { + if txx.To().Hex() != chainParams.ConnectorContractAddress { return fmt.Errorf("receiver is not connector contract for coin type %s", msg.CoinType) } return nil case common.CoinType_ERC20: - coreParams, found := k.zetaObserverKeeper.GetCoreParamsByChainID(ctx, msg.ChainId) + chainParams, found := k.zetaObserverKeeper.GetChainParamsByChainID(ctx, msg.ChainId) if !found { - return types.ErrUnsupportedChain.Wrapf("core params not found for chain %d", msg.ChainId) + return types.ErrUnsupportedChain.Wrapf("chain params not found for chain %d", msg.ChainId) } - if txx.To().Hex() != coreParams.Erc20CustodyContractAddress { + if txx.To().Hex() != chainParams.Erc20CustodyContractAddress { return fmt.Errorf("receiver is not erc20Custory contract for coin type %s", msg.CoinType) } return nil diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 5de2c55af1..42274e4698 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -21,7 +21,7 @@ var ( ErrCannotFindPendingNonces = errorsmod.Register(ModuleName, 1121, "cannot find pending nonces") ErrCannotFindTSSKeys = errorsmod.Register(ModuleName, 1122, "cannot find TSS keys") ErrNonceMismatch = errorsmod.Register(ModuleName, 1123, "nonce mismatch") - ErrNotFoundCoreParams = errorsmod.Register(ModuleName, 1126, "not found chain core params") + ErrNotFoundChainParams = errorsmod.Register(ModuleName, 1126, "not found chain chain params") ErrUnableToSendCoinType = errorsmod.Register(ModuleName, 1127, "unable to send this coin type to a receiver chain") ErrInvalidAddress = errorsmod.Register(ModuleName, 1128, "invalid address") diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index efe117117b..3bbd137795 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -50,7 +50,7 @@ type ObserverKeeper interface { GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) GetParams(ctx sdk.Context) (params observertypes.Params) - GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.CoreParams, found bool) + GetChainParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.ChainParams, found bool) GetNodeAccount(ctx sdk.Context, address string) (nodeAccount observertypes.NodeAccount, found bool) GetAllNodeAccount(ctx sdk.Context) (nodeAccounts []observertypes.NodeAccount) SetNodeAccount(ctx sdk.Context, nodeAccount observertypes.NodeAccount) @@ -91,6 +91,8 @@ type ObserverKeeper interface { SetTssAndUpdateNonce(ctx sdk.Context, tss observertypes.TSS) RemoveFromPendingNonces(ctx sdk.Context, tss string, chainID int64, nonce int64) GetAllNonceToCctx(ctx sdk.Context) (list []observertypes.NonceToCctx) + GetSupportedChainFromChainID(ctx sdk.Context, chainID int64) *common.Chain + GetSupportedChains(ctx sdk.Context) []*common.Chain } type FungibleKeeper interface { diff --git a/x/emissions/types/expected_keepers.go b/x/emissions/types/expected_keepers.go index e8b3a4d601..15ad6781a7 100644 --- a/x/emissions/types/expected_keepers.go +++ b/x/emissions/types/expected_keepers.go @@ -20,7 +20,7 @@ type ObserverKeeper interface { GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) GetParams(ctx sdk.Context) (params observertypes.Params) - GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.CoreParams, found bool) + GetChainParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.ChainParams, found bool) } // BankKeeper defines the expected interface needed to retrieve account balances. diff --git a/x/fungible/keeper/grpc_query_gas_stability_pool.go b/x/fungible/keeper/grpc_query_gas_stability_pool.go index 023ef82836..770c58a10e 100644 --- a/x/fungible/keeper/grpc_query_gas_stability_pool.go +++ b/x/fungible/keeper/grpc_query_gas_stability_pool.go @@ -53,7 +53,7 @@ func (k Keeper) GasStabilityPoolBalanceAll( ctx := sdk.UnwrapSDKContext(c) // iterate supported chains - chains := k.observerKeeper.GetParams(ctx).GetSupportedChains() + chains := k.observerKeeper.GetSupportedChains(ctx) balances := make([]types.QueryAllGasStabilityPoolBalanceResponse_Balance, 0, len(chains)) for _, chain := range chains { if chain == nil { diff --git a/x/fungible/types/expected_keepers.go b/x/fungible/types/expected_keepers.go index 43e9607820..c576a7cafc 100644 --- a/x/fungible/types/expected_keepers.go +++ b/x/fungible/types/expected_keepers.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/evmos/ethermint/x/evm/statedb" evmtypes "github.com/evmos/ethermint/x/evm/types" - + "github.com/zeta-chain/zetacore/common" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -45,7 +45,8 @@ type ObserverKeeper interface { GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetAllBallots(ctx sdk.Context) (voters []*observertypes.Ballot) GetParams(ctx sdk.Context) (params observertypes.Params) - GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.CoreParams, found bool) + GetChainParamsByChainID(ctx sdk.Context, chainID int64) (params *observertypes.ChainParams, found bool) + GetSupportedChains(ctx sdk.Context) []*common.Chain GetMaturedBallotList(ctx sdk.Context) []string } diff --git a/x/observer/client/cli/query.go b/x/observer/client/cli/query.go index 61aced4edd..b896dd9a71 100644 --- a/x/observer/client/cli/query.go +++ b/x/observer/client/cli/query.go @@ -29,8 +29,8 @@ func GetQueryCmd(_ string) *cobra.Command { CmdBallotByIdentifier(), CmdObserverSet(), CmdGetSupportedChains(), - CmdGetCoreParamsForChain(), - CmdGetCoreParams(), + CmdGetChainParamsForChain(), + CmdGetChainParams(), CmdListNodeAccount(), CmdShowNodeAccount(), CmdShowCrosschainFlags(), diff --git a/x/observer/client/cli/query_core_params.go b/x/observer/client/cli/query_chain_params.go similarity index 69% rename from x/observer/client/cli/query_core_params.go rename to x/observer/client/cli/query_chain_params.go index f41de54d15..6733c7d5c7 100644 --- a/x/observer/client/cli/query_core_params.go +++ b/x/observer/client/cli/query_chain_params.go @@ -9,10 +9,10 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) -func CmdGetCoreParamsForChain() *cobra.Command { +func CmdGetChainParamsForChain() *cobra.Command { cmd := &cobra.Command{ - Use: "show-core-params [chain-id]", - Short: "Query GetCoreParamsForChain", + Use: "show-chain-params [chain-id]", + Short: "Query GetChainParamsForChain", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { reqChainID, err := strconv.ParseInt(args[0], 10, 64) @@ -25,10 +25,10 @@ func CmdGetCoreParamsForChain() *cobra.Command { } queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryGetCoreParamsForChainRequest{ + params := &types.QueryGetChainParamsForChainRequest{ ChainId: reqChainID, } - res, err := queryClient.GetCoreParamsForChain(cmd.Context(), params) + res, err := queryClient.GetChainParamsForChain(cmd.Context(), params) if err != nil { return err } @@ -41,10 +41,10 @@ func CmdGetCoreParamsForChain() *cobra.Command { return cmd } -func CmdGetCoreParams() *cobra.Command { +func CmdGetChainParams() *cobra.Command { cmd := &cobra.Command{ - Use: "list-core-params", - Short: "Query GetCoreParams", + Use: "list-chain-params", + Short: "Query GetChainParams", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) (err error) { @@ -55,8 +55,8 @@ func CmdGetCoreParams() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryGetCoreParamsRequest{} - res, err := queryClient.GetCoreParams(cmd.Context(), params) + params := &types.QueryGetChainParamsRequest{} + res, err := queryClient.GetChainParams(cmd.Context(), params) if err != nil { return err } diff --git a/x/observer/client/cli/tx.go b/x/observer/client/cli/tx.go index dd886894aa..7f60f10be8 100644 --- a/x/observer/client/cli/tx.go +++ b/x/observer/client/cli/tx.go @@ -22,7 +22,8 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand( CmdAddObserver(), - CmdUpdateCoreParams(), + CmdUpdateChainParams(), + CmdRemoveChainParams(), CmdUpdateCrosschainFlags(), CmdUpdateKeygen(), CmdAddBlameVote(), diff --git a/x/observer/client/cli/tx_remove_chain_params.go b/x/observer/client/cli/tx_remove_chain_params.go new file mode 100644 index 0000000000..35e4d07655 --- /dev/null +++ b/x/observer/client/cli/tx_remove_chain_params.go @@ -0,0 +1,44 @@ +package cli + +import ( + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func CmdRemoveChainParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "remove-chain-params [chain-id]", + Short: "Broadcast message to remove chain params", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + // get chainID as int64 + chainID, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + + msg := types.NewMsgRemoveChainParams( + clientCtx.GetFromAddress().String(), + chainID, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/observer/client/cli/tx_update_core_params.go b/x/observer/client/cli/tx_update_chain_params.go similarity index 72% rename from x/observer/client/cli/tx_update_core_params.go rename to x/observer/client/cli/tx_update_chain_params.go index 6db2daaca5..3417fa6b50 100644 --- a/x/observer/client/cli/tx_update_core_params.go +++ b/x/observer/client/cli/tx_update_chain_params.go @@ -12,21 +12,21 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) -func CmdUpdateCoreParams() *cobra.Command { +func CmdUpdateChainParams() *cobra.Command { cmd := &cobra.Command{ - Use: "update-client-params [chain-id] [client-params.json]", - Short: "Broadcast message updateClientParams", - Args: cobra.ExactArgs(1), + Use: "update-chain-params [chain-id] [client-params.json]", + Short: "Broadcast message updateChainParams", + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) (err error) { - argCoreParams := args[0] + argChainParams := args[0] clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err } - var clientParams types.CoreParams - file, err := filepath.Abs(argCoreParams) + var clientParams types.ChainParams + file, err := filepath.Abs(argChainParams) if err != nil { return err } @@ -40,7 +40,7 @@ func CmdUpdateCoreParams() *cobra.Command { return err } - msg := types.NewMsgUpdateCoreParams( + msg := types.NewMsgUpdateChainParams( clientCtx.GetFromAddress().String(), &clientParams, ) diff --git a/x/observer/genesis.go b/x/observer/genesis.go index ca98575668..1f22e4208f 100644 --- a/x/observer/genesis.go +++ b/x/observer/genesis.go @@ -10,17 +10,30 @@ import ( // InitGenesis initializes the observer module's state from a provided genesis // state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { - observerCount := uint64(0) if genState.Observers.Len() > 0 { k.SetObserverSet(ctx, genState.Observers) observerCount = uint64(len(genState.Observers.ObserverList)) } - // If core params are defined set them, otherwise set default - if len(genState.CoreParamsList.CoreParams) > 0 { - k.SetCoreParams(ctx, genState.CoreParamsList) + + // if chian params are defined set them + if len(genState.ChainParamsList.ChainParams) > 0 { + k.SetChainParamsList(ctx, genState.ChainParamsList) } else { - k.SetCoreParams(ctx, types.GetCoreParams()) + // if no chain params are defined, set localnet chains for test purposes + btcChainParams := types.GetDefaultBtcRegtestChainParams() + btcChainParams.IsSupported = true + goerliChainParams := types.GetDefaultGoerliLocalnetChainParams() + goerliChainParams.IsSupported = true + zetaPrivnetChainParams := types.GetDefaultZetaPrivnetChainParams() + zetaPrivnetChainParams.IsSupported = true + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + btcChainParams, + goerliChainParams, + zetaPrivnetChainParams, + }, + }) } // Set all the nodeAccount @@ -125,9 +138,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { params := k.GetParams(ctx) - coreParams, found := k.GetAllCoreParams(ctx) + chainParams, found := k.GetChainParamsList(ctx) if !found { - coreParams = types.CoreParamsList{} + chainParams = types.ChainParamsList{} } // Get all node accounts @@ -178,8 +191,8 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { return &types.GenesisState{ Ballots: k.GetAllBallots(ctx), + ChainParamsList: chainParams, Observers: os, - CoreParamsList: coreParams, Params: ¶ms, NodeAccountList: nodeAccounts, CrosschainFlags: cf, diff --git a/x/observer/genesis_test.go b/x/observer/genesis_test.go index 1cd0422e79..56cc00352f 100644 --- a/x/observer/genesis_test.go +++ b/x/observer/genesis_test.go @@ -31,8 +31,8 @@ func TestGenesis(t *testing.T) { }, CrosschainFlags: types.DefaultCrosschainFlags(), Keygen: sample.Keygen(t), + ChainParamsList: sample.ChainParamsList(), LastObserverCount: sample.LastObserverCount(10), - CoreParamsList: sample.CoreParamsList(), TssFundMigrators: []types.TssFundMigratorInfo{sample.TssFundsMigrator(1), sample.TssFundsMigrator(2)}, ChainNonces: []types.ChainNonces{ sample.ChainNonces(t, "0"), diff --git a/x/observer/keeper/chain_params.go b/x/observer/keeper/chain_params.go new file mode 100644 index 0000000000..b28adc6e23 --- /dev/null +++ b/x/observer/keeper/chain_params.go @@ -0,0 +1,73 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func (k Keeper) SetChainParamsList(ctx sdk.Context, chainParams types.ChainParamsList) { + store := ctx.KVStore(k.storeKey) + b := k.cdc.MustMarshal(&chainParams) + key := types.KeyPrefix(fmt.Sprintf("%s", types.AllChainParamsKey)) + store.Set(key, b) +} + +func (k Keeper) GetChainParamsList(ctx sdk.Context) (val types.ChainParamsList, found bool) { + found = false + store := ctx.KVStore(k.storeKey) + b := store.Get(types.KeyPrefix(fmt.Sprintf("%s", types.AllChainParamsKey))) + if b == nil { + return + } + found = true + k.cdc.MustUnmarshal(b, &val) + return +} + +func (k Keeper) GetChainParamsByChainID(ctx sdk.Context, chainID int64) (*types.ChainParams, bool) { + allChainParams, found := k.GetChainParamsList(ctx) + if !found { + return &types.ChainParams{}, false + } + for _, chainParams := range allChainParams.ChainParams { + if chainParams.ChainId == chainID { + return chainParams, true + } + } + return &types.ChainParams{}, false +} + +// GetSupportedChainFromChainID returns the chain from the chain id +// it returns nil if the chain doesn't exist or is not supported +func (k Keeper) GetSupportedChainFromChainID(ctx sdk.Context, chainID int64) *common.Chain { + cpl, found := k.GetChainParamsList(ctx) + if !found { + return nil + } + + for _, cp := range cpl.ChainParams { + if cp.ChainId == chainID && cp.IsSupported { + return common.GetChainFromChainID(chainID) + } + } + return nil +} + +// GetSupportedChains returns the list of supported chains +func (k Keeper) GetSupportedChains(ctx sdk.Context) []*common.Chain { + cpl, found := k.GetChainParamsList(ctx) + if !found { + return []*common.Chain{} + } + + var chains []*common.Chain + for _, cp := range cpl.ChainParams { + if cp.IsSupported { + chains = append(chains, common.GetChainFromChainID(cp.ChainId)) + } + } + return chains +} diff --git a/x/observer/keeper/chain_params_test.go b/x/observer/keeper/chain_params_test.go new file mode 100644 index 0000000000..c9142b7526 --- /dev/null +++ b/x/observer/keeper/chain_params_test.go @@ -0,0 +1,78 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_GetSupportedChainFromChainID(t *testing.T) { + t.Run("return nil if chain not found", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + + // no core params list + require.Nil(t, k.GetSupportedChainFromChainID(ctx, getValidEthChainIDWithIndex(t, 0))) + + // core params list but chain not in list + setSupportedChain(ctx, *k, getValidEthChainIDWithIndex(t, 0)) + require.Nil(t, k.GetSupportedChainFromChainID(ctx, getValidEthChainIDWithIndex(t, 1))) + + // chain params list but chain not supported + chainParams := sample.ChainParams(getValidEthChainIDWithIndex(t, 0)) + chainParams.IsSupported = false + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{chainParams}, + }) + require.Nil(t, k.GetSupportedChainFromChainID(ctx, getValidEthChainIDWithIndex(t, 0))) + }) + + t.Run("return chain if chain found", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + chainID := getValidEthChainIDWithIndex(t, 0) + setSupportedChain(ctx, *k, getValidEthChainIDWithIndex(t, 1), chainID) + chain := k.GetSupportedChainFromChainID(ctx, chainID) + require.NotNil(t, chain) + require.EqualValues(t, chainID, chain.ChainId) + }) +} + +func TestKeeper_GetSupportedChains(t *testing.T) { + t.Run("return empty list if no core params list", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + require.Empty(t, k.GetSupportedChains(ctx)) + }) + + t.Run("return list containing supported chains", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + + require.Greater(t, len(common.ExternalChainList()), 5) + supported1 := common.ExternalChainList()[0] + supported2 := common.ExternalChainList()[1] + unsupported := common.ExternalChainList()[2] + supported3 := common.ExternalChainList()[3] + supported4 := common.ExternalChainList()[4] + + var chainParamsList []*types.ChainParams + chainParamsList = append(chainParamsList, sample.ChainParamsSupported(supported1.ChainId)) + chainParamsList = append(chainParamsList, sample.ChainParamsSupported(supported2.ChainId)) + chainParamsList = append(chainParamsList, sample.ChainParams(unsupported.ChainId)) + chainParamsList = append(chainParamsList, sample.ChainParamsSupported(supported3.ChainId)) + chainParamsList = append(chainParamsList, sample.ChainParamsSupported(supported4.ChainId)) + + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: chainParamsList, + }) + + supportedChains := k.GetSupportedChains(ctx) + + require.Len(t, supportedChains, 4) + require.EqualValues(t, supported1.ChainId, supportedChains[0].ChainId) + require.EqualValues(t, supported2.ChainId, supportedChains[1].ChainId) + require.EqualValues(t, supported3.ChainId, supportedChains[2].ChainId) + require.EqualValues(t, supported4.ChainId, supportedChains[3].ChainId) + }) +} diff --git a/x/observer/keeper/grpc_query_chain_params.go b/x/observer/keeper/grpc_query_chain_params.go new file mode 100644 index 0000000000..e35d4087a4 --- /dev/null +++ b/x/observer/keeper/grpc_query_chain_params.go @@ -0,0 +1,46 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k Keeper) GetChainParamsForChain( + goCtx context.Context, + req *types.QueryGetChainParamsForChainRequest, +) (*types.QueryGetChainParamsForChainResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + chainParams, found := k.GetChainParamsByChainID(ctx, req.ChainId) + if !found { + return nil, status.Error(codes.NotFound, "chain params not found") + } + return &types.QueryGetChainParamsForChainResponse{ + ChainParams: chainParams, + }, nil +} + +func (k Keeper) GetChainParams( + goCtx context.Context, + req *types.QueryGetChainParamsRequest, +) (*types.QueryGetChainParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + chainParams, found := k.GetChainParamsList(ctx) + if !found { + return nil, status.Error(codes.NotFound, "chain params not found") + } + return &types.QueryGetChainParamsResponse{ + ChainParams: &chainParams, + }, nil +} diff --git a/x/observer/keeper/grpc_query_core_params.go b/x/observer/keeper/grpc_query_core_params.go deleted file mode 100644 index d55daa98a9..0000000000 --- a/x/observer/keeper/grpc_query_core_params.go +++ /dev/null @@ -1,40 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/x/observer/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -func (k Keeper) GetCoreParamsForChain(goCtx context.Context, req *types.QueryGetCoreParamsForChainRequest) (*types.QueryGetCoreParamsForChainResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") - } - ctx := sdk.UnwrapSDKContext(goCtx) - coreParams, found := k.GetCoreParamsByChainID(ctx, req.ChainId) - if !found { - return nil, status.Error(codes.NotFound, "core params not found") - } - return &types.QueryGetCoreParamsForChainResponse{ - CoreParams: coreParams, - }, nil -} - -func (k Keeper) GetCoreParams(goCtx context.Context, req *types.QueryGetCoreParamsRequest) (*types.QueryGetCoreParamsResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") - } - - ctx := sdk.UnwrapSDKContext(goCtx) - - coreParams, found := k.GetAllCoreParams(ctx) - if !found { - return nil, status.Error(codes.NotFound, "core params not found") - } - return &types.QueryGetCoreParamsResponse{ - CoreParams: &coreParams, - }, nil -} diff --git a/x/observer/keeper/grpc_query_supported_chain.go b/x/observer/keeper/grpc_query_supported_chain.go index ab7dd1468c..dbd985d53c 100644 --- a/x/observer/keeper/grpc_query_supported_chain.go +++ b/x/observer/keeper/grpc_query_supported_chain.go @@ -9,6 +9,6 @@ import ( func (k Keeper) SupportedChains(goCtx context.Context, _ *types.QuerySupportedChains) (*types.QuerySupportedChainsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - chains := k.GetParams(ctx).GetSupportedChains() + chains := k.GetSupportedChains(ctx) return &types.QuerySupportedChainsResponse{Chains: chains}, nil } diff --git a/x/observer/keeper/hooks.go b/x/observer/keeper/hooks.go index 097f9e42c7..4589adf774 100644 --- a/x/observer/keeper/hooks.go +++ b/x/observer/keeper/hooks.go @@ -84,6 +84,7 @@ func (k Keeper) CleanSlashedValidator(ctx sdk.Context, valAddress sdk.ValAddress tokensToBurn := sdk.NewDecFromInt(validator.Tokens).Mul(fraction) resultingTokens := validator.Tokens.Sub(tokensToBurn.Ceil().TruncateInt()) + mindelegation, found := types.GetMinObserverDelegation() if !found { return types.ErrMinDelegationNotFound diff --git a/x/observer/keeper/migrator.go b/x/observer/keeper/migrator.go index bb40ea8151..e256358d87 100644 --- a/x/observer/keeper/migrator.go +++ b/x/observer/keeper/migrator.go @@ -31,7 +31,7 @@ func (m Migrator) Migrate2to3(ctx sdk.Context) error { } func (m Migrator) Migrate3to4(ctx sdk.Context) error { - return v4.MigrateStore(ctx, m.observerKeeper.storeKey, m.observerKeeper.cdc) + return v4.MigrateStore(ctx, m.observerKeeper) } func (m Migrator) Migrate4to5(ctx sdk.Context) error { diff --git a/x/observer/keeper/msg_server_add_blame_vote.go b/x/observer/keeper/msg_server_add_blame_vote.go index 80fb5d66aa..40f2fe54b0 100644 --- a/x/observer/keeper/msg_server_add_blame_vote.go +++ b/x/observer/keeper/msg_server_add_blame_vote.go @@ -14,7 +14,7 @@ func (k msgServer) AddBlameVote(goCtx context.Context, vote *types.MsgAddBlameVo ctx := sdk.UnwrapSDKContext(goCtx) observationType := types.ObservationType_TSSKeySign // GetChainFromChainID makes sure we are getting only supported chains , if a chain support has been turned on using gov proposal, this function returns nil - observationChain := k.GetParams(ctx).GetChainFromChainID(vote.ChainId) + observationChain := k.GetSupportedChainFromChainID(ctx, vote.ChainId) if observationChain == nil { return nil, sdkerrors.Wrap(crosschainTypes.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Blame vote", vote.ChainId)) } diff --git a/x/observer/keeper/msg_server_add_block_header.go b/x/observer/keeper/msg_server_add_block_header.go index fb1ae72742..56b0bfbec7 100644 --- a/x/observer/keeper/msg_server_add_block_header.go +++ b/x/observer/keeper/msg_server_add_block_header.go @@ -15,7 +15,11 @@ func (k msgServer) AddBlockHeader(goCtx context.Context, msg *types.MsgAddBlockH ctx := sdk.UnwrapSDKContext(goCtx) // check authorization for this chain - chain := common.GetChainFromChainID(msg.ChainId) + chain := k.GetSupportedChainFromChainID(ctx, msg.ChainId) + if chain == nil { + return nil, cosmoserrors.Wrapf(types.ErrSupportedChains, "chain id: %d", msg.ChainId) + } + if ok := k.IsAuthorized(ctx, msg.Creator); !ok { return nil, types.ErrNotAuthorizedPolicy } diff --git a/x/observer/keeper/msg_server_add_block_header_test.go b/x/observer/keeper/msg_server_add_block_header_test.go index 04e9e9c560..7f475bad4c 100644 --- a/x/observer/keeper/msg_server_add_block_header_test.go +++ b/x/observer/keeper/msg_server_add_block_header_test.go @@ -131,6 +131,22 @@ func TestMsgServer_AddBlockHeader(t *testing.T) { require.Error(t, err) }, }, + { + name: "should fail if chain is not supported", + msg: &types.MsgAddBlockHeader{ + Creator: observerAddress.String(), + ChainId: 9999, + BlockHash: header3.Hash().Bytes(), + Height: 3, + Header: common.NewEthereumHeader(header3RLP), + }, + IsEthTypeChainEnabled: true, + IsBtcTypeChainEnabled: true, + validator: validator, + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.ErrorIs(t, err, types.ErrSupportedChains) + }, + }, } for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { @@ -149,6 +165,9 @@ func TestMsgServer_AddBlockHeader(t *testing.T) { IsBtcTypeChainEnabled: tc.IsBtcTypeChainEnabled, }, }) + + setSupportedChain(ctx, *k, common.GoerliLocalnetChain().ChainId) + _, err := srv.AddBlockHeader(ctx, tc.msg) tc.wantErr(t, err) if err == nil { diff --git a/x/observer/keeper/msg_server_remove_chain_params.go b/x/observer/keeper/msg_server_remove_chain_params.go new file mode 100644 index 0000000000..4ee6259571 --- /dev/null +++ b/x/observer/keeper/msg_server_remove_chain_params.go @@ -0,0 +1,39 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// RemoveChainParams removes chain parameters for a specific chain. +func (k msgServer) RemoveChainParams(goCtx context.Context, msg *types.MsgRemoveChainParams) (*types.MsgRemoveChainParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(types.Policy_Type_group2) { + return &types.MsgRemoveChainParamsResponse{}, types.ErrNotAuthorizedPolicy + } + + // find current core params list or initialize a new one + chainParamsList, found := k.GetChainParamsList(ctx) + if !found { + return &types.MsgRemoveChainParamsResponse{}, types.ErrChainParamsNotFound + } + + // remove the core param from the list + newChainParamsList := types.ChainParamsList{} + found = false + for _, cp := range chainParamsList.ChainParams { + if cp.ChainId != msg.ChainId { + newChainParamsList.ChainParams = append(newChainParamsList.ChainParams, cp) + } else { + found = true + } + } + if !found { + return &types.MsgRemoveChainParamsResponse{}, types.ErrChainParamsNotFound + } + + k.SetChainParamsList(ctx, newChainParamsList) + return &types.MsgRemoveChainParamsResponse{}, nil +} diff --git a/x/observer/keeper/msg_server_remove_chain_params_test.go b/x/observer/keeper/msg_server_remove_chain_params_test.go new file mode 100644 index 0000000000..d99b301403 --- /dev/null +++ b/x/observer/keeper/msg_server_remove_chain_params_test.go @@ -0,0 +1,133 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_RemoveChainParams(t *testing.T) { + t.Run("can update chain params", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chain1 := common.ExternalChainList()[0].ChainId + chain2 := common.ExternalChainList()[1].ChainId + chain3 := common.ExternalChainList()[2].ChainId + + // set admin + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + // add chain params + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + sample.ChainParams(chain1), + sample.ChainParams(chain2), + sample.ChainParams(chain3), + }, + }) + + // remove chain params + _, err := srv.RemoveChainParams(sdk.WrapSDKContext(ctx), &types.MsgRemoveChainParams{ + Creator: admin, + ChainId: chain2, + }) + require.NoError(t, err) + + // check list has two chain params + chainParamsList, found := k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 2) + require.Equal(t, chain1, chainParamsList.ChainParams[0].ChainId) + require.Equal(t, chain3, chainParamsList.ChainParams[1].ChainId) + + // remove chain params + _, err = srv.RemoveChainParams(sdk.WrapSDKContext(ctx), &types.MsgRemoveChainParams{ + Creator: admin, + ChainId: chain1, + }) + require.NoError(t, err) + + // check list has one chain params + chainParamsList, found = k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 1) + require.Equal(t, chain3, chainParamsList.ChainParams[0].ChainId) + + // remove chain params + _, err = srv.RemoveChainParams(sdk.WrapSDKContext(ctx), &types.MsgRemoveChainParams{ + Creator: admin, + ChainId: chain3, + }) + require.NoError(t, err) + + // check list has no chain params + chainParamsList, found = k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 0) + }) + + t.Run("cannot remove chain params if not authorized", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + _, err := srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + + // group 1 should not be able to update core params + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) + + _, err = srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + + }) + + t.Run("cannot remove if chain ID not found", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + // set admin + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + // not found if no chain params + _, found := k.GetChainParamsList(ctx) + require.False(t, found) + + _, err := srv.RemoveChainParams(sdk.WrapSDKContext(ctx), &types.MsgRemoveChainParams{ + Creator: admin, + ChainId: common.ExternalChainList()[0].ChainId, + }) + require.ErrorIs(t, err, types.ErrChainParamsNotFound) + + // add chain params + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + sample.ChainParams(common.ExternalChainList()[0].ChainId), + sample.ChainParams(common.ExternalChainList()[1].ChainId), + sample.ChainParams(common.ExternalChainList()[2].ChainId), + }, + }) + + // not found if chain ID not in list + _, err = srv.RemoveChainParams(sdk.WrapSDKContext(ctx), &types.MsgRemoveChainParams{ + Creator: admin, + ChainId: common.ExternalChainList()[3].ChainId, + }) + require.ErrorIs(t, err, types.ErrChainParamsNotFound) + }) +} diff --git a/x/observer/keeper/msg_server_update_chain_params.go b/x/observer/keeper/msg_server_update_chain_params.go new file mode 100644 index 0000000000..638eb373f0 --- /dev/null +++ b/x/observer/keeper/msg_server_update_chain_params.go @@ -0,0 +1,40 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// UpdateChainParams updates chain parameters for a specific chain, or add a new one. +// Chain parameters include: confirmation count, outbound transaction schedule interval, ZETA token, +// connector and ERC20 custody contract addresses, etc. +// Only the admin policy account is authorized to broadcast this message. +func (k msgServer) UpdateChainParams(goCtx context.Context, msg *types.MsgUpdateChainParams) (*types.MsgUpdateChainParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(types.Policy_Type_group2) { + return &types.MsgUpdateChainParamsResponse{}, types.ErrNotAuthorizedPolicy + } + + // find current chain params list or initialize a new one + chainParamsList, found := k.GetChainParamsList(ctx) + if !found { + chainParamsList = types.ChainParamsList{} + } + + // find chain params for the chain + for i, cp := range chainParamsList.ChainParams { + if cp.ChainId == msg.ChainParams.ChainId { + chainParamsList.ChainParams[i] = msg.ChainParams + k.SetChainParamsList(ctx, chainParamsList) + return &types.MsgUpdateChainParamsResponse{}, nil + } + } + + // add new chain params + chainParamsList.ChainParams = append(chainParamsList.ChainParams, msg.ChainParams) + k.SetChainParamsList(ctx, chainParamsList) + + return &types.MsgUpdateChainParamsResponse{}, nil +} diff --git a/x/observer/keeper/msg_server_update_chain_params_test.go b/x/observer/keeper/msg_server_update_chain_params_test.go new file mode 100644 index 0000000000..7b2f8a5cb3 --- /dev/null +++ b/x/observer/keeper/msg_server_update_chain_params_test.go @@ -0,0 +1,115 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_UpdateChainParams(t *testing.T) { + t.Run("can update chain params", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chain1 := common.ExternalChainList()[0].ChainId + chain2 := common.ExternalChainList()[1].ChainId + chain3 := common.ExternalChainList()[2].ChainId + + // set admin + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) + + // check list initially empty + _, found := k.GetChainParamsList(ctx) + require.False(t, found) + + // a new chain params can be added + chainParams1 := sample.ChainParams(chain1) + _, err := srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: admin, + ChainParams: chainParams1, + }) + require.NoError(t, err) + + // check list has one chain params + chainParamsList, found := k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 1) + require.Equal(t, chainParams1, chainParamsList.ChainParams[0]) + + // a new chian params can be added + chainParams2 := sample.ChainParams(chain2) + _, err = srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: admin, + ChainParams: chainParams2, + }) + require.NoError(t, err) + + // check list has two chain params + chainParamsList, found = k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 2) + require.Equal(t, chainParams1, chainParamsList.ChainParams[0]) + require.Equal(t, chainParams2, chainParamsList.ChainParams[1]) + + // a new chain params can be added + chainParams3 := sample.ChainParams(chain3) + _, err = srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: admin, + ChainParams: chainParams3, + }) + require.NoError(t, err) + + // check list has three chain params + chainParamsList, found = k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 3) + require.Equal(t, chainParams1, chainParamsList.ChainParams[0]) + require.Equal(t, chainParams2, chainParamsList.ChainParams[1]) + require.Equal(t, chainParams3, chainParamsList.ChainParams[2]) + + // chain params can be updated + chainParams2.ConfirmationCount = chainParams2.ConfirmationCount + 1 + _, err = srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: admin, + ChainParams: chainParams2, + }) + require.NoError(t, err) + + // check list has three chain params + chainParamsList, found = k.GetChainParamsList(ctx) + require.True(t, found) + require.Len(t, chainParamsList.ChainParams, 3) + require.Equal(t, chainParams1, chainParamsList.ChainParams[0]) + require.Equal(t, chainParams2, chainParamsList.ChainParams[1]) + require.Equal(t, chainParams3, chainParamsList.ChainParams[2]) + }) + + t.Run("cannot update chain params if not authorized", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + _, err := srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + + // group 1 should not be able to update chain params + admin := sample.AccAddress() + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) + + _, err = srv.UpdateChainParams(sdk.WrapSDKContext(ctx), &types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }) + require.ErrorIs(t, err, types.ErrNotAuthorizedPolicy) + + }) +} diff --git a/x/observer/keeper/msg_server_update_core_params.go b/x/observer/keeper/msg_server_update_core_params.go deleted file mode 100644 index 87fbbc9606..0000000000 --- a/x/observer/keeper/msg_server_update_core_params.go +++ /dev/null @@ -1,39 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -// UpdateCoreParams updates core parameters for a specific chain. Core parameters include -// confirmation count, outbound transaction schedule interval, ZETA token, -// connector and ERC20 custody contract addresses, etc. -// -// Throws an error if the chain ID is not supported. -// -// Only the admin policy account is authorized to broadcast this message. -func (k msgServer) UpdateCoreParams(goCtx context.Context, msg *types.MsgUpdateCoreParams) (*types.MsgUpdateCoreParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(types.Policy_Type_group2) { - return &types.MsgUpdateCoreParamsResponse{}, types.ErrNotAuthorizedPolicy - } - if !k.GetParams(ctx).IsChainIDSupported(msg.CoreParams.ChainId) { - return &types.MsgUpdateCoreParamsResponse{}, types.ErrSupportedChains - } - coreParams, found := k.GetAllCoreParams(ctx) - if !found { - return &types.MsgUpdateCoreParamsResponse{}, types.ErrCoreParamsNotSet - } - newCoreParams := make([]*types.CoreParams, len(coreParams.CoreParams)) - for i, cp := range coreParams.CoreParams { - if cp.ChainId == msg.CoreParams.ChainId { - newCoreParams[i] = msg.CoreParams - continue - } - newCoreParams[i] = cp - } - k.SetCoreParams(ctx, types.CoreParamsList{CoreParams: newCoreParams}) - return &types.MsgUpdateCoreParamsResponse{}, nil -} diff --git a/x/observer/keeper/msg_server_update_observer.go b/x/observer/keeper/msg_server_update_observer.go index 7a04c35ac9..c3aaee7472 100644 --- a/x/observer/keeper/msg_server_update_observer.go +++ b/x/observer/keeper/msg_server_update_observer.go @@ -9,6 +9,7 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) +// UpdateObserver handles updating an observer address // Authorized: admin policy group 2 (admin update), old observer address (if the // reason is that the observer was tombstoned). func (k msgServer) UpdateObserver(goCtx context.Context, msg *types.MsgUpdateObserver) (*types.MsgUpdateObserverResponse, error) { @@ -21,6 +22,7 @@ func (k msgServer) UpdateObserver(goCtx context.Context, msg *types.MsgUpdateObs if !ok { return nil, errorsmod.Wrap(types.ErrUpdateObserver, fmt.Sprintf("Unable to update observer with update reason : %s", msg.UpdateReason)) } + // We do not use IsAuthorized here because we want to allow tombstoned observers to be updated if !k.IsAddressPartOfObserverSet(ctx, msg.OldObserverAddress) { return nil, errorsmod.Wrap(types.ErrNotAuthorized, fmt.Sprintf("Observer address is not authorized : %s", msg.OldObserverAddress)) diff --git a/x/observer/keeper/msg_server_update_observer_test.go b/x/observer/keeper/msg_server_update_observer_test.go index 181c360bb1..649ce6ca13 100644 --- a/x/observer/keeper/msg_server_update_observer_test.go +++ b/x/observer/keeper/msg_server_update_observer_test.go @@ -38,6 +38,7 @@ func TestMsgServer_UpdateObserver(t *testing.T) { Tombstoned: true, MissedBlocksCounter: 1, }) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) assert.NoError(t, err) diff --git a/x/observer/keeper/params.go b/x/observer/keeper/params.go index c3516e0633..3c570c9cf0 100644 --- a/x/observer/keeper/params.go +++ b/x/observer/keeper/params.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -22,35 +20,3 @@ func (k Keeper) GetParamsIfExists(ctx sdk.Context) (params types.Params) { func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { k.paramstore.SetParamSet(ctx, ¶ms) } - -func (k Keeper) SetCoreParams(ctx sdk.Context, coreParams types.CoreParamsList) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshal(&coreParams) - key := types.KeyPrefix(fmt.Sprintf("%s", types.AllCoreParams)) - store.Set(key, b) -} - -func (k Keeper) GetAllCoreParams(ctx sdk.Context) (val types.CoreParamsList, found bool) { - found = false - store := ctx.KVStore(k.storeKey) - b := store.Get(types.KeyPrefix(fmt.Sprintf("%s", types.AllCoreParams))) - if b == nil { - return - } - found = true - k.cdc.MustUnmarshal(b, &val) - return -} - -func (k Keeper) GetCoreParamsByChainID(ctx sdk.Context, chainID int64) (*types.CoreParams, bool) { - allCoreParams, found := k.GetAllCoreParams(ctx) - if !found { - return &types.CoreParams{}, false - } - for _, coreParams := range allCoreParams.CoreParams { - if coreParams.ChainId == chainID { - return coreParams, true - } - } - return &types.CoreParams{}, false -} diff --git a/x/observer/keeper/pending_nonces.go b/x/observer/keeper/pending_nonces.go index 6ab5b61ca4..eb140ee4bd 100644 --- a/x/observer/keeper/pending_nonces.go +++ b/x/observer/keeper/pending_nonces.go @@ -81,7 +81,7 @@ func (k Keeper) RemoveFromPendingNonces(ctx sdk.Context, tssPubkey string, chain func (k Keeper) SetTssAndUpdateNonce(ctx sdk.Context, tss types.TSS) { k.SetTSS(ctx, tss) // initialize the nonces and pending nonces of all enabled chains - supportedChains := k.GetParams(ctx).GetSupportedChains() + supportedChains := k.GetSupportedChains(ctx) for _, chain := range supportedChains { chainNonce := types.ChainNonces{ Index: chain.ChainName.String(), diff --git a/x/observer/keeper/utils.go b/x/observer/keeper/utils.go index fecdbd5f73..5a1896755e 100644 --- a/x/observer/keeper/utils.go +++ b/x/observer/keeper/utils.go @@ -4,7 +4,6 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -46,23 +45,30 @@ func (k Keeper) IsAuthorized(ctx sdk.Context, address string) bool { return true } -func (k Keeper) FindBallot(ctx sdk.Context, index string, chain *common.Chain, observationType types.ObservationType) (ballot types.Ballot, isNew bool, err error) { +func (k Keeper) FindBallot( + ctx sdk.Context, + index string, + chain *common.Chain, + observationType types.ObservationType, +) (ballot types.Ballot, isNew bool, err error) { isNew = false ballot, found := k.GetBallot(ctx, index) if !found { observerSet, _ := k.GetObserverSet(ctx) - obsParams := k.GetParams(ctx).GetParamsForChain(chain) - if !obsParams.IsSupported { - err = errors.Wrap(types.ErrSupportedChains, fmt.Sprintf("Thresholds not set for Chain %s and Observation %s", chain.String(), observationType)) + + cp, found := k.GetChainParamsByChainID(ctx, chain.ChainId) + if !found || cp == nil || !cp.IsSupported { + err = types.ErrSupportedChains return } + ballot = types.Ballot{ Index: "", BallotIdentifier: index, VoterList: observerSet.ObserverList, Votes: types.CreateVotes(len(observerSet.ObserverList)), ObservationType: observationType, - BallotThreshold: obsParams.BallotThreshold, + BallotThreshold: cp.BallotThreshold, BallotStatus: types.BallotStatus_BallotInProgress, BallotCreationHeight: ctx.BlockHeight(), } @@ -123,11 +129,13 @@ func (k Keeper) CheckObserverSelfDelegation(ctx sdk.Context, accAddress string) if !found { return types.ErrSelfDelegation } + minDelegation, err := types.GetMinObserverDelegationDec() if err != nil { return err } tokens := validator.TokensFromShares(delegation.Shares) + if tokens.LT(minDelegation) { k.RemoveObserverFromSet(ctx, accAddress) } diff --git a/x/observer/keeper/utils_test.go b/x/observer/keeper/utils_test.go index a958fb5dc3..e62cc57758 100644 --- a/x/observer/keeper/utils_test.go +++ b/x/observer/keeper/utils_test.go @@ -5,16 +5,47 @@ import ( "testing" "time" + sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + zetacommon "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) +// setSupportedChain sets the supported chains for the observer module +func setSupportedChain(ctx sdk.Context, observerKeeper keeper.Keeper, chainIDs ...int64) { + chainParamsList := make([]*types.ChainParams, len(chainIDs)) + for i, chainID := range chainIDs { + chainParams := sample.ChainParams(chainID) + chainParams.IsSupported = true + chainParamsList[i] = chainParams + } + observerKeeper.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: chainParamsList, + }) +} + +// getValidEthChainIDWithIndex get a valid eth chain id with index +func getValidEthChainIDWithIndex(t *testing.T, index int) int64 { + switch index { + case 0: + return zetacommon.GoerliLocalnetChain().ChainId + case 1: + return zetacommon.GoerliChain().ChainId + default: + require.Fail(t, "invalid index") + } + return 0 +} + func TestKeeper_IsAuthorized(t *testing.T) { t.Run("authorized observer", func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) + r := rand.New(rand.NewSource(9)) // Set validator in the store diff --git a/x/observer/migrations/v4/migrate.go b/x/observer/migrations/v4/migrate.go index dbf1e5c7df..a23cc28dd5 100644 --- a/x/observer/migrations/v4/migrate.go +++ b/x/observer/migrations/v4/migrate.go @@ -8,7 +8,24 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) -func MigrateStore(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { +// observerKeeper prevents circular dependency +type observerKeeper interface { + GetParams(ctx sdk.Context) types.Params + SetParams(ctx sdk.Context, params types.Params) + GetChainParamsList(ctx sdk.Context) (params types.ChainParamsList, found bool) + SetChainParamsList(ctx sdk.Context, params types.ChainParamsList) + StoreKey() storetypes.StoreKey + Codec() codec.BinaryCodec +} + +func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error { + if err := MigrateCrosschainFlags(ctx, observerKeeper.StoreKey(), observerKeeper.Codec()); err != nil { + return err + } + return MigrateObserverParams(ctx, observerKeeper) +} + +func MigrateCrosschainFlags(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { newCrossChainFlags := types.DefaultCrosschainFlags() var val types.LegacyCrosschainFlags store := prefix.NewStore(ctx.KVStore(observerStoreKey), types.KeyPrefix(types.CrosschainFlagsKey)) @@ -28,3 +45,31 @@ func MigrateStore(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc cod store.Set([]byte{0}, b) return nil } + +// MigrateObserverParams migrates the observer params to the chain params +// the function assumes that each oberver params entry has a corresponding chain params entry +// if the chain is not found, the observer params entry is ignored because it is considered as not supported +func MigrateObserverParams(ctx sdk.Context, observerKeeper observerKeeper) error { + chainParamsList, found := observerKeeper.GetChainParamsList(ctx) + if !found { + // no chain params found, nothing to migrate + return nil + } + + // search for the observer params with chain params entry + observerParams := observerKeeper.GetParams(ctx).ObserverParams + for _, observerParam := range observerParams { + for i := range chainParamsList.ChainParams { + // if the chain is found, update the chain params with the observer params + if chainParamsList.ChainParams[i].ChainId == observerParam.Chain.ChainId { + chainParamsList.ChainParams[i].MinObserverDelegation = observerParam.MinObserverDelegation + chainParamsList.ChainParams[i].BallotThreshold = observerParam.BallotThreshold + chainParamsList.ChainParams[i].IsSupported = observerParam.IsSupported + break + } + } + } + + observerKeeper.SetChainParamsList(ctx, chainParamsList) + return nil +} diff --git a/x/observer/migrations/v4/migrate_test.go b/x/observer/migrations/v4/migrate_test.go index 2e420749b9..3a64fd97ab 100644 --- a/x/observer/migrations/v4/migrate_test.go +++ b/x/observer/migrations/v4/migrate_test.go @@ -4,14 +4,17 @@ import ( "testing" "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" v4 "github.com/zeta-chain/zetacore/x/observer/migrations/v4" "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestMigrateStore(t *testing.T) { - +func TestMigrateCrosschainFlags(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) store := prefix.NewStore(ctx.KVStore(k.StoreKey()), types.KeyPrefix(types.CrosschainFlagsKey)) legacyFlags := types.LegacyCrosschainFlags{ @@ -21,10 +24,84 @@ func TestMigrateStore(t *testing.T) { } val := k.Codec().MustMarshal(&legacyFlags) store.Set([]byte{0}, val) - err := v4.MigrateStore(ctx, k.StoreKey(), k.Codec()) + + err := v4.MigrateCrosschainFlags(ctx, k.StoreKey(), k.Codec()) assert.NoError(t, err) + flags, found := k.GetCrosschainFlags(ctx) assert.True(t, found) assert.True(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) assert.True(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) } + +func TestMigrateObserverParams(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + + // set chain params + previousChainParamsList := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + sample.ChainParams(1), + sample.ChainParams(2), + sample.ChainParams(3), + sample.ChainParams(4), + }, + } + k.SetChainParamsList(ctx, previousChainParamsList) + + // set observer params + dec42, err := sdk.NewDecFromStr("0.42") + require.NoError(t, err) + dec43, err := sdk.NewDecFromStr("0.43") + require.NoError(t, err) + dec1000, err := sdk.NewDecFromStr("1000.0") + require.NoError(t, err) + dec1001, err := sdk.NewDecFromStr("1001.0") + require.NoError(t, err) + params := types.Params{ + ObserverParams: []*types.ObserverParams{ + { + Chain: &common.Chain{ChainId: 2}, + BallotThreshold: dec42, + MinObserverDelegation: dec1000, + IsSupported: true, + }, + { + Chain: &common.Chain{ChainId: 3}, + BallotThreshold: dec43, + MinObserverDelegation: dec1001, + IsSupported: true, + }, + }, + } + k.SetParams(ctx, params) + + // perform migration + err = v4.MigrateObserverParams(ctx, *k) + require.NoError(t, err) + + // check chain params + newChainParamsList, found := k.GetChainParamsList(ctx) + require.True(t, found) + + // unchanged values + require.EqualValues(t, previousChainParamsList.ChainParams[0], newChainParamsList.ChainParams[0]) + require.EqualValues(t, previousChainParamsList.ChainParams[3], newChainParamsList.ChainParams[3]) + + // changed values + require.EqualValues(t, dec42, newChainParamsList.ChainParams[1].BallotThreshold) + require.EqualValues(t, dec1000, newChainParamsList.ChainParams[1].MinObserverDelegation) + require.EqualValues(t, dec43, newChainParamsList.ChainParams[2].BallotThreshold) + require.EqualValues(t, dec1001, newChainParamsList.ChainParams[2].MinObserverDelegation) + require.True(t, newChainParamsList.ChainParams[1].IsSupported) + require.True(t, newChainParamsList.ChainParams[2].IsSupported) + + // check remaining values are unchanged + previousChainParamsList.ChainParams[1].BallotThreshold = dec42 + previousChainParamsList.ChainParams[2].BallotThreshold = dec43 + previousChainParamsList.ChainParams[1].MinObserverDelegation = dec1000 + previousChainParamsList.ChainParams[2].MinObserverDelegation = dec1001 + previousChainParamsList.ChainParams[1].IsSupported = true + previousChainParamsList.ChainParams[2].IsSupported = true + require.EqualValues(t, previousChainParamsList.ChainParams[1], newChainParamsList.ChainParams[1]) + require.EqualValues(t, previousChainParamsList.ChainParams[2], newChainParamsList.ChainParams[2]) +} diff --git a/x/observer/types/chain_params.go b/x/observer/types/chain_params.go new file mode 100644 index 0000000000..78b66af17d --- /dev/null +++ b/x/observer/types/chain_params.go @@ -0,0 +1,321 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + + errorsmod "cosmossdk.io/errors" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/common" +) + +const ( + zeroAddress = "0x0000000000000000000000000000000000000000" +) + +var ( + DefaultMinObserverDelegation = sdk.MustNewDecFromStr("1000000000000000000000") + DefaultBallotThreshold = sdk.MustNewDecFromStr("0.66") +) + +// Validate checks all chain params correspond to a chain and there is no duplicate chain id +func (cpl ChainParamsList) Validate() error { + // check all chain params correspond to a chain + chainMap := make(map[int64]struct{}) + existingChainMap := make(map[int64]struct{}) + + externalChainList := common.DefaultChainsList() + for _, chain := range externalChainList { + chainMap[chain.ChainId] = struct{}{} + } + + // validate the chain params and check for duplicates + for _, chainParam := range cpl.ChainParams { + if err := ValidateChainParams(chainParam); err != nil { + return err + } + + if _, ok := chainMap[chainParam.ChainId]; !ok { + return fmt.Errorf("chain id %d not found in chain list", chainParam.ChainId) + } + if _, ok := existingChainMap[chainParam.ChainId]; ok { + return fmt.Errorf("duplicated chain id %d found", chainParam.ChainId) + } + existingChainMap[chainParam.ChainId] = struct{}{} + } + return nil +} + +// ValidateChainParams performs some basic checks on chain params +func ValidateChainParams(params *ChainParams) error { + if params == nil { + return fmt.Errorf("chain params cannot be nil") + } + chain := common.GetChainFromChainID(params.ChainId) + if chain == nil { + return fmt.Errorf("ChainId %d not supported", params.ChainId) + } + // zeta chain skips the rest of the checks for now + if chain.IsZetaChain() { + return nil + } + + if params.ConfirmationCount == 0 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "ConfirmationCount must be greater than 0") + } + if params.GasPriceTicker <= 0 || params.GasPriceTicker > 300 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "GasPriceTicker %d out of range", params.GasPriceTicker) + } + if params.InTxTicker <= 0 || params.InTxTicker > 300 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "InTxTicker %d out of range", params.InTxTicker) + } + if params.OutTxTicker <= 0 || params.OutTxTicker > 300 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutTxTicker %d out of range", params.OutTxTicker) + } + if params.OutboundTxScheduleInterval == 0 || params.OutboundTxScheduleInterval > 100 { // 600 secs + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutboundTxScheduleInterval %d out of range", params.OutboundTxScheduleInterval) + } + if params.OutboundTxScheduleLookahead == 0 || params.OutboundTxScheduleLookahead > 500 { // 500 cctxs + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutboundTxScheduleLookahead %d out of range", params.OutboundTxScheduleLookahead) + } + + // chain type specific checks + if common.IsBitcoinChain(params.ChainId) { + if params.WatchUtxoTicker == 0 || params.WatchUtxoTicker > 300 { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "WatchUtxoTicker %d out of range", params.WatchUtxoTicker) + } + } + if common.IsEVMChain(params.ChainId) { + if !validChainContractAddress(params.ZetaTokenContractAddress) { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid ZetaTokenContractAddress %s", params.ZetaTokenContractAddress) + } + if !validChainContractAddress(params.ConnectorContractAddress) { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid ConnectorContractAddress %s", params.ConnectorContractAddress) + } + if !validChainContractAddress(params.Erc20CustodyContractAddress) { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid Erc20CustodyContractAddress %s", params.Erc20CustodyContractAddress) + } + } + + if params.BallotThreshold.IsNil() || params.BallotThreshold.GT(sdk.OneDec()) { + return ErrParamsThreshold + } + + if params.MinObserverDelegation.IsNil() { + return ErrParamsMinObserverDelegation + } + + return nil +} + +func validChainContractAddress(address string) bool { + if !strings.HasPrefix(address, "0x") { + return false + } + return ethcommon.IsHexAddress(address) +} + +// GetDefaultChainParams returns a list of default chain params +// TODO: remove this function +// https://github.com/zeta-chain/node-private/issues/100 +func GetDefaultChainParams() ChainParamsList { + return ChainParamsList{ + ChainParams: []*ChainParams{ + GetDefaultEthMainnetChainParams(), + GetDefaultBscMainnetChainParams(), + GetDefaultBtcMainnetChainParams(), + GetDefaultGoerliTestnetChainParams(), + GetDefaultBscTestnetChainParams(), + GetDefaultMumbaiTestnetChainParams(), + GetDefaultBtcTestnetChainParams(), + GetDefaultBtcRegtestChainParams(), + GetDefaultGoerliLocalnetChainParams(), + GetDefaultZetaPrivnetChainParams(), + }, + } +} + +func GetDefaultEthMainnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.EthChain().ChainId, + ConfirmationCount: 14, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 12, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultBscMainnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.BscMainnetChain().ChainId, + ConfirmationCount: 14, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 5, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultBtcMainnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.BtcMainnetChain().ChainId, + ConfirmationCount: 2, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + WatchUtxoTicker: 30, + InTxTicker: 120, + OutTxTicker: 60, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultGoerliTestnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.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", + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 12, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultBscTestnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.BscTestnetChain().ChainId, + ConfirmationCount: 6, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 5, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultMumbaiTestnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.MumbaiChain().ChainId, + ConfirmationCount: 12, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 2, + OutTxTicker: 15, + WatchUtxoTicker: 0, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 60, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultBtcTestnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.BtcTestNetChain().ChainId, + ConfirmationCount: 2, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + WatchUtxoTicker: 30, + InTxTicker: 120, + OutTxTicker: 12, + GasPriceTicker: 30, + OutboundTxScheduleInterval: 30, + OutboundTxScheduleLookahead: 100, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultBtcRegtestChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.BtcRegtestChain().ChainId, + ConfirmationCount: 1, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + GasPriceTicker: 5, + WatchUtxoTicker: 1, + InTxTicker: 1, + OutTxTicker: 2, + OutboundTxScheduleInterval: 2, + OutboundTxScheduleLookahead: 5, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultGoerliLocalnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.GoerliLocalnetChain().ChainId, + ConfirmationCount: 1, + ZetaTokenContractAddress: "0x733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9", + ConnectorContractAddress: "0xD28D6A0b8189305551a0A8bd247a6ECa9CE781Ca", + Erc20CustodyContractAddress: "0xff3135df4F2775f4091b81f4c7B6359CfA07862a", + InTxTicker: 2, + OutTxTicker: 2, + WatchUtxoTicker: 0, + GasPriceTicker: 5, + OutboundTxScheduleInterval: 2, + OutboundTxScheduleLookahead: 5, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} +func GetDefaultZetaPrivnetChainParams() *ChainParams { + return &ChainParams{ + ChainId: common.ZetaPrivnetChain().ChainId, + ConfirmationCount: 1, + ZetaTokenContractAddress: zeroAddress, + ConnectorContractAddress: zeroAddress, + Erc20CustodyContractAddress: zeroAddress, + InTxTicker: 2, + OutTxTicker: 2, + WatchUtxoTicker: 0, + GasPriceTicker: 5, + OutboundTxScheduleInterval: 0, + OutboundTxScheduleLookahead: 0, + BallotThreshold: DefaultBallotThreshold, + MinObserverDelegation: DefaultMinObserverDelegation, + IsSupported: false, + } +} diff --git a/x/observer/types/message_update_core_params_test.go b/x/observer/types/chain_params_test.go similarity index 51% rename from x/observer/types/message_update_core_params_test.go rename to x/observer/types/chain_params_test.go index a76c81975b..5852f1f661 100644 --- a/x/observer/types/message_update_core_params_test.go +++ b/x/observer/types/chain_params_test.go @@ -1,27 +1,51 @@ -package types +package types_test import ( "testing" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/zeta-chain/zetacore/x/observer/types" . "gopkg.in/check.v1" ) -type UpdateCoreParamsSuite struct { +func TestChainParamsList_Validate(t *testing.T) { + t.Run("should return no error for default list", func(t *testing.T) { + list := types.GetDefaultChainParams() + err := list.Validate() + require.NoError(t, err) + }) + + t.Run("should return error for invalid chain id", func(t *testing.T) { + list := types.GetDefaultChainParams() + list.ChainParams[0].ChainId = 999 + err := list.Validate() + require.Error(t, err) + }) + + t.Run("should return error for duplicated chain ID", func(t *testing.T) { + list := types.GetDefaultChainParams() + list.ChainParams = append(list.ChainParams, list.ChainParams[0]) + err := list.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "duplicated chain id") + }) +} + +type UpdateChainParamsSuite struct { suite.Suite - evmParams *CoreParams - btcParams *CoreParams + evmParams *types.ChainParams + btcParams *types.ChainParams } -var _ = Suite(&UpdateCoreParamsSuite{}) +var _ = Suite(&UpdateChainParamsSuite{}) -func TestUpdateCoreParamsSuiteSuite(t *testing.T) { - suite.Run(t, new(UpdateCoreParamsSuite)) +func TestUpdateChainParamsSuiteSuite(t *testing.T) { + suite.Run(t, new(UpdateChainParamsSuite)) } -func (s *UpdateCoreParamsSuite) SetupTest() { - s.evmParams = &CoreParams{ +func (s *UpdateChainParamsSuite) SetupTest() { + s.evmParams = &types.ChainParams{ ConfirmationCount: 1, GasPriceTicker: 1, InTxTicker: 1, @@ -33,8 +57,11 @@ func (s *UpdateCoreParamsSuite) SetupTest() { ChainId: 5, OutboundTxScheduleInterval: 1, OutboundTxScheduleLookahead: 1, + BallotThreshold: types.DefaultBallotThreshold, + MinObserverDelegation: types.DefaultMinObserverDelegation, + IsSupported: false, } - s.btcParams = &CoreParams{ + s.btcParams = &types.ChainParams{ ConfirmationCount: 1, GasPriceTicker: 1, InTxTicker: 1, @@ -46,118 +73,121 @@ func (s *UpdateCoreParamsSuite) SetupTest() { ChainId: 18332, OutboundTxScheduleInterval: 1, OutboundTxScheduleLookahead: 1, + BallotThreshold: types.DefaultBallotThreshold, + MinObserverDelegation: types.DefaultMinObserverDelegation, + IsSupported: false, } } -func (s *UpdateCoreParamsSuite) TestValidParams() { - err := ValidateCoreParams(s.evmParams) +func (s *UpdateChainParamsSuite) TestValidParams() { + err := types.ValidateChainParams(s.evmParams) require.Nil(s.T(), err) - err = ValidateCoreParams(s.btcParams) + err = types.ValidateChainParams(s.btcParams) require.Nil(s.T(), err) } -func (s *UpdateCoreParamsSuite) TestCommonParams() { +func (s *UpdateChainParamsSuite) TestCommonParams() { s.Validate(s.evmParams) s.Validate(s.btcParams) } -func (s *UpdateCoreParamsSuite) TestBTCParams() { +func (s *UpdateChainParamsSuite) TestBTCParams() { copy := *s.btcParams copy.WatchUtxoTicker = 0 - err := ValidateCoreParams(©) + err := types.ValidateChainParams(©) require.NotNil(s.T(), err) } -func (s *UpdateCoreParamsSuite) TestCoreContractAddresses() { +func (s *UpdateChainParamsSuite) TestCoreContractAddresses() { copy := *s.evmParams copy.ZetaTokenContractAddress = "0x123" - err := ValidateCoreParams(©) + err := types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *s.evmParams copy.ZetaTokenContractAddress = "733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9" - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *s.evmParams copy.ConnectorContractAddress = "0x123" - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *s.evmParams copy.ConnectorContractAddress = "733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9" - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *s.evmParams copy.Erc20CustodyContractAddress = "0x123" - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *s.evmParams copy.Erc20CustodyContractAddress = "733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9" - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) } -func (s *UpdateCoreParamsSuite) Validate(params *CoreParams) { +func (s *UpdateChainParamsSuite) Validate(params *types.ChainParams) { copy := *params copy.ConfirmationCount = 0 - err := ValidateCoreParams(©) + err := types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *params copy.GasPriceTicker = 0 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy.GasPriceTicker = 300 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.Nil(s.T(), err) copy.GasPriceTicker = 301 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *params copy.InTxTicker = 0 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy.InTxTicker = 300 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.Nil(s.T(), err) copy.InTxTicker = 301 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *params copy.OutTxTicker = 0 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy.OutTxTicker = 300 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.Nil(s.T(), err) copy.OutTxTicker = 301 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *params copy.OutboundTxScheduleInterval = 0 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy.OutboundTxScheduleInterval = 100 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.Nil(s.T(), err) copy.OutboundTxScheduleInterval = 101 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy = *params copy.OutboundTxScheduleLookahead = 0 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) copy.OutboundTxScheduleLookahead = 500 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.Nil(s.T(), err) copy.OutboundTxScheduleLookahead = 501 - err = ValidateCoreParams(©) + err = types.ValidateChainParams(©) require.NotNil(s.T(), err) } diff --git a/x/observer/types/codec.go b/x/observer/types/codec.go index c6add9ed17..b28c4d0041 100644 --- a/x/observer/types/codec.go +++ b/x/observer/types/codec.go @@ -9,7 +9,8 @@ import ( func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgAddObserver{}, "observer/AddObserver", nil) - cdc.RegisterConcrete(&MsgUpdateCoreParams{}, "observer/UpdateCoreParam", nil) + cdc.RegisterConcrete(&MsgUpdateChainParams{}, "observer/UpdateChainParams", nil) + cdc.RegisterConcrete(&MsgRemoveChainParams{}, "observer/RemoveChainParams", nil) cdc.RegisterConcrete(&MsgAddBlameVote{}, "crosschain/AddBlameVote", nil) cdc.RegisterConcrete(&MsgUpdateCrosschainFlags{}, "crosschain/UpdateCrosschainFlags", nil) cdc.RegisterConcrete(&MsgUpdateKeygen{}, "crosschain/UpdateKeygen", nil) @@ -20,7 +21,8 @@ func RegisterCodec(cdc *codec.LegacyAmino) { func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { registry.RegisterImplementations((*sdk.Msg)(nil), &MsgAddObserver{}, - &MsgUpdateCoreParams{}, + &MsgUpdateChainParams{}, + &MsgRemoveChainParams{}, &MsgAddBlameVote{}, &MsgUpdateCrosschainFlags{}, &MsgUpdateKeygen{}, diff --git a/x/observer/types/core_params.go b/x/observer/types/core_params.go deleted file mode 100644 index d40a2bb8c5..0000000000 --- a/x/observer/types/core_params.go +++ /dev/null @@ -1,156 +0,0 @@ -package types - -import ( - "fmt" - - "github.com/zeta-chain/zetacore/common" -) - -// GetCoreParams returns a list of default core params -func GetCoreParams() CoreParamsList { - return CoreParamsList{ - CoreParams: []*CoreParams{ - { - ChainId: common.EthChain().ChainId, - ConfirmationCount: 14, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 12, - OutTxTicker: 15, - WatchUtxoTicker: 0, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.BscMainnetChain().ChainId, - ConfirmationCount: 14, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 5, - OutTxTicker: 15, - WatchUtxoTicker: 0, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.BtcMainnetChain().ChainId, - ConfirmationCount: 2, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - WatchUtxoTicker: 30, - InTxTicker: 120, - OutTxTicker: 60, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.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", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 12, - OutTxTicker: 15, - WatchUtxoTicker: 0, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.BscTestnetChain().ChainId, - ConfirmationCount: 6, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 5, - OutTxTicker: 15, - WatchUtxoTicker: 0, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.MumbaiChain().ChainId, - ConfirmationCount: 12, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - InTxTicker: 2, - OutTxTicker: 15, - WatchUtxoTicker: 0, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 60, - }, - { - ChainId: common.BtcTestNetChain().ChainId, - ConfirmationCount: 2, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - WatchUtxoTicker: 30, - InTxTicker: 120, - OutTxTicker: 12, - GasPriceTicker: 30, - OutboundTxScheduleInterval: 30, - OutboundTxScheduleLookahead: 100, - }, - { - ChainId: common.BtcRegtestChain().ChainId, - ConfirmationCount: 1, - ZetaTokenContractAddress: "", - ConnectorContractAddress: "", - Erc20CustodyContractAddress: "", - GasPriceTicker: 5, - WatchUtxoTicker: 2, - InTxTicker: 2, - OutTxTicker: 2, - OutboundTxScheduleInterval: 2, - OutboundTxScheduleLookahead: 5, - }, - { - ChainId: common.GoerliLocalnetChain().ChainId, - ConfirmationCount: 1, - ZetaTokenContractAddress: "0x733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9", - ConnectorContractAddress: "0xD28D6A0b8189305551a0A8bd247a6ECa9CE781Ca", - Erc20CustodyContractAddress: "0xff3135df4F2775f4091b81f4c7B6359CfA07862a", - InTxTicker: 2, - OutTxTicker: 2, - WatchUtxoTicker: 0, - GasPriceTicker: 5, - OutboundTxScheduleInterval: 2, - OutboundTxScheduleLookahead: 5, - }, - }, - } -} - -// Validate checks all core params correspond to a chain and there is no duplicate chain id -func (cpl CoreParamsList) Validate() error { - // check all core params correspond to a chain - externalChainMap := make(map[int64]struct{}) - existingChainMap := make(map[int64]struct{}) - - externalChainList := common.ExternalChainList() - for _, chain := range externalChainList { - externalChainMap[chain.ChainId] = struct{}{} - } - - for _, param := range cpl.CoreParams { - if _, ok := externalChainMap[param.ChainId]; !ok { - return fmt.Errorf("chain id %d not found in chain list", param.ChainId) - } - if _, ok := existingChainMap[param.ChainId]; ok { - return fmt.Errorf("duplicated chain id %d found", param.ChainId) - } - existingChainMap[param.ChainId] = struct{}{} - } - return nil -} diff --git a/x/observer/types/core_params_test.go b/x/observer/types/core_params_test.go deleted file mode 100644 index 273e96d00c..0000000000 --- a/x/observer/types/core_params_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func TestCoreParamsList_Validate(t *testing.T) { - t.Run("should return no error for default list", func(t *testing.T) { - list := types.GetCoreParams() - err := list.Validate() - require.NoError(t, err) - }) - - t.Run("should return error for invalid chain id", func(t *testing.T) { - list := types.GetCoreParams() - list.CoreParams[0].ChainId = 999 - err := list.Validate() - require.Error(t, err) - require.Contains(t, err.Error(), "not found in chain list") - }) - - t.Run("should return error for duplicated chain ID", func(t *testing.T) { - list := types.GetCoreParams() - list.CoreParams = append(list.CoreParams, list.CoreParams[0]) - err := list.Validate() - require.Error(t, err) - require.Contains(t, err.Error(), "duplicated chain id") - }) -} diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index ca6f6fb10a..8918b08e7f 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -19,14 +19,11 @@ var ( ErrSelfDelegation = errorsmod.Register(ModuleName, 1109, "self Delegation for operator not found") ErrCheckObserverDelegation = errorsmod.Register(ModuleName, 1110, "observer delegation not sufficient") ErrNotAuthorizedPolicy = errorsmod.Register(ModuleName, 1111, "msg Sender is not the authorized policy") - ErrCoreParamsNotSet = errorsmod.Register(ModuleName, 1112, "core params has not been set") ErrKeygenNotFound = errorsmod.Register(ModuleName, 1113, "Keygen not found, Keygen block can only be updated,New keygen cannot be set") ErrKeygenBlockTooLow = errorsmod.Register(ModuleName, 1114, "please set a block number at-least 10 blocks higher than the current block number") ErrKeygenCompleted = errorsmod.Register(ModuleName, 1115, "keygen already completed") ErrNotAuthorized = errorsmod.Register(ModuleName, 1116, "not authorized") - ErrBlockHeaderNotFound = errorsmod.Register(ModuleName, 1117, "block header not found") - ErrUnrecognizedBlockHeader = errorsmod.Register(ModuleName, 1118, "unrecognized block header") ErrBlockAlreadyExist = errorsmod.Register(ModuleName, 1119, "block already exists") ErrNoParentHash = errorsmod.Register(ModuleName, 1120, "no parent hash") ErrInvalidTimestamp = errorsmod.Register(ModuleName, 1121, "invalid timestamp") @@ -34,6 +31,9 @@ var ( ErrLastObserverCountNotFound = errorsmod.Register(ModuleName, 1123, "last observer count not found") ErrUpdateObserver = errorsmod.Register(ModuleName, 1124, "unable to update observer") ErrNodeAccountNotFound = errorsmod.Register(ModuleName, 1125, "node account not found") - ErrMinDelegationNotFound = errorsmod.Register(ModuleName, 1126, "min delegation not found") - ErrObserverSetNotFound = errorsmod.Register(ModuleName, 1127, "observer set not found") + ErrInvalidChainParams = errorsmod.Register(ModuleName, 1126, "invalid chain params") + ErrChainParamsNotFound = errorsmod.Register(ModuleName, 1127, "chain params not found") + ErrParamsMinObserverDelegation = errorsmod.Register(ModuleName, 1128, "min observer delegation cannot be nil") + ErrMinDelegationNotFound = errorsmod.Register(ModuleName, 1129, "min delegation not found") + ErrObserverSetNotFound = errorsmod.Register(ModuleName, 1130, "observer set not found") ) diff --git a/x/observer/types/genesis.go b/x/observer/types/genesis.go index d41169671a..c20cd8ff04 100644 --- a/x/observer/types/genesis.go +++ b/x/observer/types/genesis.go @@ -40,8 +40,8 @@ func (gs GenesisState) Validate() error { nodeAccountIndexMap[elem.GetOperator()] = true } - // check for invalid core params - if err := gs.CoreParamsList.Validate(); err != nil { + // check for invalid chain params + if err := gs.ChainParamsList.Validate(); err != nil { return err } diff --git a/x/observer/types/genesis.pb.go b/x/observer/types/genesis.pb.go index 1dd109c840..0f81d44c6f 100644 --- a/x/observer/types/genesis.pb.go +++ b/x/observer/types/genesis.pb.go @@ -32,7 +32,7 @@ type GenesisState struct { Params *Params `protobuf:"bytes,5,opt,name=params,proto3" json:"params,omitempty"` Keygen *Keygen `protobuf:"bytes,6,opt,name=keygen,proto3" json:"keygen,omitempty"` LastObserverCount *LastObserverCount `protobuf:"bytes,7,opt,name=last_observer_count,json=lastObserverCount,proto3" json:"last_observer_count,omitempty"` - CoreParamsList CoreParamsList `protobuf:"bytes,8,opt,name=core_params_list,json=coreParamsList,proto3" json:"core_params_list"` + ChainParamsList ChainParamsList `protobuf:"bytes,8,opt,name=chain_params_list,json=chainParamsList,proto3" json:"chain_params_list"` Tss *TSS `protobuf:"bytes,9,opt,name=tss,proto3" json:"tss,omitempty"` TssHistory []TSS `protobuf:"bytes,10,rep,name=tss_history,json=tssHistory,proto3" json:"tss_history"` TssFundMigrators []TssFundMigratorInfo `protobuf:"bytes,11,rep,name=tss_fund_migrators,json=tssFundMigrators,proto3" json:"tss_fund_migrators"` @@ -124,11 +124,11 @@ func (m *GenesisState) GetLastObserverCount() *LastObserverCount { return nil } -func (m *GenesisState) GetCoreParamsList() CoreParamsList { +func (m *GenesisState) GetChainParamsList() ChainParamsList { if m != nil { - return m.CoreParamsList + return m.ChainParamsList } - return CoreParamsList{} + return ChainParamsList{} } func (m *GenesisState) GetTss() *TSS { @@ -187,48 +187,47 @@ func init() { func init() { proto.RegisterFile("observer/genesis.proto", fileDescriptor_15ea8c9d44da7399) } var fileDescriptor_15ea8c9d44da7399 = []byte{ - // 641 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xcb, 0x6e, 0xd3, 0x4c, - 0x14, 0x4e, 0xfe, 0xf6, 0x6f, 0xe9, 0xa4, 0x37, 0x86, 0x02, 0xa3, 0x16, 0xdc, 0x52, 0x36, 0x15, - 0x17, 0x1b, 0x95, 0x25, 0x62, 0x41, 0x23, 0xb5, 0x54, 0x94, 0x02, 0x4e, 0x25, 0x24, 0x90, 0xb0, - 0x26, 0x93, 0xa9, 0x6b, 0xe1, 0xcc, 0x44, 0x9e, 0x09, 0x6a, 0x78, 0x0a, 0xde, 0x83, 0x17, 0xe9, - 0xb2, 0x4b, 0x56, 0x08, 0x25, 0x2f, 0x82, 0xe6, 0x66, 0xc7, 0x89, 0x64, 0xb2, 0x1b, 0x7d, 0xe7, - 0x7c, 0xdf, 0x39, 0x73, 0x6e, 0xe0, 0x0e, 0x6f, 0x0b, 0x9a, 0x7d, 0xa3, 0x59, 0x10, 0x53, 0x46, - 0x45, 0x22, 0xfc, 0x5e, 0xc6, 0x25, 0x87, 0x5b, 0xdf, 0xa9, 0xc4, 0xe4, 0x02, 0x27, 0xcc, 0xd7, - 0x2f, 0x9e, 0x51, 0xdf, 0xb9, 0x6e, 0x6e, 0xc4, 0x3c, 0xe6, 0xda, 0x2f, 0x50, 0x2f, 0x43, 0xd9, - 0xbc, 0x9d, 0x4b, 0xb5, 0x71, 0x9a, 0x72, 0x69, 0xe1, 0x8d, 0x02, 0x4e, 0x71, 0x97, 0x5a, 0x74, - 0x2b, 0x47, 0x75, 0x90, 0x88, 0x71, 0x46, 0xa8, 0x0d, 0xbe, 0xb9, 0x5d, 0x18, 0x33, 0x2e, 0x84, - 0xf1, 0x38, 0x4f, 0x71, 0x2c, 0xa6, 0x42, 0x7d, 0xa5, 0x83, 0x98, 0xb2, 0x29, 0x51, 0xc6, 0x3b, - 0x34, 0xc2, 0x84, 0xf0, 0x3e, 0x73, 0x79, 0xdc, 0x1b, 0x33, 0x32, 0x42, 0x23, 0xc9, 0x23, 0x42, - 0xe4, 0xa5, 0xb5, 0xde, 0xcd, 0xad, 0xee, 0x31, 0x15, 0xaa, 0x87, 0x33, 0xdc, 0x75, 0x19, 0xdc, - 0x2f, 0x60, 0xca, 0x3a, 0x09, 0x8b, 0xcb, 0x3f, 0x80, 0xb9, 0x59, 0x0a, 0x87, 0x3d, 0x18, 0xc7, - 0xa2, 0xf3, 0x3e, 0xeb, 0x88, 0xa8, 0x9b, 0xc4, 0x19, 0x96, 0xdc, 0x06, 0xdb, 0xfd, 0xb9, 0x04, - 0x96, 0x8f, 0x4c, 0x1f, 0x5a, 0x12, 0x4b, 0x0a, 0x5f, 0x82, 0x45, 0x53, 0x4c, 0x81, 0xea, 0x3b, - 0x73, 0x7b, 0x8d, 0xfd, 0x87, 0x7e, 0x45, 0x63, 0xfc, 0x03, 0xed, 0x1b, 0x3a, 0x0e, 0x3c, 0x01, - 0x4b, 0xce, 0x26, 0xd0, 0x7f, 0x3b, 0xf5, 0xbd, 0xc6, 0xfe, 0x5e, 0xa5, 0xc0, 0x3b, 0xfb, 0x68, - 0x51, 0x79, 0x30, 0x7f, 0xf5, 0x7b, 0xbb, 0x16, 0x16, 0x02, 0x30, 0x04, 0x6b, 0xaa, 0xae, 0xaf, - 0x4c, 0x59, 0x4f, 0x12, 0x21, 0xd1, 0x9c, 0x4e, 0xaa, 0x5a, 0xf3, 0xb4, 0xe0, 0x84, 0x93, 0x02, - 0xf0, 0x23, 0x58, 0x9f, 0xec, 0x31, 0x9a, 0xd7, 0x89, 0x3e, 0xa9, 0x14, 0x6d, 0xe6, 0xa4, 0x43, - 0xc5, 0x09, 0xd7, 0x48, 0x19, 0x80, 0x2f, 0xc0, 0x82, 0x69, 0x18, 0xfa, 0x5f, 0xcb, 0x55, 0x17, - 0xee, 0xbd, 0x76, 0x0d, 0x2d, 0x45, 0x91, 0xcd, 0x60, 0xa1, 0x85, 0x19, 0xc8, 0x6f, 0xb4, 0x6b, - 0x68, 0x29, 0xf0, 0x0b, 0xb8, 0x95, 0x62, 0x21, 0x23, 0x67, 0x8f, 0xf4, 0x6f, 0xd1, 0xa2, 0x56, - 0xf2, 0x2b, 0x95, 0x4e, 0xb0, 0x90, 0xae, 0x05, 0x4d, 0x5d, 0xb0, 0x9b, 0xe9, 0x24, 0x04, 0x3f, - 0x83, 0x75, 0xc5, 0x8a, 0x4c, 0xae, 0x51, 0xaa, 0xfa, 0x70, 0x43, 0x8b, 0x3f, 0xae, 0x2e, 0x19, - 0xcf, 0xa8, 0xf9, 0xa7, 0xaa, 0xbc, 0x6d, 0xef, 0x2a, 0x29, 0xa1, 0x70, 0x1f, 0xcc, 0x49, 0x21, - 0xd0, 0x92, 0xd6, 0xdb, 0xa9, 0xd4, 0x3b, 0x6b, 0xb5, 0x42, 0xe5, 0x0c, 0x8f, 0x40, 0x43, 0x4d, - 0xf4, 0x45, 0x22, 0x24, 0xcf, 0x06, 0x08, 0xe8, 0x99, 0xf8, 0x27, 0xd7, 0x26, 0x00, 0xa4, 0x10, - 0xaf, 0x0d, 0x13, 0x76, 0x00, 0x74, 0xab, 0x91, 0x6f, 0x86, 0x40, 0x0d, 0xad, 0xf7, 0xac, 0x5a, - 0x4f, 0x88, 0xc3, 0x3e, 0xeb, 0xbc, 0xb5, 0xa4, 0x63, 0x76, 0xce, 0xad, 0xfe, 0xba, 0x2c, 0x9b, - 0x54, 0xba, 0x40, 0x5f, 0x22, 0x53, 0xb9, 0x65, 0xad, 0xbe, 0x5b, 0xbd, 0x56, 0xca, 0xdd, 0xed, - 0x83, 0xe6, 0xda, 0xd9, 0x5d, 0x2d, 0x2f, 0x3f, 0x5a, 0xd1, 0x62, 0x8f, 0xaa, 0x47, 0xcd, 0x50, - 0x4e, 0x35, 0xc3, 0x8a, 0xae, 0xf4, 0xc6, 0x41, 0xf8, 0x01, 0x2c, 0x8f, 0x5f, 0x45, 0xb4, 0x3a, - 0xc3, 0x96, 0x35, 0x15, 0x5e, 0x12, 0x6d, 0x90, 0x02, 0x82, 0x21, 0x58, 0x29, 0x9d, 0x3d, 0xb4, - 0x36, 0xd3, 0xe6, 0x32, 0x42, 0xcf, 0x78, 0x93, 0xc8, 0x4b, 0xa7, 0xc9, 0xc6, 0xa0, 0xe3, 0xab, - 0xa1, 0x57, 0xbf, 0x1e, 0x7a, 0xf5, 0x3f, 0x43, 0xaf, 0xfe, 0x63, 0xe4, 0xd5, 0xae, 0x47, 0x5e, - 0xed, 0xd7, 0xc8, 0xab, 0x7d, 0x0a, 0xe2, 0x44, 0x5e, 0xf4, 0xdb, 0x3e, 0xe1, 0xdd, 0x40, 0xc9, - 0x3e, 0xd5, 0x11, 0x02, 0x17, 0x21, 0xb8, 0x0c, 0x8a, 0x5b, 0x38, 0xe8, 0x51, 0xd1, 0x5e, 0xd0, - 0xf7, 0xef, 0xf9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x39, 0x18, 0xe6, 0x8f, 0x06, 0x00, - 0x00, + // 637 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xdf, 0x4e, 0x13, 0x4f, + 0x14, 0x6e, 0x7f, 0xf0, 0x03, 0x99, 0x02, 0x85, 0x11, 0x75, 0x02, 0xba, 0x20, 0xde, 0x10, 0xa3, + 0xbb, 0x06, 0x2f, 0x8d, 0x17, 0x42, 0x02, 0x12, 0x11, 0x75, 0x4b, 0x62, 0xe2, 0x05, 0x9b, 0xe9, + 0x74, 0x58, 0x36, 0x6e, 0x67, 0x9a, 0x9d, 0xa9, 0xa1, 0x3e, 0x85, 0x4f, 0xe2, 0x73, 0x70, 0xc9, + 0xa5, 0x57, 0xc6, 0xb4, 0x2f, 0x62, 0xe6, 0xdf, 0x6e, 0xb7, 0x4d, 0xd6, 0xde, 0x4d, 0xbe, 0x73, + 0xbe, 0xef, 0x9c, 0x39, 0xff, 0xc0, 0x7d, 0xde, 0x16, 0x34, 0xfb, 0x46, 0xb3, 0x20, 0xa6, 0x8c, + 0x8a, 0x44, 0xf8, 0xbd, 0x8c, 0x4b, 0x0e, 0xb7, 0xbe, 0x53, 0x89, 0xc9, 0x15, 0x4e, 0x98, 0xaf, + 0x5f, 0x3c, 0xa3, 0xbe, 0x73, 0xdd, 0xdc, 0x88, 0x79, 0xcc, 0xb5, 0x5f, 0xa0, 0x5e, 0x86, 0xb2, + 0x79, 0x2f, 0x97, 0x6a, 0xe3, 0x34, 0xe5, 0xd2, 0xc2, 0x1b, 0x05, 0x9c, 0xe2, 0x2e, 0xb5, 0xe8, + 0x56, 0x8e, 0xea, 0x20, 0x11, 0xe3, 0x8c, 0x50, 0x1b, 0x7c, 0x73, 0xbb, 0x30, 0x66, 0x5c, 0x08, + 0xe3, 0x71, 0x99, 0xe2, 0x58, 0x4c, 0x85, 0xfa, 0x4a, 0x07, 0x31, 0x65, 0x53, 0xa2, 0x8c, 0x77, + 0x68, 0x84, 0x09, 0xe1, 0x7d, 0xe6, 0xf2, 0x78, 0x38, 0x66, 0x64, 0x84, 0x46, 0x92, 0x47, 0x84, + 0xc8, 0x6b, 0x6b, 0x7d, 0x90, 0x5b, 0xdd, 0x63, 0x2a, 0x54, 0x0f, 0x67, 0xb8, 0xeb, 0x32, 0x78, + 0x54, 0xc0, 0x94, 0x75, 0x12, 0x16, 0x97, 0x7f, 0x00, 0x73, 0xb3, 0x14, 0x0e, 0x7b, 0x3c, 0x8e, + 0x45, 0x97, 0x7d, 0xd6, 0x11, 0x51, 0x37, 0x89, 0x33, 0x2c, 0xb9, 0x0d, 0xb6, 0xfb, 0x73, 0x09, + 0x2c, 0x1f, 0x9b, 0x3e, 0xb4, 0x24, 0x96, 0x14, 0xbe, 0x06, 0x8b, 0xa6, 0x98, 0x02, 0xd5, 0x77, + 0xe6, 0xf6, 0x1a, 0xfb, 0x4f, 0xfc, 0x8a, 0xc6, 0xf8, 0x07, 0xda, 0x37, 0x74, 0x1c, 0x78, 0x0a, + 0x96, 0x9c, 0x4d, 0xa0, 0xff, 0x76, 0xea, 0x7b, 0x8d, 0xfd, 0xbd, 0x4a, 0x81, 0x0f, 0xf6, 0xd1, + 0xa2, 0xf2, 0x60, 0xfe, 0xe6, 0xf7, 0x76, 0x2d, 0x2c, 0x04, 0x60, 0x08, 0x9a, 0xaa, 0xae, 0x6f, + 0x4c, 0x59, 0x4f, 0x13, 0x21, 0xd1, 0x9c, 0x4e, 0xaa, 0x5a, 0xf3, 0xac, 0xe0, 0x84, 0x93, 0x02, + 0xf0, 0x33, 0x58, 0x9b, 0xec, 0x31, 0x9a, 0xd7, 0x89, 0x3e, 0xab, 0x14, 0x3d, 0xcc, 0x49, 0x47, + 0x8a, 0x13, 0x36, 0x49, 0x19, 0x80, 0xaf, 0xc0, 0x82, 0x69, 0x18, 0xfa, 0x5f, 0xcb, 0x55, 0x17, + 0xee, 0xa3, 0x76, 0x0d, 0x2d, 0x45, 0x91, 0xcd, 0x60, 0xa1, 0x85, 0x19, 0xc8, 0xef, 0xb4, 0x6b, + 0x68, 0x29, 0xf0, 0x02, 0xdc, 0x4d, 0xb1, 0x90, 0x91, 0xb3, 0x47, 0xfa, 0xb7, 0x68, 0x51, 0x2b, + 0xf9, 0x95, 0x4a, 0xa7, 0x58, 0x48, 0xd7, 0x82, 0x43, 0x5d, 0xb0, 0xf5, 0x74, 0x12, 0x82, 0x17, + 0x60, 0xdd, 0x54, 0xcb, 0x24, 0x1b, 0xa5, 0xaa, 0x11, 0x77, 0x66, 0xa9, 0x99, 0xc2, 0xcd, 0x4f, + 0x55, 0xed, 0x6d, 0x83, 0x9b, 0xa4, 0x0c, 0xc3, 0x7d, 0x30, 0x27, 0x85, 0x40, 0x4b, 0x5a, 0x71, + 0xa7, 0x52, 0xf1, 0xbc, 0xd5, 0x0a, 0x95, 0x33, 0x3c, 0x06, 0x0d, 0x35, 0xd4, 0x57, 0x89, 0x90, + 0x3c, 0x1b, 0x20, 0xa0, 0xc7, 0xe2, 0x9f, 0x5c, 0x9b, 0x01, 0x90, 0x42, 0xbc, 0x35, 0x4c, 0xd8, + 0x01, 0xd0, 0x6d, 0x47, 0xbe, 0x1c, 0x02, 0x35, 0xb4, 0xde, 0x8b, 0x6a, 0x3d, 0x21, 0x8e, 0xfa, + 0xac, 0xf3, 0xde, 0x92, 0x4e, 0xd8, 0x25, 0xb7, 0xfa, 0x6b, 0xb2, 0x6c, 0x52, 0xe9, 0x02, 0x7d, + 0x8c, 0x4c, 0xed, 0x96, 0xb5, 0xfa, 0x6e, 0xf5, 0x66, 0x29, 0x77, 0xb7, 0x12, 0x9a, 0x6b, 0xc7, + 0x77, 0xb5, 0xbc, 0xff, 0x68, 0x45, 0x8b, 0x3d, 0xad, 0x9e, 0x36, 0x43, 0x39, 0xd3, 0x0c, 0x2b, + 0xba, 0xd2, 0x1b, 0x07, 0xe1, 0x27, 0xb0, 0x3c, 0x7e, 0x18, 0xd1, 0xea, 0x0c, 0x8b, 0xa6, 0xfb, + 0x5b, 0x12, 0x6d, 0x90, 0x02, 0x82, 0x21, 0x58, 0x29, 0x5d, 0x3e, 0xd4, 0x9c, 0x69, 0x79, 0x19, + 0xa1, 0xe7, 0xfc, 0x90, 0xc8, 0x6b, 0xa7, 0xc9, 0xc6, 0xa0, 0x93, 0x9b, 0xa1, 0x57, 0xbf, 0x1d, + 0x7a, 0xf5, 0x3f, 0x43, 0xaf, 0xfe, 0x63, 0xe4, 0xd5, 0x6e, 0x47, 0x5e, 0xed, 0xd7, 0xc8, 0xab, + 0x7d, 0x09, 0xe2, 0x44, 0x5e, 0xf5, 0xdb, 0x3e, 0xe1, 0xdd, 0x40, 0xc9, 0x3e, 0xd7, 0x11, 0x02, + 0x17, 0x21, 0xb8, 0x0e, 0x8a, 0x73, 0x38, 0xe8, 0x51, 0xd1, 0x5e, 0xd0, 0x27, 0xf0, 0xe5, 0xdf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0x5e, 0x89, 0xea, 0x92, 0x06, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -348,7 +347,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x4a } { - size, err := m.CoreParamsList.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ChainParamsList.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -493,7 +492,7 @@ func (m *GenesisState) Size() (n int) { l = m.LastObserverCount.Size() n += 1 + l + sovGenesis(uint64(l)) } - l = m.CoreParamsList.Size() + l = m.ChainParamsList.Size() n += 1 + l + sovGenesis(uint64(l)) if m.Tss != nil { l = m.Tss.Size() @@ -820,7 +819,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParamsList", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainParamsList", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -847,7 +846,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.CoreParamsList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ChainParamsList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/observer/types/genesis_test.go b/x/observer/types/genesis_test.go index 91047ccfd1..1ba8212a35 100644 --- a/x/observer/types/genesis_test.go +++ b/x/observer/types/genesis_test.go @@ -8,9 +8,9 @@ import ( ) func TestGenesisState_Validate(t *testing.T) { - invalidCoreParamsGen := types.DefaultGenesis() - coreParams := types.GetCoreParams().CoreParams - invalidCoreParamsGen.CoreParamsList.CoreParams = append(coreParams, coreParams[0]) + invalidChainParamsGen := types.DefaultGenesis() + chainParams := types.GetDefaultChainParams().ChainParams + invalidChainParamsGen.ChainParamsList.ChainParams = append(chainParams, chainParams[0]) for _, tc := range []struct { desc string @@ -28,8 +28,8 @@ func TestGenesisState_Validate(t *testing.T) { valid: true, }, { - desc: "invalid core params", - genState: invalidCoreParamsGen, + desc: "invalid chain params", + genState: invalidChainParamsGen, valid: false, }, } { @@ -42,7 +42,4 @@ func TestGenesisState_Validate(t *testing.T) { } }) } - - list := types.GetCoreParams() - list.CoreParams = append(list.CoreParams, list.CoreParams[0]) } diff --git a/x/observer/types/keys.go b/x/observer/types/keys.go index fe7669b57a..6c7b45b2c7 100644 --- a/x/observer/types/keys.go +++ b/x/observer/types/keys.go @@ -48,10 +48,13 @@ func BallotListKeyPrefix(p int64) []byte { const ( BlameKey = "Blame-" // TODO change identifier for VoterKey to something more descriptive - VoterKey = "Voter-value-" - AllCoreParams = "CoreParams" - ObserverMapperKey = "Observer-value-" + VoterKey = "Voter-value-" + // AllChainParamsKey is the ke prefix for all chain params + // NOTE: CoreParams is old name for AllChainParams we keep it as key value for backward compatibility + AllChainParamsKey = "CoreParams" + + ObserverMapperKey = "Observer-value-" ObserverSetKey = "ObserverSet-value-" ObserverParamsKey = "ObserverParams" AdminPolicyParamsKey = "AdminParams" diff --git a/x/observer/types/message_remove_chain_params.go b/x/observer/types/message_remove_chain_params.go new file mode 100644 index 0000000000..dbf4484263 --- /dev/null +++ b/x/observer/types/message_remove_chain_params.go @@ -0,0 +1,56 @@ +package types + +import ( + cosmoserrors "cosmossdk.io/errors" + "github.com/zeta-chain/zetacore/common" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgRemoveChainParams = "remove_chain_params" + +var _ sdk.Msg = &MsgRemoveChainParams{} + +func NewMsgRemoveChainParams(creator string, chainID int64) *MsgRemoveChainParams { + return &MsgRemoveChainParams{ + Creator: creator, + ChainId: chainID, + } +} + +func (msg *MsgRemoveChainParams) Route() string { + return RouterKey +} + +func (msg *MsgRemoveChainParams) Type() string { + return TypeMsgRemoveChainParams +} + +func (msg *MsgRemoveChainParams) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgRemoveChainParams) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgRemoveChainParams) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + // Check if chain exists + chain := common.GetChainFromChainID(msg.ChainId) + if chain == nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidChainID, "invalid chain id (%d)", msg.ChainId) + } + + return nil +} diff --git a/x/observer/types/message_remove_chain_params_test.go b/x/observer/types/message_remove_chain_params_test.go new file mode 100644 index 0000000000..10d5a4c777 --- /dev/null +++ b/x/observer/types/message_remove_chain_params_test.go @@ -0,0 +1,54 @@ +package types_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgRemoveChainParams_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg types.MsgRemoveChainParams + err error + }{ + { + name: "valid message", + msg: types.MsgRemoveChainParams{ + Creator: sample.AccAddress(), + ChainId: common.ExternalChainList()[0].ChainId, + }, + }, + { + name: "invalid address", + msg: types.MsgRemoveChainParams{ + Creator: "invalid_address", + ChainId: common.ExternalChainList()[0].ChainId, + }, + err: sdkerrors.ErrInvalidAddress, + }, + + { + name: "invalid chain ID", + msg: types.MsgRemoveChainParams{ + Creator: sample.AccAddress(), + ChainId: 999, + }, + err: sdkerrors.ErrInvalidChainID, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + }) + } +} diff --git a/x/observer/types/message_update_chain_params.go b/x/observer/types/message_update_chain_params.go new file mode 100644 index 0000000000..7682a684f3 --- /dev/null +++ b/x/observer/types/message_update_chain_params.go @@ -0,0 +1,53 @@ +package types + +import ( + cosmoserrors "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgUpdateChainParams = "update_chain_params" + +var _ sdk.Msg = &MsgUpdateChainParams{} + +func NewMsgUpdateChainParams(creator string, chainParams *ChainParams) *MsgUpdateChainParams { + return &MsgUpdateChainParams{ + Creator: creator, + ChainParams: chainParams, + } +} + +func (msg *MsgUpdateChainParams) Route() string { + return RouterKey +} + +func (msg *MsgUpdateChainParams) Type() string { + return TypeMsgUpdateChainParams +} + +func (msg *MsgUpdateChainParams) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUpdateChainParams) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUpdateChainParams) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + if err := ValidateChainParams(msg.ChainParams); err != nil { + return cosmoserrors.Wrapf(ErrInvalidChainParams, err.Error()) + } + + return nil +} diff --git a/x/observer/types/message_update_chain_params_test.go b/x/observer/types/message_update_chain_params_test.go new file mode 100644 index 0000000000..3f3efc4e2f --- /dev/null +++ b/x/observer/types/message_update_chain_params_test.go @@ -0,0 +1,53 @@ +package types_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgUpdateChainParams_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg types.MsgUpdateChainParams + err error + }{ + { + name: "valid message", + msg: types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }, + }, + { + name: "invalid address", + msg: types.MsgUpdateChainParams{ + Creator: "invalid_address", + ChainParams: sample.ChainParams(common.ExternalChainList()[0].ChainId), + }, + err: sdkerrors.ErrInvalidAddress, + }, + + { + name: "invalid chain params (nil)", + msg: types.MsgUpdateChainParams{ + Creator: sample.AccAddress(), + }, + err: types.ErrInvalidChainParams, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + }) + } +} diff --git a/x/observer/types/message_update_core_params.go b/x/observer/types/message_update_core_params.go deleted file mode 100644 index b4f7828379..0000000000 --- a/x/observer/types/message_update_core_params.go +++ /dev/null @@ -1,112 +0,0 @@ -package types - -import ( - "fmt" - "strings" - - errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/zeta-chain/zetacore/common" -) - -const TypeMsgUpdateClientParams = "update_client_params" - -var _ sdk.Msg = &MsgUpdateCoreParams{} - -func NewMsgUpdateCoreParams(creator string, coreParams *CoreParams) *MsgUpdateCoreParams { - return &MsgUpdateCoreParams{ - Creator: creator, - CoreParams: coreParams, - } -} - -func (msg *MsgUpdateCoreParams) Route() string { - return RouterKey -} - -func (msg *MsgUpdateCoreParams) Type() string { - return TypeMsgUpdateClientParams -} - -func (msg *MsgUpdateCoreParams) GetSigners() []sdk.AccAddress { - creator, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - panic(err) - } - return []sdk.AccAddress{creator} -} - -func (msg *MsgUpdateCoreParams) GetSignBytes() []byte { - bz := ModuleCdc.MustMarshalJSON(msg) - return sdk.MustSortJSON(bz) -} - -func (msg *MsgUpdateCoreParams) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) - } - return ValidateCoreParams(msg.CoreParams) -} - -// ValidateCoreParams performs some basic checks on core params -func ValidateCoreParams(params *CoreParams) error { - if params == nil { - return fmt.Errorf("core params cannot be nil") - } - chain := common.GetChainFromChainID(params.ChainId) - if chain == nil { - return fmt.Errorf("ChainId %d not supported", params.ChainId) - } - // zeta chain skips the rest of the checks for now - if chain.IsZetaChain() { - return nil - } - - if params.ConfirmationCount == 0 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "ConfirmationCount must be greater than 0") - } - if params.GasPriceTicker <= 0 || params.GasPriceTicker > 300 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "GasPriceTicker %d out of range", params.GasPriceTicker) - } - if params.InTxTicker <= 0 || params.InTxTicker > 300 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "InTxTicker %d out of range", params.InTxTicker) - } - if params.OutTxTicker <= 0 || params.OutTxTicker > 300 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutTxTicker %d out of range", params.OutTxTicker) - } - if params.OutboundTxScheduleInterval == 0 || params.OutboundTxScheduleInterval > 100 { // 600 secs - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutboundTxScheduleInterval %d out of range", params.OutboundTxScheduleInterval) - } - if params.OutboundTxScheduleLookahead == 0 || params.OutboundTxScheduleLookahead > 500 { // 500 cctxs - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "OutboundTxScheduleLookahead %d out of range", params.OutboundTxScheduleLookahead) - } - - // chain type specific checks - if common.IsBitcoinChain(params.ChainId) { - if params.WatchUtxoTicker == 0 || params.WatchUtxoTicker > 300 { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "WatchUtxoTicker %d out of range", params.WatchUtxoTicker) - } - } - if common.IsEVMChain(params.ChainId) { - if !validCoreContractAddress(params.ZetaTokenContractAddress) { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid ZetaTokenContractAddress %s", params.ZetaTokenContractAddress) - } - if !validCoreContractAddress(params.ConnectorContractAddress) { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid ConnectorContractAddress %s", params.ConnectorContractAddress) - } - if !validCoreContractAddress(params.Erc20CustodyContractAddress) { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid Erc20CustodyContractAddress %s", params.Erc20CustodyContractAddress) - } - } - return nil -} - -func validCoreContractAddress(address string) bool { - if !strings.HasPrefix(address, "0x") { - return false - } - return ethcommon.IsHexAddress(address) -} diff --git a/x/observer/types/params.go b/x/observer/types/params.go index 9b755af3cf..13910baa97 100644 --- a/x/observer/types/params.go +++ b/x/observer/types/params.go @@ -77,6 +77,7 @@ func (p Params) String() string { return string(out) } +// Deprecated: observer params are now stored in core params func validateVotingThresholds(i interface{}) error { v, ok := i.([]*ObserverParams) if !ok { @@ -114,68 +115,3 @@ func (p Params) GetAdminPolicyAccount(policyType Policy_Type) string { } return "" } -func (p Params) GetParamsForChain(chain *common.Chain) ObserverParams { - for _, ObserverParam := range p.GetObserverParams() { - if ObserverParam.Chain.IsEqual(*chain) { - return *ObserverParam - } - } - return ObserverParams{} -} - -func (p Params) GetParamsForChainID(chainID int64) ObserverParams { - for _, ObserverParam := range p.GetObserverParams() { - if ObserverParam.Chain.ChainId == chainID { - return *ObserverParam - } - } - return ObserverParams{} -} - -func (p Params) GetSupportedChains() (chains []*common.Chain) { - for _, observerParam := range p.GetObserverParams() { - if observerParam.IsSupported { - chains = append(chains, observerParam.Chain) - } - } - return -} - -func (p Params) GetChainFromChainID(chainID int64) *common.Chain { - chainList := p.GetObserverParams() - for _, observerParam := range chainList { - if observerParam.Chain.ChainId == chainID && observerParam.IsSupported { - return observerParam.Chain - } - } - return nil -} - -func (p Params) GetChainFromChainName(name common.ChainName) *common.Chain { - for _, observerParam := range p.GetObserverParams() { - if observerParam.Chain.ChainName == name && observerParam.IsSupported { - return observerParam.Chain - } - } - return nil -} - -func (p Params) IsChainSupported(checkChain common.Chain) bool { - chains := p.GetSupportedChains() - for _, chain := range chains { - if checkChain.IsEqual(*chain) { - return true - } - } - return false -} - -func (p Params) IsChainIDSupported(checkChainID int64) bool { - chains := p.GetSupportedChains() - for _, chain := range chains { - if chain.ChainId == checkChainID { - return true - } - } - return false -} diff --git a/x/observer/types/params.pb.go b/x/observer/types/params.pb.go index 609e56c5ca..066685bb22 100644 --- a/x/observer/types/params.pb.go +++ b/x/observer/types/params.pb.go @@ -51,22 +51,22 @@ func (Policy_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor_4542fa62877488a1, []int{0} } -type CoreParamsList struct { - CoreParams []*CoreParams `protobuf:"bytes,1,rep,name=core_params,json=coreParams,proto3" json:"core_params,omitempty"` +type ChainParamsList struct { + ChainParams []*ChainParams `protobuf:"bytes,1,rep,name=chain_params,json=chainParams,proto3" json:"chain_params,omitempty"` } -func (m *CoreParamsList) Reset() { *m = CoreParamsList{} } -func (m *CoreParamsList) String() string { return proto.CompactTextString(m) } -func (*CoreParamsList) ProtoMessage() {} -func (*CoreParamsList) Descriptor() ([]byte, []int) { +func (m *ChainParamsList) Reset() { *m = ChainParamsList{} } +func (m *ChainParamsList) String() string { return proto.CompactTextString(m) } +func (*ChainParamsList) ProtoMessage() {} +func (*ChainParamsList) Descriptor() ([]byte, []int) { return fileDescriptor_4542fa62877488a1, []int{0} } -func (m *CoreParamsList) XXX_Unmarshal(b []byte) error { +func (m *ChainParamsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *CoreParamsList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ChainParamsList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_CoreParamsList.Marshal(b, m, deterministic) + return xxx_messageInfo_ChainParamsList.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -76,51 +76,54 @@ func (m *CoreParamsList) XXX_Marshal(b []byte, deterministic bool) ([]byte, erro return b[:n], nil } } -func (m *CoreParamsList) XXX_Merge(src proto.Message) { - xxx_messageInfo_CoreParamsList.Merge(m, src) +func (m *ChainParamsList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainParamsList.Merge(m, src) } -func (m *CoreParamsList) XXX_Size() int { +func (m *ChainParamsList) XXX_Size() int { return m.Size() } -func (m *CoreParamsList) XXX_DiscardUnknown() { - xxx_messageInfo_CoreParamsList.DiscardUnknown(m) +func (m *ChainParamsList) XXX_DiscardUnknown() { + xxx_messageInfo_ChainParamsList.DiscardUnknown(m) } -var xxx_messageInfo_CoreParamsList proto.InternalMessageInfo +var xxx_messageInfo_ChainParamsList proto.InternalMessageInfo -func (m *CoreParamsList) GetCoreParams() []*CoreParams { +func (m *ChainParamsList) GetChainParams() []*ChainParams { if m != nil { - return m.CoreParams + return m.ChainParams } return nil } -type CoreParams struct { - ConfirmationCount uint64 `protobuf:"varint,1,opt,name=confirmation_count,json=confirmationCount,proto3" json:"confirmation_count,omitempty"` - GasPriceTicker uint64 `protobuf:"varint,2,opt,name=gas_price_ticker,json=gasPriceTicker,proto3" json:"gas_price_ticker,omitempty"` - InTxTicker uint64 `protobuf:"varint,3,opt,name=in_tx_ticker,json=inTxTicker,proto3" json:"in_tx_ticker,omitempty"` - OutTxTicker uint64 `protobuf:"varint,4,opt,name=out_tx_ticker,json=outTxTicker,proto3" json:"out_tx_ticker,omitempty"` - WatchUtxoTicker uint64 `protobuf:"varint,5,opt,name=watch_utxo_ticker,json=watchUtxoTicker,proto3" json:"watch_utxo_ticker,omitempty"` - ZetaTokenContractAddress string `protobuf:"bytes,8,opt,name=zeta_token_contract_address,json=zetaTokenContractAddress,proto3" json:"zeta_token_contract_address,omitempty"` - ConnectorContractAddress string `protobuf:"bytes,9,opt,name=connector_contract_address,json=connectorContractAddress,proto3" json:"connector_contract_address,omitempty"` - Erc20CustodyContractAddress string `protobuf:"bytes,10,opt,name=erc20_custody_contract_address,json=erc20CustodyContractAddress,proto3" json:"erc20_custody_contract_address,omitempty"` - ChainId int64 `protobuf:"varint,11,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - OutboundTxScheduleInterval int64 `protobuf:"varint,12,opt,name=outbound_tx_schedule_interval,json=outboundTxScheduleInterval,proto3" json:"outbound_tx_schedule_interval,omitempty"` - OutboundTxScheduleLookahead int64 `protobuf:"varint,13,opt,name=outbound_tx_schedule_lookahead,json=outboundTxScheduleLookahead,proto3" json:"outbound_tx_schedule_lookahead,omitempty"` -} - -func (m *CoreParams) Reset() { *m = CoreParams{} } -func (m *CoreParams) String() string { return proto.CompactTextString(m) } -func (*CoreParams) ProtoMessage() {} -func (*CoreParams) Descriptor() ([]byte, []int) { +type ChainParams struct { + ChainId int64 `protobuf:"varint,11,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + ConfirmationCount uint64 `protobuf:"varint,1,opt,name=confirmation_count,json=confirmationCount,proto3" json:"confirmation_count,omitempty"` + GasPriceTicker uint64 `protobuf:"varint,2,opt,name=gas_price_ticker,json=gasPriceTicker,proto3" json:"gas_price_ticker,omitempty"` + InTxTicker uint64 `protobuf:"varint,3,opt,name=in_tx_ticker,json=inTxTicker,proto3" json:"in_tx_ticker,omitempty"` + OutTxTicker uint64 `protobuf:"varint,4,opt,name=out_tx_ticker,json=outTxTicker,proto3" json:"out_tx_ticker,omitempty"` + WatchUtxoTicker uint64 `protobuf:"varint,5,opt,name=watch_utxo_ticker,json=watchUtxoTicker,proto3" json:"watch_utxo_ticker,omitempty"` + ZetaTokenContractAddress string `protobuf:"bytes,8,opt,name=zeta_token_contract_address,json=zetaTokenContractAddress,proto3" json:"zeta_token_contract_address,omitempty"` + ConnectorContractAddress string `protobuf:"bytes,9,opt,name=connector_contract_address,json=connectorContractAddress,proto3" json:"connector_contract_address,omitempty"` + Erc20CustodyContractAddress string `protobuf:"bytes,10,opt,name=erc20_custody_contract_address,json=erc20CustodyContractAddress,proto3" json:"erc20_custody_contract_address,omitempty"` + OutboundTxScheduleInterval int64 `protobuf:"varint,12,opt,name=outbound_tx_schedule_interval,json=outboundTxScheduleInterval,proto3" json:"outbound_tx_schedule_interval,omitempty"` + OutboundTxScheduleLookahead int64 `protobuf:"varint,13,opt,name=outbound_tx_schedule_lookahead,json=outboundTxScheduleLookahead,proto3" json:"outbound_tx_schedule_lookahead,omitempty"` + BallotThreshold github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=ballot_threshold,json=ballotThreshold,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"ballot_threshold"` + MinObserverDelegation github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,15,opt,name=min_observer_delegation,json=minObserverDelegation,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_observer_delegation"` + IsSupported bool `protobuf:"varint,16,opt,name=is_supported,json=isSupported,proto3" json:"is_supported,omitempty"` +} + +func (m *ChainParams) Reset() { *m = ChainParams{} } +func (m *ChainParams) String() string { return proto.CompactTextString(m) } +func (*ChainParams) ProtoMessage() {} +func (*ChainParams) Descriptor() ([]byte, []int) { return fileDescriptor_4542fa62877488a1, []int{1} } -func (m *CoreParams) XXX_Unmarshal(b []byte) error { +func (m *ChainParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *CoreParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ChainParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_CoreParams.Marshal(b, m, deterministic) + return xxx_messageInfo_ChainParams.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -130,95 +133,103 @@ func (m *CoreParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *CoreParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_CoreParams.Merge(m, src) +func (m *ChainParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainParams.Merge(m, src) } -func (m *CoreParams) XXX_Size() int { +func (m *ChainParams) XXX_Size() int { return m.Size() } -func (m *CoreParams) XXX_DiscardUnknown() { - xxx_messageInfo_CoreParams.DiscardUnknown(m) +func (m *ChainParams) XXX_DiscardUnknown() { + xxx_messageInfo_ChainParams.DiscardUnknown(m) } -var xxx_messageInfo_CoreParams proto.InternalMessageInfo +var xxx_messageInfo_ChainParams proto.InternalMessageInfo -func (m *CoreParams) GetConfirmationCount() uint64 { +func (m *ChainParams) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +func (m *ChainParams) GetConfirmationCount() uint64 { if m != nil { return m.ConfirmationCount } return 0 } -func (m *CoreParams) GetGasPriceTicker() uint64 { +func (m *ChainParams) GetGasPriceTicker() uint64 { if m != nil { return m.GasPriceTicker } return 0 } -func (m *CoreParams) GetInTxTicker() uint64 { +func (m *ChainParams) GetInTxTicker() uint64 { if m != nil { return m.InTxTicker } return 0 } -func (m *CoreParams) GetOutTxTicker() uint64 { +func (m *ChainParams) GetOutTxTicker() uint64 { if m != nil { return m.OutTxTicker } return 0 } -func (m *CoreParams) GetWatchUtxoTicker() uint64 { +func (m *ChainParams) GetWatchUtxoTicker() uint64 { if m != nil { return m.WatchUtxoTicker } return 0 } -func (m *CoreParams) GetZetaTokenContractAddress() string { +func (m *ChainParams) GetZetaTokenContractAddress() string { if m != nil { return m.ZetaTokenContractAddress } return "" } -func (m *CoreParams) GetConnectorContractAddress() string { +func (m *ChainParams) GetConnectorContractAddress() string { if m != nil { return m.ConnectorContractAddress } return "" } -func (m *CoreParams) GetErc20CustodyContractAddress() string { +func (m *ChainParams) GetErc20CustodyContractAddress() string { if m != nil { return m.Erc20CustodyContractAddress } return "" } -func (m *CoreParams) GetChainId() int64 { +func (m *ChainParams) GetOutboundTxScheduleInterval() int64 { if m != nil { - return m.ChainId + return m.OutboundTxScheduleInterval } return 0 } -func (m *CoreParams) GetOutboundTxScheduleInterval() int64 { +func (m *ChainParams) GetOutboundTxScheduleLookahead() int64 { if m != nil { - return m.OutboundTxScheduleInterval + return m.OutboundTxScheduleLookahead } return 0 } -func (m *CoreParams) GetOutboundTxScheduleLookahead() int64 { +func (m *ChainParams) GetIsSupported() bool { if m != nil { - return m.OutboundTxScheduleLookahead + return m.IsSupported } - return 0 + return false } +// Deprecated: Use ChainParamsList type ObserverParams struct { Chain *common.Chain `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` BallotThreshold github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=ballot_threshold,json=ballotThreshold,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"ballot_threshold"` @@ -327,6 +338,7 @@ func (m *Admin_Policy) GetAddress() string { // Params defines the parameters for the module. type Params struct { + // Deprecated: Use ChainParamsList ObserverParams []*ObserverParams `protobuf:"bytes,1,rep,name=observer_params,json=observerParams,proto3" json:"observer_params,omitempty"` AdminPolicy []*Admin_Policy `protobuf:"bytes,2,rep,name=admin_policy,json=adminPolicy,proto3" json:"admin_policy,omitempty"` BallotMaturityBlocks int64 `protobuf:"varint,3,opt,name=ballot_maturity_blocks,json=ballotMaturityBlocks,proto3" json:"ballot_maturity_blocks,omitempty"` @@ -387,8 +399,8 @@ func (m *Params) GetBallotMaturityBlocks() int64 { func init() { proto.RegisterEnum("zetachain.zetacore.observer.Policy_Type", Policy_Type_name, Policy_Type_value) - proto.RegisterType((*CoreParamsList)(nil), "zetachain.zetacore.observer.CoreParamsList") - proto.RegisterType((*CoreParams)(nil), "zetachain.zetacore.observer.CoreParams") + proto.RegisterType((*ChainParamsList)(nil), "zetachain.zetacore.observer.ChainParamsList") + proto.RegisterType((*ChainParams)(nil), "zetachain.zetacore.observer.ChainParams") proto.RegisterType((*ObserverParams)(nil), "zetachain.zetacore.observer.ObserverParams") proto.RegisterType((*Admin_Policy)(nil), "zetachain.zetacore.observer.Admin_Policy") proto.RegisterType((*Params)(nil), "zetachain.zetacore.observer.Params") @@ -397,60 +409,61 @@ func init() { func init() { proto.RegisterFile("observer/params.proto", fileDescriptor_4542fa62877488a1) } var fileDescriptor_4542fa62877488a1 = []byte{ - // 792 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0xbd, 0x89, 0x9b, 0x26, 0x6f, 0x1d, 0x27, 0x5d, 0x5a, 0xba, 0x38, 0xc2, 0x31, 0x46, - 0x02, 0xd3, 0x2a, 0x36, 0x18, 0x4e, 0x08, 0x0e, 0x89, 0x7b, 0x20, 0x52, 0x10, 0xd1, 0xd6, 0x1c, - 0xe8, 0x65, 0x34, 0x9e, 0x9d, 0xda, 0x23, 0xaf, 0xf7, 0xad, 0x66, 0x66, 0x8b, 0xcd, 0x5f, 0xc1, - 0x11, 0x89, 0x0b, 0x07, 0x0e, 0xfc, 0x11, 0xfc, 0x01, 0x3d, 0xf6, 0x88, 0x38, 0x54, 0x28, 0xb9, - 0xf0, 0x67, 0xa0, 0x7d, 0xfb, 0xa3, 0x4e, 0x82, 0x22, 0xf5, 0xe4, 0xb7, 0xf3, 0x3e, 0xef, 0x3b, - 0x6f, 0xde, 0x7c, 0x3d, 0xf0, 0x00, 0x27, 0x46, 0xea, 0x17, 0x52, 0x0f, 0x12, 0xae, 0xf9, 0xc2, - 0xf4, 0x13, 0x8d, 0x16, 0xbd, 0x83, 0x9f, 0xa4, 0xe5, 0x62, 0xc6, 0x55, 0xdc, 0xa7, 0x08, 0xb5, - 0xec, 0x97, 0x64, 0xeb, 0x1d, 0x81, 0x8b, 0x05, 0xc6, 0x83, 0xfc, 0x27, 0xaf, 0x68, 0xdd, 0x9f, - 0xe2, 0x14, 0x29, 0x1c, 0x64, 0x51, 0xb1, 0xfa, 0xb0, 0x92, 0x2f, 0x83, 0x3c, 0xd1, 0x7d, 0x06, - 0xcd, 0x11, 0x6a, 0x79, 0x4e, 0x9b, 0x9e, 0x29, 0x63, 0xbd, 0x6f, 0xc0, 0xcd, 0xb6, 0x61, 0x79, - 0x1f, 0xbe, 0xd3, 0xd9, 0xec, 0xb9, 0xc3, 0x8f, 0xfb, 0xb7, 0x34, 0xd2, 0x7f, 0xa3, 0x10, 0x80, - 0xa8, 0xe2, 0xee, 0x9f, 0x75, 0x80, 0x37, 0x29, 0xef, 0x08, 0x3c, 0x81, 0xf1, 0x73, 0xa5, 0x17, - 0xdc, 0x2a, 0x8c, 0x99, 0xc0, 0x34, 0xb6, 0xbe, 0xd3, 0x71, 0x7a, 0xf5, 0xe0, 0xde, 0x7a, 0x66, - 0x94, 0x25, 0xbc, 0x1e, 0xec, 0x4f, 0xb9, 0x61, 0x89, 0x56, 0x42, 0x32, 0xab, 0xc4, 0x5c, 0x6a, - 0x7f, 0x83, 0xe0, 0xe6, 0x94, 0x9b, 0xf3, 0x6c, 0x79, 0x4c, 0xab, 0x5e, 0x07, 0x1a, 0x2a, 0x66, - 0x76, 0x59, 0x52, 0x9b, 0x44, 0x81, 0x8a, 0xc7, 0xcb, 0x82, 0xe8, 0xc2, 0x2e, 0xa6, 0x76, 0x0d, - 0xa9, 0x13, 0xe2, 0x62, 0x6a, 0x2b, 0xe6, 0x11, 0xdc, 0xfb, 0x91, 0x5b, 0x31, 0x63, 0xa9, 0x5d, - 0x62, 0xc9, 0xdd, 0x21, 0x6e, 0x8f, 0x12, 0xdf, 0xdb, 0x25, 0x16, 0xec, 0xd7, 0x40, 0x17, 0xc3, - 0x2c, 0xce, 0x65, 0x76, 0x90, 0xd8, 0x6a, 0x2e, 0x2c, 0xe3, 0x61, 0xa8, 0xa5, 0x31, 0xfe, 0x76, - 0xc7, 0xe9, 0xed, 0x04, 0x7e, 0x86, 0x8c, 0x33, 0x62, 0x54, 0x00, 0xc7, 0x79, 0xde, 0xfb, 0x0a, - 0x5a, 0x02, 0xe3, 0x58, 0x0a, 0x8b, 0xfa, 0x66, 0xf5, 0x4e, 0x5e, 0x5d, 0x11, 0xd7, 0xab, 0x47, - 0xd0, 0x96, 0x5a, 0x0c, 0x3f, 0x65, 0x22, 0x35, 0x16, 0xc3, 0xd5, 0x4d, 0x05, 0x20, 0x85, 0x03, - 0xa2, 0x46, 0x39, 0x74, 0x5d, 0xe4, 0x3d, 0xd8, 0xa6, 0xdb, 0x64, 0x2a, 0xf4, 0xdd, 0x8e, 0xd3, - 0xdb, 0x0c, 0xee, 0xd2, 0xf7, 0x69, 0xe8, 0x1d, 0xc3, 0xfb, 0x98, 0xda, 0x09, 0xa6, 0x71, 0x98, - 0x4d, 0xcc, 0x88, 0x99, 0x0c, 0xd3, 0x48, 0x32, 0x15, 0x5b, 0xa9, 0x5f, 0xf0, 0xc8, 0x6f, 0x10, - 0xdf, 0x2a, 0xa1, 0xf1, 0xf2, 0x69, 0x81, 0x9c, 0x16, 0x44, 0xd6, 0xe2, 0xff, 0x4a, 0x44, 0x88, - 0x73, 0x3e, 0x93, 0x3c, 0xf4, 0x77, 0x49, 0xe3, 0xe0, 0xa6, 0xc6, 0x59, 0x89, 0x74, 0x7f, 0xdd, - 0x80, 0xe6, 0x77, 0x85, 0xc5, 0x0a, 0x0b, 0x7d, 0x08, 0x77, 0xa8, 0x4b, 0x72, 0x8d, 0x3b, 0xdc, - 0xed, 0x17, 0xd6, 0x1f, 0x65, 0x8b, 0x41, 0x9e, 0xf3, 0x7e, 0x80, 0xfd, 0x09, 0x8f, 0x22, 0xb4, - 0xcc, 0xce, 0xb4, 0x34, 0x33, 0x8c, 0x42, 0xb2, 0xc4, 0xce, 0x49, 0xff, 0xe5, 0xeb, 0xc3, 0xda, - 0xdf, 0xaf, 0x0f, 0x3f, 0x9a, 0x2a, 0x3b, 0x4b, 0x27, 0x59, 0xf5, 0x40, 0xa0, 0x59, 0xa0, 0x29, - 0x7e, 0x8e, 0x4c, 0x38, 0x1f, 0xd8, 0x55, 0x22, 0x4d, 0xff, 0x89, 0x14, 0xc1, 0x5e, 0xae, 0x33, - 0x2e, 0x65, 0xbc, 0xe7, 0xf0, 0x70, 0xa1, 0x62, 0x56, 0x1a, 0x9f, 0x85, 0x32, 0x92, 0x53, 0xf2, - 0x2c, 0x39, 0xea, 0xed, 0x77, 0x78, 0xb0, 0x50, 0x71, 0x79, 0xc6, 0x27, 0x95, 0x98, 0xf7, 0x01, - 0x34, 0x94, 0x61, 0x26, 0x4d, 0x12, 0xd4, 0x56, 0x86, 0x64, 0xc3, 0xed, 0xc0, 0x55, 0xe6, 0x69, - 0xb9, 0xd4, 0x35, 0xd0, 0x38, 0x0e, 0xb3, 0x66, 0xce, 0x31, 0x52, 0x62, 0xe5, 0x9d, 0x82, 0x9b, - 0x50, 0xc4, 0x32, 0x75, 0x1a, 0x50, 0x73, 0xd8, 0xbb, 0xf5, 0x6f, 0x9b, 0x57, 0xb2, 0xf1, 0x2a, - 0x91, 0x01, 0xe4, 0xc5, 0x59, 0xec, 0xf9, 0x70, 0xb7, 0x74, 0xd2, 0x06, 0x39, 0xa9, 0xfc, 0xec, - 0xfe, 0xeb, 0xc0, 0x56, 0x71, 0x15, 0x63, 0xd8, 0xab, 0xc6, 0x70, 0xe5, 0xa9, 0x78, 0x7c, 0xeb, - 0x9e, 0x57, 0x2f, 0x34, 0x68, 0xe2, 0xd5, 0x0b, 0x3e, 0x83, 0x06, 0xa7, 0x53, 0xe5, 0xed, 0xf8, - 0x1b, 0x24, 0xf9, 0xc9, 0xad, 0x92, 0xeb, 0x63, 0x08, 0x5c, 0x2a, 0x2f, 0x66, 0xf2, 0x05, 0xbc, - 0x5b, 0x38, 0x61, 0xc1, 0x6d, 0xaa, 0x95, 0x5d, 0xb1, 0x49, 0x84, 0x62, 0x6e, 0xc8, 0x0f, 0x9b, - 0xc1, 0xfd, 0x3c, 0xfb, 0x6d, 0x91, 0x3c, 0xa1, 0xdc, 0x97, 0xf5, 0x5f, 0x7e, 0x3b, 0xac, 0x3d, - 0x7a, 0x0c, 0xee, 0xda, 0x7c, 0x3c, 0x80, 0xad, 0xa9, 0xc6, 0x34, 0xf9, 0x6c, 0xbf, 0x56, 0xc5, - 0xc3, 0x7d, 0xa7, 0x55, 0xff, 0xe3, 0xf7, 0xb6, 0x73, 0x72, 0xfa, 0xf2, 0xa2, 0xed, 0xbc, 0xba, - 0x68, 0x3b, 0xff, 0x5c, 0xb4, 0x9d, 0x9f, 0x2f, 0xdb, 0xb5, 0x57, 0x97, 0xed, 0xda, 0x5f, 0x97, - 0xed, 0xda, 0xb3, 0xc1, 0x9a, 0x11, 0xb2, 0xd6, 0x8f, 0xe8, 0x14, 0x83, 0xf2, 0x14, 0x83, 0x65, - 0xf5, 0x20, 0xe7, 0xae, 0x98, 0x6c, 0xd1, 0xbb, 0xfc, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x7f, 0x57, 0xd8, 0xba, 0x11, 0x06, 0x00, 0x00, -} - -func (m *CoreParamsList) Marshal() (dAtA []byte, err error) { + // 808 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x41, 0x8f, 0xdb, 0x44, + 0x14, 0xc7, 0xe3, 0x4d, 0x76, 0xbb, 0x7d, 0xce, 0x26, 0xa9, 0x69, 0xa9, 0xc9, 0x0a, 0x6f, 0x08, + 0x12, 0x0a, 0xad, 0xd6, 0x86, 0x85, 0x13, 0x82, 0xc3, 0x6e, 0x7a, 0x59, 0xb1, 0x88, 0x95, 0x1b, + 0x0e, 0x70, 0x60, 0x34, 0x19, 0x4f, 0x93, 0x51, 0x6c, 0x3f, 0x6b, 0x66, 0x5c, 0x12, 0x3e, 0x05, + 0x47, 0x24, 0x2e, 0x48, 0x70, 0xe0, 0xa3, 0xf4, 0xd8, 0x23, 0xe2, 0x50, 0xa1, 0xdd, 0x0b, 0x1f, + 0x03, 0x79, 0x6c, 0x87, 0x6c, 0xb7, 0x5a, 0xa4, 0x4a, 0x3d, 0xf9, 0x79, 0xde, 0xef, 0xfd, 0xe7, + 0xcd, 0x9b, 0xf7, 0x6c, 0xb8, 0x87, 0x53, 0xc5, 0xe5, 0x53, 0x2e, 0x83, 0x8c, 0x4a, 0x9a, 0x28, + 0x3f, 0x93, 0xa8, 0xd1, 0xd9, 0xff, 0x91, 0x6b, 0xca, 0xe6, 0x54, 0xa4, 0xbe, 0xb1, 0x50, 0x72, + 0xbf, 0x26, 0xfb, 0x6f, 0x31, 0x4c, 0x12, 0x4c, 0x83, 0xf2, 0x51, 0x46, 0xf4, 0xef, 0xce, 0x70, + 0x86, 0xc6, 0x0c, 0x0a, 0xab, 0x5a, 0xbd, 0xbf, 0x96, 0xaf, 0x8d, 0xd2, 0x31, 0xfc, 0x1e, 0xba, + 0xe3, 0x42, 0xfe, 0xdc, 0xec, 0x7a, 0x26, 0x94, 0x76, 0xbe, 0x84, 0xb6, 0xd9, 0x91, 0x94, 0x99, + 0xb8, 0xd6, 0xa0, 0x39, 0xb2, 0x8f, 0x46, 0xfe, 0x0d, 0xa9, 0xf8, 0x1b, 0x1a, 0xa1, 0xcd, 0xfe, + 0x7b, 0x19, 0xfe, 0xb6, 0x03, 0xf6, 0x86, 0xd3, 0x79, 0x07, 0x76, 0x4b, 0x71, 0x11, 0xb9, 0xf6, + 0xc0, 0x1a, 0x35, 0xc3, 0x5b, 0xe6, 0xfd, 0x34, 0x72, 0x0e, 0xc1, 0x61, 0x98, 0x3e, 0x11, 0x32, + 0xa1, 0x5a, 0x60, 0x4a, 0x18, 0xe6, 0xa9, 0x76, 0xad, 0x81, 0x35, 0x6a, 0x85, 0x77, 0x36, 0x3d, + 0xe3, 0xc2, 0xe1, 0x8c, 0xa0, 0x37, 0xa3, 0x8a, 0x64, 0x52, 0x30, 0x4e, 0xb4, 0x60, 0x0b, 0x2e, + 0xdd, 0x2d, 0x03, 0x77, 0x66, 0x54, 0x9d, 0x17, 0xcb, 0x13, 0xb3, 0xea, 0x0c, 0xa0, 0x2d, 0x52, + 0xa2, 0x97, 0x35, 0xd5, 0x34, 0x14, 0x88, 0x74, 0xb2, 0xac, 0x88, 0x21, 0xec, 0x61, 0xae, 0x37, + 0x90, 0x96, 0x41, 0x6c, 0xcc, 0xf5, 0x9a, 0x79, 0x00, 0x77, 0x7e, 0xa0, 0x9a, 0xcd, 0x49, 0xae, + 0x97, 0x58, 0x73, 0xdb, 0x86, 0xeb, 0x1a, 0xc7, 0x37, 0x7a, 0x89, 0x15, 0xfb, 0x05, 0x98, 0x8b, + 0x23, 0x1a, 0x17, 0xbc, 0x38, 0x48, 0xaa, 0x25, 0x65, 0x9a, 0xd0, 0x28, 0x92, 0x5c, 0x29, 0x77, + 0x77, 0x60, 0x8d, 0x6e, 0x87, 0x6e, 0x81, 0x4c, 0x0a, 0x62, 0x5c, 0x01, 0xc7, 0xa5, 0xdf, 0xf9, + 0x1c, 0xfa, 0x0c, 0xd3, 0x94, 0x33, 0x8d, 0xf2, 0x7a, 0xf4, 0xed, 0x32, 0x7a, 0x4d, 0xbc, 0x1c, + 0x3d, 0x06, 0x8f, 0x4b, 0x76, 0xf4, 0x11, 0x61, 0xb9, 0xd2, 0x18, 0xad, 0xae, 0x2b, 0x80, 0x51, + 0xd8, 0x37, 0xd4, 0xb8, 0x84, 0x5e, 0x16, 0x39, 0x86, 0x77, 0x31, 0xd7, 0x53, 0xcc, 0xd3, 0xa8, + 0x28, 0x8b, 0x62, 0x73, 0x1e, 0xe5, 0x31, 0x27, 0x22, 0xd5, 0x5c, 0x3e, 0xa5, 0xb1, 0xdb, 0x36, + 0x97, 0xd7, 0xaf, 0xa1, 0xc9, 0xf2, 0x71, 0x85, 0x9c, 0x56, 0x44, 0x91, 0xc7, 0x2b, 0x25, 0x62, + 0xc4, 0x05, 0x9d, 0x73, 0x1a, 0xb9, 0x7b, 0x46, 0x63, 0xff, 0xba, 0xc6, 0x59, 0x8d, 0x38, 0xdf, + 0x42, 0x6f, 0x4a, 0xe3, 0x18, 0x35, 0xd1, 0x73, 0xc9, 0xd5, 0x1c, 0xe3, 0xc8, 0xed, 0x14, 0xe9, + 0x9f, 0xf8, 0xcf, 0x5e, 0x1c, 0x34, 0xfe, 0x7a, 0x71, 0xf0, 0xc1, 0x4c, 0xe8, 0x79, 0x3e, 0xf5, + 0x19, 0x26, 0x01, 0x43, 0x95, 0xa0, 0xaa, 0x1e, 0x87, 0x2a, 0x5a, 0x04, 0x7a, 0x95, 0x71, 0xe5, + 0x3f, 0xe2, 0x2c, 0xec, 0x96, 0x3a, 0x93, 0x5a, 0xc6, 0x79, 0x02, 0xf7, 0x13, 0x91, 0x92, 0xba, + 0x87, 0x49, 0xc4, 0x63, 0x3e, 0x33, 0x0d, 0xe6, 0x76, 0x5f, 0x6b, 0x87, 0x7b, 0x89, 0x48, 0xbf, + 0xae, 0xd4, 0x1e, 0xad, 0xc5, 0x9c, 0xf7, 0xa0, 0x2d, 0x14, 0x51, 0x79, 0x96, 0xa1, 0xd4, 0x3c, + 0x72, 0x7b, 0x03, 0x6b, 0xb4, 0x1b, 0xda, 0x42, 0x3d, 0xae, 0x97, 0x86, 0xbf, 0x6c, 0x41, 0xa7, + 0x8e, 0xac, 0x06, 0xe5, 0x7d, 0xd8, 0x36, 0x83, 0x61, 0x06, 0xc0, 0x3e, 0xda, 0xf3, 0xab, 0x29, + 0x37, 0xc3, 0x14, 0x96, 0xbe, 0x57, 0x56, 0xa7, 0xf9, 0xc6, 0xab, 0xd3, 0x7a, 0x93, 0xd5, 0xd9, + 0xbe, 0x5e, 0x1d, 0x05, 0xed, 0xe3, 0xa8, 0x48, 0xe6, 0x1c, 0x63, 0xc1, 0x56, 0xce, 0x29, 0xd8, + 0x99, 0xb1, 0x48, 0xa1, 0x6e, 0x0a, 0xd4, 0xf9, 0x9f, 0xef, 0x53, 0x19, 0x49, 0x26, 0xab, 0x8c, + 0x87, 0x50, 0x06, 0x17, 0xb6, 0xe3, 0xc2, 0xad, 0x7a, 0x28, 0xb6, 0xcc, 0x50, 0xd4, 0xaf, 0xc3, + 0x7f, 0x2c, 0xd8, 0xa9, 0xae, 0x62, 0x02, 0xdd, 0x75, 0x19, 0xae, 0x7c, 0x13, 0x1f, 0xde, 0xb8, + 0xe7, 0xd5, 0x0b, 0x0d, 0x3b, 0x78, 0xf5, 0x82, 0xcf, 0xa0, 0x4d, 0xcd, 0xa9, 0xca, 0x74, 0xdc, + 0x2d, 0x23, 0xf9, 0xe1, 0x8d, 0x92, 0x9b, 0x65, 0x08, 0x6d, 0x13, 0x5e, 0xd5, 0xe4, 0x53, 0x78, + 0xbb, 0xea, 0x84, 0x84, 0xea, 0x5c, 0x0a, 0xbd, 0x22, 0xd3, 0x18, 0xd9, 0x42, 0x99, 0x7e, 0x68, + 0x86, 0x77, 0x4b, 0xef, 0x57, 0x95, 0xf3, 0xc4, 0xf8, 0x3e, 0x6b, 0xfd, 0xfc, 0xeb, 0x41, 0xe3, + 0xc1, 0x43, 0xb0, 0x37, 0xea, 0xe3, 0x00, 0xec, 0xcc, 0x24, 0xe6, 0xd9, 0xc7, 0xbd, 0xc6, 0xda, + 0x3e, 0xea, 0x59, 0xfd, 0xd6, 0x1f, 0xbf, 0x7b, 0xd6, 0xc9, 0xe9, 0xb3, 0x0b, 0xcf, 0x7a, 0x7e, + 0xe1, 0x59, 0x7f, 0x5f, 0x78, 0xd6, 0x4f, 0x97, 0x5e, 0xe3, 0xf9, 0xa5, 0xd7, 0xf8, 0xf3, 0xd2, + 0x6b, 0x7c, 0x17, 0x6c, 0x34, 0x42, 0x91, 0xfa, 0xa1, 0x39, 0x45, 0x50, 0x9f, 0x22, 0x58, 0xae, + 0xff, 0x3d, 0x65, 0x57, 0x4c, 0x77, 0xcc, 0x2f, 0xe8, 0x93, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, + 0xaf, 0x0f, 0xcf, 0xef, 0xfc, 0x06, 0x00, 0x00, +} + +func (m *ChainParamsList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -460,20 +473,20 @@ func (m *CoreParamsList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *CoreParamsList) MarshalTo(dAtA []byte) (int, error) { +func (m *ChainParamsList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *CoreParamsList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ChainParamsList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.CoreParams) > 0 { - for iNdEx := len(m.CoreParams) - 1; iNdEx >= 0; iNdEx-- { + if len(m.ChainParams) > 0 { + for iNdEx := len(m.ChainParams) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.CoreParams[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ChainParams[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -487,7 +500,7 @@ func (m *CoreParamsList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *CoreParams) Marshal() (dAtA []byte, err error) { +func (m *ChainParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -497,16 +510,48 @@ func (m *CoreParams) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *CoreParams) MarshalTo(dAtA []byte) (int, error) { +func (m *ChainParams) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *CoreParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ChainParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l + if m.IsSupported { + i-- + if m.IsSupported { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } + { + size := m.MinObserverDelegation.Size() + i -= size + if _, err := m.MinObserverDelegation.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x7a + { + size := m.BallotThreshold.Size() + i -= size + if _, err := m.BallotThreshold.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 if m.OutboundTxScheduleLookahead != 0 { i = encodeVarintParams(dAtA, i, uint64(m.OutboundTxScheduleLookahead)) i-- @@ -738,14 +783,14 @@ func encodeVarintParams(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *CoreParamsList) Size() (n int) { +func (m *ChainParamsList) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.CoreParams) > 0 { - for _, e := range m.CoreParams { + if len(m.ChainParams) > 0 { + for _, e := range m.ChainParams { l = e.Size() n += 1 + l + sovParams(uint64(l)) } @@ -753,7 +798,7 @@ func (m *CoreParamsList) Size() (n int) { return n } -func (m *CoreParams) Size() (n int) { +func (m *ChainParams) Size() (n int) { if m == nil { return 0 } @@ -795,6 +840,13 @@ func (m *CoreParams) Size() (n int) { if m.OutboundTxScheduleLookahead != 0 { n += 1 + sovParams(uint64(m.OutboundTxScheduleLookahead)) } + l = m.BallotThreshold.Size() + n += 1 + l + sovParams(uint64(l)) + l = m.MinObserverDelegation.Size() + n += 1 + l + sovParams(uint64(l)) + if m.IsSupported { + n += 3 + } return n } @@ -864,7 +916,7 @@ func sovParams(x uint64) (n int) { func sozParams(x uint64) (n int) { return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *CoreParamsList) Unmarshal(dAtA []byte) error { +func (m *ChainParamsList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -887,15 +939,15 @@ func (m *CoreParamsList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CoreParamsList: wiretype end group for non-group") + return fmt.Errorf("proto: ChainParamsList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CoreParamsList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ChainParamsList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -922,8 +974,8 @@ func (m *CoreParamsList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CoreParams = append(m.CoreParams, &CoreParams{}) - if err := m.CoreParams[len(m.CoreParams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ChainParams = append(m.ChainParams, &ChainParams{}) + if err := m.ChainParams[len(m.ChainParams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -948,7 +1000,7 @@ func (m *CoreParamsList) Unmarshal(dAtA []byte) error { } return nil } -func (m *CoreParams) Unmarshal(dAtA []byte) error { +func (m *ChainParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -971,10 +1023,10 @@ func (m *CoreParams) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CoreParams: wiretype end group for non-group") + return fmt.Errorf("proto: ChainParams: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CoreParams: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ChainParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1225,6 +1277,94 @@ func (m *CoreParams) Unmarshal(dAtA []byte) error { break } } + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BallotThreshold", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.BallotThreshold.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinObserverDelegation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinObserverDelegation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsSupported", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsSupported = bool(v != 0) default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 7925d09576..752350f029 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -1406,22 +1406,22 @@ func (m *QuerySupportedChainsResponse) GetChains() []*common.Chain { return nil } -type QueryGetCoreParamsForChainRequest struct { +type QueryGetChainParamsForChainRequest struct { ChainId int64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` } -func (m *QueryGetCoreParamsForChainRequest) Reset() { *m = QueryGetCoreParamsForChainRequest{} } -func (m *QueryGetCoreParamsForChainRequest) String() string { return proto.CompactTextString(m) } -func (*QueryGetCoreParamsForChainRequest) ProtoMessage() {} -func (*QueryGetCoreParamsForChainRequest) Descriptor() ([]byte, []int) { +func (m *QueryGetChainParamsForChainRequest) Reset() { *m = QueryGetChainParamsForChainRequest{} } +func (m *QueryGetChainParamsForChainRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetChainParamsForChainRequest) ProtoMessage() {} +func (*QueryGetChainParamsForChainRequest) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{29} } -func (m *QueryGetCoreParamsForChainRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryGetChainParamsForChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGetCoreParamsForChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryGetChainParamsForChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGetCoreParamsForChainRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryGetChainParamsForChainRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1431,41 +1431,41 @@ func (m *QueryGetCoreParamsForChainRequest) XXX_Marshal(b []byte, deterministic return b[:n], nil } } -func (m *QueryGetCoreParamsForChainRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGetCoreParamsForChainRequest.Merge(m, src) +func (m *QueryGetChainParamsForChainRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetChainParamsForChainRequest.Merge(m, src) } -func (m *QueryGetCoreParamsForChainRequest) XXX_Size() int { +func (m *QueryGetChainParamsForChainRequest) XXX_Size() int { return m.Size() } -func (m *QueryGetCoreParamsForChainRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGetCoreParamsForChainRequest.DiscardUnknown(m) +func (m *QueryGetChainParamsForChainRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetChainParamsForChainRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryGetCoreParamsForChainRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryGetChainParamsForChainRequest proto.InternalMessageInfo -func (m *QueryGetCoreParamsForChainRequest) GetChainId() int64 { +func (m *QueryGetChainParamsForChainRequest) GetChainId() int64 { if m != nil { return m.ChainId } return 0 } -type QueryGetCoreParamsForChainResponse struct { - CoreParams *CoreParams `protobuf:"bytes,1,opt,name=core_params,json=coreParams,proto3" json:"core_params,omitempty"` +type QueryGetChainParamsForChainResponse struct { + ChainParams *ChainParams `protobuf:"bytes,1,opt,name=chain_params,json=chainParams,proto3" json:"chain_params,omitempty"` } -func (m *QueryGetCoreParamsForChainResponse) Reset() { *m = QueryGetCoreParamsForChainResponse{} } -func (m *QueryGetCoreParamsForChainResponse) String() string { return proto.CompactTextString(m) } -func (*QueryGetCoreParamsForChainResponse) ProtoMessage() {} -func (*QueryGetCoreParamsForChainResponse) Descriptor() ([]byte, []int) { +func (m *QueryGetChainParamsForChainResponse) Reset() { *m = QueryGetChainParamsForChainResponse{} } +func (m *QueryGetChainParamsForChainResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetChainParamsForChainResponse) ProtoMessage() {} +func (*QueryGetChainParamsForChainResponse) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{30} } -func (m *QueryGetCoreParamsForChainResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryGetChainParamsForChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGetCoreParamsForChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryGetChainParamsForChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGetCoreParamsForChainResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryGetChainParamsForChainResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1475,40 +1475,40 @@ func (m *QueryGetCoreParamsForChainResponse) XXX_Marshal(b []byte, deterministic return b[:n], nil } } -func (m *QueryGetCoreParamsForChainResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGetCoreParamsForChainResponse.Merge(m, src) +func (m *QueryGetChainParamsForChainResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetChainParamsForChainResponse.Merge(m, src) } -func (m *QueryGetCoreParamsForChainResponse) XXX_Size() int { +func (m *QueryGetChainParamsForChainResponse) XXX_Size() int { return m.Size() } -func (m *QueryGetCoreParamsForChainResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGetCoreParamsForChainResponse.DiscardUnknown(m) +func (m *QueryGetChainParamsForChainResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetChainParamsForChainResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryGetCoreParamsForChainResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryGetChainParamsForChainResponse proto.InternalMessageInfo -func (m *QueryGetCoreParamsForChainResponse) GetCoreParams() *CoreParams { +func (m *QueryGetChainParamsForChainResponse) GetChainParams() *ChainParams { if m != nil { - return m.CoreParams + return m.ChainParams } return nil } -type QueryGetCoreParamsRequest struct { +type QueryGetChainParamsRequest struct { } -func (m *QueryGetCoreParamsRequest) Reset() { *m = QueryGetCoreParamsRequest{} } -func (m *QueryGetCoreParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryGetCoreParamsRequest) ProtoMessage() {} -func (*QueryGetCoreParamsRequest) Descriptor() ([]byte, []int) { +func (m *QueryGetChainParamsRequest) Reset() { *m = QueryGetChainParamsRequest{} } +func (m *QueryGetChainParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetChainParamsRequest) ProtoMessage() {} +func (*QueryGetChainParamsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{31} } -func (m *QueryGetCoreParamsRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryGetChainParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGetCoreParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryGetChainParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGetCoreParamsRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryGetChainParamsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1518,34 +1518,34 @@ func (m *QueryGetCoreParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([ return b[:n], nil } } -func (m *QueryGetCoreParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGetCoreParamsRequest.Merge(m, src) +func (m *QueryGetChainParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetChainParamsRequest.Merge(m, src) } -func (m *QueryGetCoreParamsRequest) XXX_Size() int { +func (m *QueryGetChainParamsRequest) XXX_Size() int { return m.Size() } -func (m *QueryGetCoreParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGetCoreParamsRequest.DiscardUnknown(m) +func (m *QueryGetChainParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetChainParamsRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryGetCoreParamsRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryGetChainParamsRequest proto.InternalMessageInfo -type QueryGetCoreParamsResponse struct { - CoreParams *CoreParamsList `protobuf:"bytes,1,opt,name=core_params,json=coreParams,proto3" json:"core_params,omitempty"` +type QueryGetChainParamsResponse struct { + ChainParams *ChainParamsList `protobuf:"bytes,1,opt,name=chain_params,json=chainParams,proto3" json:"chain_params,omitempty"` } -func (m *QueryGetCoreParamsResponse) Reset() { *m = QueryGetCoreParamsResponse{} } -func (m *QueryGetCoreParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryGetCoreParamsResponse) ProtoMessage() {} -func (*QueryGetCoreParamsResponse) Descriptor() ([]byte, []int) { +func (m *QueryGetChainParamsResponse) Reset() { *m = QueryGetChainParamsResponse{} } +func (m *QueryGetChainParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetChainParamsResponse) ProtoMessage() {} +func (*QueryGetChainParamsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_dcb801e455adaee4, []int{32} } -func (m *QueryGetCoreParamsResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryGetChainParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryGetCoreParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryGetChainParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryGetCoreParamsResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryGetChainParamsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1555,21 +1555,21 @@ func (m *QueryGetCoreParamsResponse) XXX_Marshal(b []byte, deterministic bool) ( return b[:n], nil } } -func (m *QueryGetCoreParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryGetCoreParamsResponse.Merge(m, src) +func (m *QueryGetChainParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetChainParamsResponse.Merge(m, src) } -func (m *QueryGetCoreParamsResponse) XXX_Size() int { +func (m *QueryGetChainParamsResponse) XXX_Size() int { return m.Size() } -func (m *QueryGetCoreParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryGetCoreParamsResponse.DiscardUnknown(m) +func (m *QueryGetChainParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetChainParamsResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryGetCoreParamsResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryGetChainParamsResponse proto.InternalMessageInfo -func (m *QueryGetCoreParamsResponse) GetCoreParams() *CoreParamsList { +func (m *QueryGetChainParamsResponse) GetChainParams() *ChainParamsList { if m != nil { - return m.CoreParams + return m.ChainParams } return nil } @@ -2580,10 +2580,10 @@ func init() { proto.RegisterType((*QueryObserverSetResponse)(nil), "zetachain.zetacore.observer.QueryObserverSetResponse") proto.RegisterType((*QuerySupportedChains)(nil), "zetachain.zetacore.observer.QuerySupportedChains") proto.RegisterType((*QuerySupportedChainsResponse)(nil), "zetachain.zetacore.observer.QuerySupportedChainsResponse") - proto.RegisterType((*QueryGetCoreParamsForChainRequest)(nil), "zetachain.zetacore.observer.QueryGetCoreParamsForChainRequest") - proto.RegisterType((*QueryGetCoreParamsForChainResponse)(nil), "zetachain.zetacore.observer.QueryGetCoreParamsForChainResponse") - proto.RegisterType((*QueryGetCoreParamsRequest)(nil), "zetachain.zetacore.observer.QueryGetCoreParamsRequest") - proto.RegisterType((*QueryGetCoreParamsResponse)(nil), "zetachain.zetacore.observer.QueryGetCoreParamsResponse") + proto.RegisterType((*QueryGetChainParamsForChainRequest)(nil), "zetachain.zetacore.observer.QueryGetChainParamsForChainRequest") + proto.RegisterType((*QueryGetChainParamsForChainResponse)(nil), "zetachain.zetacore.observer.QueryGetChainParamsForChainResponse") + proto.RegisterType((*QueryGetChainParamsRequest)(nil), "zetachain.zetacore.observer.QueryGetChainParamsRequest") + proto.RegisterType((*QueryGetChainParamsResponse)(nil), "zetachain.zetacore.observer.QueryGetChainParamsResponse") proto.RegisterType((*QueryGetNodeAccountRequest)(nil), "zetachain.zetacore.observer.QueryGetNodeAccountRequest") proto.RegisterType((*QueryGetNodeAccountResponse)(nil), "zetachain.zetacore.observer.QueryGetNodeAccountResponse") proto.RegisterType((*QueryAllNodeAccountRequest)(nil), "zetachain.zetacore.observer.QueryAllNodeAccountRequest") @@ -2611,164 +2611,163 @@ func init() { func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 2512 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x6f, 0xdc, 0xc6, - 0x15, 0x37, 0xad, 0x48, 0x91, 0x9e, 0x24, 0x5b, 0x1e, 0xcb, 0xb1, 0x4d, 0xd9, 0xb2, 0x4c, 0xc7, - 0xb1, 0x2c, 0xdb, 0xcb, 0x58, 0xce, 0x87, 0xe3, 0xaf, 0x44, 0xeb, 0xda, 0x92, 0x1d, 0xd7, 0x76, - 0x76, 0xdd, 0xa6, 0x70, 0xda, 0xb2, 0xdc, 0xdd, 0xd1, 0x2e, 0x93, 0x15, 0xb9, 0x21, 0x47, 0x8a, - 0x36, 0xaa, 0xd0, 0xa2, 0x47, 0xa3, 0x87, 0x00, 0x05, 0xda, 0x5b, 0x91, 0x4b, 0x7b, 0x6b, 0x51, - 0x04, 0x28, 0x5a, 0xa0, 0xe8, 0xa1, 0xa7, 0xe6, 0xd0, 0x43, 0x8a, 0x02, 0x45, 0x7b, 0x68, 0x11, - 0xd8, 0xed, 0xff, 0x51, 0x70, 0xf8, 0x48, 0x0e, 0x3f, 0x96, 0x3b, 0xab, 0xa8, 0x27, 0x2d, 0x67, - 0xe6, 0xbd, 0xf9, 0xfd, 0xde, 0x7c, 0xbc, 0xf7, 0x13, 0x09, 0xd3, 0x4e, 0xcd, 0xa3, 0xee, 0x06, - 0x75, 0xf5, 0x0f, 0xd7, 0xa9, 0xdb, 0x2d, 0x75, 0x5c, 0x87, 0x39, 0x64, 0xe6, 0x63, 0xca, 0xcc, - 0x7a, 0xcb, 0xb4, 0xec, 0x12, 0xff, 0xe5, 0xb8, 0xb4, 0x14, 0x0e, 0x54, 0x0f, 0xd6, 0x9d, 0xb5, - 0x35, 0xc7, 0xd6, 0x83, 0x3f, 0x81, 0x85, 0xba, 0x50, 0x77, 0xbc, 0x35, 0xc7, 0xd3, 0x6b, 0xa6, - 0x47, 0x03, 0x57, 0xfa, 0xc6, 0xc5, 0x1a, 0x65, 0xe6, 0x45, 0xbd, 0x63, 0x36, 0x2d, 0xdb, 0x64, - 0x56, 0x34, 0x76, 0xba, 0xe9, 0x34, 0x1d, 0xfe, 0x53, 0xf7, 0x7f, 0x61, 0xeb, 0xb1, 0xa6, 0xe3, - 0x34, 0xdb, 0x54, 0x37, 0x3b, 0x96, 0x6e, 0xda, 0xb6, 0xc3, 0xb8, 0x89, 0x87, 0xbd, 0x87, 0x22, - 0x9c, 0x35, 0xb3, 0xdd, 0x76, 0x58, 0xe8, 0x2a, 0x6e, 0x6e, 0x9b, 0x6b, 0x14, 0x5b, 0x67, 0x84, - 0x56, 0xa7, 0xfe, 0x81, 0xd1, 0xa2, 0x66, 0x83, 0xba, 0x99, 0x4e, 0x4e, 0xd0, 0xb0, 0x1d, 0xbb, - 0x4e, 0xc3, 0x69, 0x4e, 0xc4, 0x9d, 0xae, 0xe3, 0x79, 0xc1, 0x88, 0xd5, 0xb6, 0xd9, 0xcc, 0xe2, - 0xf8, 0x80, 0x76, 0x9b, 0xd4, 0xce, 0x38, 0xb5, 0x9d, 0x06, 0x35, 0xcc, 0x7a, 0xdd, 0x59, 0xb7, - 0x43, 0x90, 0x87, 0xa3, 0xce, 0xf0, 0x47, 0xc6, 0x59, 0xc7, 0x74, 0xcd, 0xb5, 0x70, 0x8e, 0xe3, - 0x71, 0x33, 0xb5, 0x1b, 0x96, 0xdd, 0x4c, 0x62, 0x24, 0x51, 0x37, 0xf3, 0xb0, 0x4d, 0x5b, 0x04, - 0xf5, 0x1d, 0x3f, 0xe8, 0xcb, 0x94, 0xdd, 0xf4, 0x31, 0xdf, 0xe7, 0x06, 0x15, 0xfa, 0xe1, 0x3a, - 0xf5, 0x18, 0x99, 0x86, 0x61, 0xcb, 0x6e, 0xd0, 0xcd, 0x23, 0xca, 0x9c, 0x32, 0x3f, 0x56, 0x09, - 0x1e, 0x34, 0x07, 0x66, 0x72, 0x6d, 0xbc, 0x8e, 0x63, 0x7b, 0x94, 0x3c, 0x84, 0x71, 0xa1, 0x99, - 0x9b, 0x8e, 0x2f, 0xce, 0x97, 0x0a, 0x76, 0x46, 0x49, 0x18, 0x5f, 0x7e, 0xee, 0xf3, 0x7f, 0x9f, - 0xd8, 0x53, 0x11, 0x5d, 0x68, 0x0d, 0x04, 0xb9, 0xd4, 0x6e, 0xe7, 0x80, 0xbc, 0x0d, 0x10, 0xef, - 0x14, 0x9c, 0xee, 0xa5, 0x52, 0xb0, 0xad, 0x4a, 0xfe, 0xb6, 0x2a, 0x05, 0x3b, 0x14, 0xb7, 0x55, - 0xe9, 0xa1, 0xd9, 0xa4, 0x68, 0x5b, 0x11, 0x2c, 0xb5, 0xdf, 0x2b, 0xc8, 0x2b, 0x3d, 0x4d, 0x2f, - 0x5e, 0x43, 0x5f, 0x91, 0x17, 0x59, 0x4e, 0x20, 0xdf, 0xcb, 0x91, 0x9f, 0xe9, 0x8b, 0x3c, 0x80, - 0x93, 0x80, 0xbe, 0x0a, 0xc7, 0x42, 0xe4, 0x0f, 0x83, 0x95, 0xff, 0xff, 0x84, 0xe8, 0x4f, 0x0a, - 0x1c, 0xef, 0x31, 0x11, 0x06, 0xe9, 0x5d, 0xd8, 0x97, 0xdc, 0x7b, 0x18, 0xa7, 0x85, 0xc2, 0x38, - 0x25, 0x7c, 0x61, 0xa4, 0x26, 0x3b, 0x62, 0xe3, 0xee, 0xc5, 0xea, 0x3a, 0xcc, 0x71, 0x0a, 0xc9, - 0x39, 0xbb, 0x7c, 0x5d, 0xc2, 0x78, 0x1d, 0x85, 0xd1, 0xe0, 0x04, 0x5b, 0x0d, 0x1e, 0xad, 0xa1, - 0xca, 0xf3, 0xfc, 0xf9, 0x4e, 0x43, 0xfb, 0x3e, 0x9c, 0x2c, 0x30, 0x2f, 0x88, 0x82, 0xb2, 0x0b, - 0x51, 0xd0, 0xa6, 0x81, 0x84, 0x47, 0xef, 0x51, 0xb5, 0x8a, 0x70, 0xb5, 0x07, 0x70, 0x30, 0xd1, - 0x8a, 0x28, 0x2e, 0xc3, 0xd0, 0xa3, 0x6a, 0x15, 0xa7, 0x9e, 0x2b, 0x9c, 0xfa, 0x51, 0xb5, 0x8a, - 0x13, 0xfa, 0x26, 0xda, 0x2d, 0x38, 0x1a, 0x39, 0xf4, 0xbc, 0xa5, 0x46, 0xc3, 0xa5, 0x5e, 0xb4, - 0x99, 0xe6, 0x61, 0xaa, 0x66, 0xb1, 0xba, 0x63, 0xd9, 0x46, 0x14, 0xa4, 0xbd, 0x3c, 0x48, 0xfb, - 0xb0, 0xfd, 0x26, 0xc6, 0xea, 0xad, 0xf8, 0x72, 0x11, 0xdd, 0x20, 0xbc, 0x29, 0x18, 0xa2, 0xac, - 0x85, 0x57, 0x8b, 0xff, 0xd3, 0x6f, 0xa9, 0xb1, 0x3a, 0x77, 0x36, 0x56, 0xf1, 0x7f, 0x6a, 0x4f, - 0x14, 0x58, 0xc8, 0xba, 0x28, 0x77, 0x6f, 0x5b, 0xb6, 0xd9, 0xb6, 0x3e, 0xa6, 0x8d, 0x15, 0x6a, - 0x35, 0x5b, 0x2c, 0x84, 0xb6, 0x08, 0x87, 0x56, 0xc3, 0x1e, 0xc3, 0x67, 0x69, 0xb4, 0x78, 0x3f, - 0x2e, 0xe2, 0xc1, 0xa8, 0xf3, 0x31, 0x65, 0x66, 0x60, 0x3a, 0x00, 0x9d, 0x77, 0xe0, 0x9c, 0x14, - 0x96, 0x01, 0xf8, 0x7d, 0x0f, 0x5e, 0xe0, 0x2e, 0x1f, 0x79, 0xde, 0x8a, 0xe5, 0x31, 0xc7, 0xed, - 0xee, 0xf6, 0x91, 0xfd, 0x85, 0x02, 0x87, 0x33, 0x53, 0x20, 0xc2, 0x25, 0x18, 0x65, 0x9e, 0x67, - 0xb4, 0x2d, 0x8f, 0xe1, 0x31, 0x95, 0xdd, 0x25, 0xcf, 0x33, 0xcf, 0xbb, 0x67, 0x79, 0x6c, 0xf7, - 0x8e, 0xe5, 0x2f, 0x15, 0x38, 0x10, 0x1c, 0x2c, 0xd7, 0xd9, 0xa0, 0xfd, 0x0f, 0x22, 0x39, 0x0c, - 0xcf, 0xb3, 0x4d, 0xa3, 0x65, 0x7a, 0x2d, 0x0c, 0xe8, 0x08, 0xdb, 0x5c, 0x31, 0xbd, 0x16, 0x39, - 0x05, 0xc3, 0x1d, 0xd7, 0x71, 0x56, 0x8f, 0x0c, 0x71, 0x34, 0x93, 0x25, 0xac, 0x37, 0x1e, 0xfa, - 0x8d, 0x95, 0xa0, 0x8f, 0x1c, 0x07, 0xc0, 0x14, 0xef, 0x3b, 0x78, 0x8e, 0x3b, 0x18, 0xe3, 0x2d, - 0xdc, 0xc7, 0x51, 0x18, 0x65, 0x9b, 0x46, 0x90, 0xfb, 0x86, 0x83, 0x79, 0xd9, 0xe6, 0x1d, 0x9e, - 0xfd, 0x16, 0xf0, 0x08, 0x22, 0x4e, 0x0c, 0xe5, 0x34, 0x0c, 0x6f, 0x98, 0x6d, 0x44, 0x39, 0x5a, - 0x09, 0x1e, 0xa2, 0xe3, 0xfa, 0x90, 0x67, 0xe9, 0xf0, 0xb8, 0x7e, 0x0b, 0x8f, 0x6b, 0xd8, 0x1a, - 0xad, 0xc6, 0x48, 0x90, 0xcd, 0x71, 0xb5, 0x4f, 0x15, 0x5f, 0x16, 0x7c, 0x28, 0x2e, 0x07, 0x1a, - 0x6a, 0x2d, 0x98, 0xe6, 0x9e, 0x57, 0x4c, 0xef, 0x9b, 0x0e, 0xa3, 0x8d, 0x30, 0x8c, 0xe7, 0xe0, - 0x40, 0x50, 0xfd, 0x18, 0x56, 0x83, 0xda, 0xcc, 0x5a, 0xb5, 0xa8, 0x8b, 0x1b, 0x73, 0x2a, 0xe8, - 0xb8, 0x13, 0xb5, 0x93, 0x53, 0x30, 0xb9, 0xe1, 0x30, 0xea, 0x1a, 0x66, 0xb0, 0xc3, 0x31, 0xbc, - 0x13, 0xbc, 0x11, 0x77, 0xbd, 0xf6, 0x0a, 0x1c, 0x4a, 0xcd, 0x84, 0x2c, 0x66, 0x60, 0xac, 0x65, - 0x7a, 0x86, 0x3f, 0x38, 0x0c, 0xc6, 0x68, 0x0b, 0x07, 0x69, 0x5f, 0x87, 0x59, 0x6e, 0x55, 0xe6, - 0x73, 0x96, 0xbb, 0xf1, 0xac, 0x3b, 0x41, 0xaa, 0x31, 0x18, 0xf3, 0xfd, 0xba, 0x7c, 0x27, 0x66, - 0x60, 0x2b, 0x59, 0xd8, 0xa4, 0x0c, 0x63, 0xfe, 0xb3, 0xc1, 0xba, 0x1d, 0xca, 0x79, 0xed, 0x5b, - 0x3c, 0x5d, 0x18, 0x66, 0xdf, 0xff, 0xa3, 0x6e, 0x87, 0x56, 0x46, 0x37, 0xf0, 0x97, 0xf6, 0xbb, - 0xbd, 0x70, 0xa2, 0x27, 0x0b, 0x8c, 0xc2, 0x40, 0x01, 0xbf, 0x01, 0x23, 0x1c, 0xa4, 0x1f, 0xe9, - 0x21, 0x7e, 0xcc, 0xfb, 0x21, 0xe2, 0x8c, 0x2b, 0x68, 0x45, 0xde, 0x85, 0xa9, 0xa0, 0x97, 0x9f, - 0xa4, 0x80, 0xdb, 0x10, 0xe7, 0x76, 0xbe, 0xd0, 0xd3, 0x83, 0xd8, 0x88, 0x53, 0xdc, 0xef, 0x24, - 0x1b, 0xc8, 0x7d, 0x98, 0x44, 0x16, 0x1e, 0x33, 0xd9, 0xba, 0xc7, 0xcf, 0xc9, 0xbe, 0xc5, 0xb3, - 0x85, 0x5e, 0x83, 0xa8, 0x54, 0xb9, 0x41, 0x65, 0xa2, 0x26, 0x3c, 0x69, 0x04, 0xa6, 0x78, 0xe0, - 0x1e, 0xe0, 0xd8, 0x2a, 0x65, 0xda, 0x65, 0x38, 0x92, 0x6e, 0x8b, 0xa2, 0x78, 0x0c, 0xc6, 0x42, - 0xb7, 0x41, 0x1d, 0x31, 0x56, 0x89, 0x1b, 0xb4, 0x17, 0x70, 0xb3, 0x57, 0xd7, 0x3b, 0x1d, 0xc7, - 0x65, 0xb4, 0xc1, 0xef, 0x69, 0x4f, 0xbb, 0x85, 0xc5, 0x50, 0xaa, 0x3d, 0xf2, 0x7a, 0x1a, 0x46, - 0x38, 0xf6, 0xb0, 0x34, 0x89, 0x2e, 0x88, 0x20, 0x87, 0x63, 0xa7, 0x76, 0x03, 0x13, 0xbd, 0x5f, - 0xe5, 0x3a, 0x2e, 0x0d, 0xce, 0xdb, 0x6d, 0xc7, 0x95, 0x2d, 0x14, 0x6c, 0xd0, 0x8a, 0xec, 0x11, - 0xcc, 0x0a, 0x8c, 0xfb, 0xe1, 0x33, 0x12, 0x27, 0xff, 0x4c, 0x71, 0x51, 0x19, 0x79, 0xab, 0x40, - 0x3d, 0xfa, 0xad, 0xcd, 0xc4, 0x39, 0x5b, 0x18, 0x81, 0x57, 0xce, 0xfb, 0x42, 0x99, 0x2f, 0x74, - 0x22, 0x88, 0x7b, 0x79, 0x20, 0xce, 0x49, 0x82, 0xe0, 0x5b, 0x51, 0x04, 0x22, 0x48, 0x8a, 0xfb, - 0x4e, 0x83, 0x2e, 0x05, 0x92, 0xa6, 0x58, 0x52, 0xbc, 0x1f, 0x4b, 0x8a, 0x84, 0x0d, 0x02, 0x7c, - 0x1b, 0x26, 0x44, 0x79, 0x24, 0xa5, 0x29, 0x44, 0x3f, 0xe3, 0x76, 0xfc, 0x20, 0xaa, 0x89, 0x1c, - 0x7c, 0xbb, 0x95, 0x77, 0x3f, 0x13, 0xd4, 0x44, 0x1e, 0xa5, 0xbb, 0x30, 0x2e, 0x34, 0x4b, 0xa9, - 0x89, 0x04, 0x23, 0xe1, 0x61, 0xf7, 0x92, 0xf0, 0x1c, 0xde, 0xcf, 0xfe, 0x36, 0x89, 0x64, 0xec, - 0x6d, 0x5f, 0xc5, 0x86, 0x1b, 0xe9, 0x87, 0x0a, 0x5e, 0x7e, 0x79, 0x43, 0x90, 0xda, 0x77, 0x60, - 0x2a, 0x2d, 0x82, 0x31, 0x90, 0xc5, 0xf7, 0x51, 0xca, 0x1f, 0xe6, 0xb6, 0xfd, 0xf5, 0x64, 0xb3, - 0x76, 0x18, 0x53, 0xcf, 0x32, 0x65, 0x6f, 0x73, 0x29, 0x1d, 0x62, 0xfb, 0x06, 0x16, 0x53, 0x42, - 0x07, 0x22, 0xba, 0x0a, 0x23, 0x81, 0xea, 0x96, 0x4a, 0xad, 0x68, 0x8c, 0x26, 0xda, 0x09, 0xd4, - 0x3c, 0xd5, 0x96, 0xf3, 0x51, 0x78, 0x4b, 0xdd, 0x14, 0xb6, 0x8c, 0x1f, 0x93, 0xd9, 0x5e, 0x23, - 0x10, 0xc0, 0x77, 0xe1, 0x60, 0xdb, 0xf4, 0x98, 0x11, 0xce, 0x61, 0x88, 0xfb, 0xb8, 0x54, 0x88, - 0xe6, 0x9e, 0xe9, 0xb1, 0xa4, 0xd3, 0x03, 0xed, 0x74, 0x93, 0x76, 0x17, 0x31, 0x96, 0xdb, 0xe6, - 0x1a, 0xcd, 0xcb, 0xab, 0x67, 0x61, 0x8a, 0xff, 0xa3, 0x23, 0x9b, 0x8f, 0xf6, 0xf3, 0x76, 0x21, - 0xab, 0xd6, 0xc3, 0x24, 0x9d, 0xf5, 0x15, 0x55, 0x2a, 0x80, 0xce, 0xec, 0x55, 0x07, 0x49, 0x68, - 0xc5, 0x49, 0xc1, 0x1f, 0xee, 0x17, 0x58, 0xfe, 0x54, 0xf6, 0xaa, 0xa3, 0xd1, 0xf8, 0x74, 0x04, - 0x7d, 0xb4, 0xee, 0xb8, 0x8d, 0x5d, 0x17, 0xac, 0xbf, 0x51, 0x62, 0x65, 0x9c, 0x9c, 0x07, 0xa9, - 0x2c, 0xa7, 0xa8, 0x0c, 0xc9, 0x51, 0xc1, 0xbd, 0x19, 0x13, 0xda, 0xbd, 0x33, 0x58, 0x45, 0x7d, - 0x8a, 0xe1, 0xe7, 0xe9, 0x62, 0xc9, 0x6e, 0x70, 0x01, 0x28, 0x51, 0x16, 0x4f, 0xc3, 0x30, 0x97, - 0x9c, 0xa8, 0x61, 0x82, 0x07, 0x6d, 0x15, 0x93, 0x59, 0xbe, 0xd3, 0x1e, 0xcb, 0x3a, 0x34, 0xf8, - 0xb2, 0x0a, 0x77, 0x6b, 0x99, 0x17, 0xd3, 0xfc, 0x1f, 0x68, 0xbb, 0xbd, 0xaa, 0x9f, 0x2a, 0xe2, - 0xee, 0x11, 0xa6, 0x89, 0x84, 0xef, 0xa4, 0xf8, 0xff, 0xbb, 0x30, 0xd1, 0x1f, 0x0c, 0x13, 0xbd, - 0x68, 0x33, 0x51, 0x8b, 0x1f, 0x76, 0xf1, 0xbf, 0x0c, 0x4b, 0xb8, 0x8a, 0xcb, 0x94, 0x09, 0xb3, - 0x95, 0xfd, 0x7a, 0xb9, 0x15, 0x86, 0x23, 0xa9, 0x41, 0xfc, 0x70, 0x4c, 0x08, 0x1a, 0x44, 0x7b, - 0x2f, 0x2e, 0x40, 0x72, 0x5c, 0x20, 0xd5, 0xd7, 0x60, 0x42, 0xa4, 0x8a, 0x41, 0xcd, 0x65, 0x3a, - 0x2e, 0x30, 0xd5, 0xae, 0xc5, 0xd7, 0xb8, 0x30, 0xc6, 0xaf, 0xd3, 0x24, 0x36, 0x99, 0xf6, 0x83, - 0x5c, 0x76, 0x68, 0x8d, 0xc8, 0xde, 0x03, 0x22, 0x22, 0xe3, 0x25, 0x24, 0x45, 0x7c, 0x17, 0xfa, - 0xec, 0xaa, 0x94, 0xcb, 0xa9, 0x5a, 0xaa, 0x65, 0xf1, 0xc9, 0x3c, 0x0c, 0x73, 0x04, 0xe4, 0x13, - 0x05, 0x46, 0x82, 0xc2, 0x83, 0xe8, 0x85, 0x5e, 0xb3, 0x42, 0x4c, 0x7d, 0x59, 0xde, 0x20, 0x20, - 0xa5, 0x9d, 0xfa, 0xd1, 0xdf, 0xfe, 0xf3, 0x93, 0xbd, 0xc7, 0xc9, 0x8c, 0xee, 0x8f, 0xbf, 0xc0, - 0x4d, 0xf5, 0xd4, 0x3f, 0x63, 0xc9, 0x1f, 0x15, 0x18, 0x0d, 0x75, 0x11, 0xb9, 0xd8, 0x7f, 0x8e, - 0x94, 0x5a, 0x53, 0x17, 0x07, 0x31, 0x41, 0x60, 0x77, 0x39, 0xb0, 0xaf, 0x91, 0x72, 0x2e, 0xb0, - 0x48, 0x91, 0xe9, 0x5b, 0x19, 0x59, 0xb2, 0xad, 0x6f, 0x25, 0x74, 0xd3, 0x36, 0xf9, 0xbb, 0x02, - 0x24, 0xab, 0x6d, 0xc8, 0xd5, 0xfe, 0xb0, 0x7a, 0xea, 0x3a, 0xf5, 0xda, 0xce, 0x8c, 0x91, 0xdd, - 0x2d, 0xce, 0xee, 0x4d, 0x72, 0x3d, 0x97, 0x1d, 0x52, 0xaa, 0x75, 0x05, 0x56, 0x79, 0x44, 0xc9, - 0xcf, 0x15, 0x18, 0x17, 0x74, 0x06, 0xb9, 0xd0, 0x1f, 0x94, 0x30, 0x5c, 0x7d, 0x75, 0xa0, 0xe1, - 0x11, 0xf8, 0xb3, 0x1c, 0xfc, 0x29, 0x72, 0x32, 0x17, 0x7c, 0x54, 0x11, 0x78, 0x94, 0x91, 0x5f, - 0x29, 0xb0, 0x3f, 0x25, 0x5b, 0x64, 0x36, 0x50, 0xca, 0x44, 0x7d, 0x63, 0x60, 0x93, 0x08, 0xec, - 0x79, 0x0e, 0xf6, 0x25, 0xf2, 0x62, 0x2e, 0x58, 0x2f, 0x85, 0xed, 0x5f, 0x0a, 0x1c, 0xca, 0xd5, - 0x37, 0xe4, 0x46, 0x7f, 0x08, 0x45, 0xc2, 0x4a, 0x7d, 0x73, 0xc7, 0xf6, 0x48, 0xe4, 0x26, 0x27, - 0x72, 0x9d, 0x5c, 0xcd, 0x25, 0xd2, 0xa4, 0xcc, 0xa8, 0xb7, 0x2d, 0x6a, 0x33, 0x14, 0x3d, 0xc6, - 0xaa, 0xe3, 0x06, 0xff, 0xff, 0xd3, 0xb7, 0xc2, 0x5b, 0x6f, 0x9b, 0xfc, 0x5a, 0x81, 0xc9, 0xc4, - 0x34, 0xe4, 0xb5, 0x01, 0x71, 0x85, 0x7c, 0x5e, 0x1f, 0xd8, 0x4e, 0x6a, 0x41, 0x38, 0x8f, 0x58, - 0xba, 0x91, 0xcf, 0x94, 0x84, 0xac, 0x20, 0x72, 0xd3, 0x66, 0x65, 0x90, 0x7a, 0x79, 0x70, 0x43, - 0x04, 0xfc, 0x32, 0x07, 0xbc, 0x40, 0xe6, 0x73, 0x01, 0x0b, 0x42, 0x4c, 0xdf, 0xe2, 0xda, 0x6f, - 0xdb, 0xdf, 0xf5, 0xfb, 0x04, 0x4f, 0x4b, 0xed, 0xb6, 0x0c, 0xee, 0x5c, 0xf9, 0x26, 0x83, 0x3b, - 0x5f, 0x90, 0x69, 0xf3, 0x1c, 0xb7, 0x46, 0xe6, 0xfa, 0xe1, 0x26, 0x7f, 0x50, 0x60, 0x7f, 0x4a, - 0xab, 0xc8, 0x5c, 0x8e, 0x3d, 0x45, 0x95, 0xcc, 0xe5, 0xd8, 0x5b, 0x6e, 0x69, 0x17, 0x38, 0xf0, - 0x33, 0xe4, 0x74, 0x2e, 0xf0, 0xb4, 0x12, 0x23, 0x3f, 0x55, 0x60, 0x24, 0x50, 0x38, 0x64, 0x51, - 0x6a, 0xde, 0x84, 0xc8, 0x52, 0x2f, 0x0d, 0x64, 0x23, 0x95, 0x36, 0x03, 0x9d, 0x45, 0xfe, 0xac, - 0xc0, 0x81, 0x8c, 0x82, 0x22, 0x57, 0x24, 0xee, 0xb2, 0x1e, 0xc2, 0x4c, 0xbd, 0xba, 0x23, 0x5b, - 0xc4, 0xfc, 0x06, 0xc7, 0x7c, 0x89, 0x5c, 0x14, 0x31, 0x87, 0x5e, 0x84, 0x2b, 0xb1, 0xe5, 0x7c, - 0x94, 0x92, 0x75, 0xe4, 0xaf, 0x0a, 0x1c, 0xc8, 0xa8, 0x27, 0x19, 0x26, 0xbd, 0xe4, 0x9b, 0x0c, - 0x93, 0x9e, 0x72, 0xad, 0xcf, 0x55, 0x18, 0x94, 0xfc, 0xe9, 0xe4, 0x99, 0xd2, 0x8a, 0xdb, 0x7e, - 0x51, 0x43, 0x96, 0x29, 0x4b, 0xe9, 0x28, 0x22, 0x77, 0xde, 0x72, 0x24, 0x9e, 0x4c, 0x92, 0xea, - 0x21, 0xda, 0xb4, 0x45, 0x4e, 0xe8, 0x3c, 0x59, 0xe8, 0x79, 0x27, 0x9a, 0xed, 0xb6, 0x11, 0x70, - 0x70, 0x11, 0xe8, 0x97, 0x0a, 0x1c, 0xe2, 0xce, 0xbc, 0x94, 0xfc, 0x21, 0xd7, 0xa5, 0x63, 0x9b, - 0xa7, 0xc5, 0xd4, 0x1b, 0x3b, 0x35, 0x47, 0x32, 0x2b, 0x9c, 0x4c, 0x99, 0xbc, 0x55, 0xbc, 0x3a, - 0xc1, 0x11, 0x36, 0xed, 0x46, 0xf0, 0x46, 0x51, 0xc8, 0x52, 0xfa, 0x16, 0x6f, 0xd9, 0xf6, 0xef, - 0xa5, 0x68, 0x89, 0x04, 0x4d, 0xf3, 0xba, 0x64, 0xa0, 0xd3, 0x72, 0x4d, 0xbd, 0x3c, 0xb8, 0xe1, - 0x80, 0x0b, 0x24, 0x68, 0x34, 0xf2, 0x4f, 0x05, 0xa6, 0xf3, 0xa4, 0x8e, 0xcc, 0xfa, 0x14, 0xa8, - 0x2c, 0xf5, 0xc6, 0x4e, 0xcd, 0x91, 0x4b, 0x99, 0x73, 0xb9, 0x46, 0xae, 0xf4, 0xe4, 0x92, 0x90, - 0x39, 0xb5, 0x2e, 0x97, 0x73, 0xfe, 0x11, 0x0a, 0xa5, 0xdd, 0x36, 0xf9, 0xaf, 0x02, 0x6a, 0x8e, - 0x56, 0xc2, 0x2d, 0x41, 0xae, 0x0d, 0x0a, 0x51, 0xd4, 0x69, 0xea, 0xf5, 0x1d, 0x5a, 0x4b, 0x29, - 0x87, 0x0c, 0x3f, 0x2e, 0xe3, 0xe2, 0x0d, 0x69, 0x35, 0xc4, 0x7a, 0xe9, 0xc7, 0x0a, 0x0c, 0xf3, - 0xf7, 0x62, 0xa4, 0x24, 0x21, 0xad, 0x84, 0x17, 0x7d, 0xaa, 0x2e, 0x3d, 0x1e, 0x61, 0x6b, 0x1c, - 0xf6, 0x31, 0xa2, 0xe6, 0x2b, 0x31, 0x0e, 0x02, 0xcb, 0xb7, 0xf8, 0x65, 0xad, 0x64, 0xf9, 0x96, - 0x79, 0xe7, 0x2d, 0x59, 0xbe, 0x65, 0x5f, 0x72, 0x4b, 0x94, 0x6f, 0xcc, 0xf3, 0x42, 0xe9, 0x45, - 0x7e, 0xb6, 0x17, 0x66, 0x8b, 0xdf, 0x2e, 0x93, 0xe5, 0x01, 0x91, 0xf4, 0x7a, 0x57, 0xae, 0xae, - 0x7c, 0x75, 0x47, 0xc8, 0xb1, 0xc6, 0x39, 0x7e, 0x9b, 0x3c, 0x96, 0xe1, 0x68, 0xb4, 0xf8, 0x4b, - 0x68, 0xab, 0x6e, 0xb6, 0xf5, 0xad, 0xdc, 0x97, 0xf5, 0xdb, 0xfa, 0x56, 0xfa, 0x85, 0xfc, 0x36, - 0x79, 0xa2, 0xf0, 0x8f, 0x19, 0x64, 0x34, 0x7e, 0xe2, 0xdb, 0x08, 0x19, 0x8d, 0x9f, 0xfc, 0x6c, - 0x42, 0x9b, 0xe3, 0x74, 0x54, 0x72, 0x24, 0x97, 0x8e, 0x0f, 0xe2, 0x53, 0x05, 0x20, 0x7e, 0x9d, - 0x4e, 0x24, 0x4a, 0xa2, 0xcc, 0xfb, 0x7d, 0xf5, 0x95, 0xc1, 0x8c, 0x10, 0xdb, 0x19, 0x8e, 0xed, - 0x24, 0x39, 0x91, 0x8b, 0x8d, 0xc5, 0x98, 0x7e, 0xab, 0xc0, 0x54, 0xe2, 0x7b, 0x12, 0xbf, 0xaa, - 0x96, 0x4b, 0xb9, 0x79, 0x5f, 0x10, 0xa9, 0x57, 0x76, 0x62, 0x8a, 0xa0, 0x17, 0x38, 0xe8, 0x17, - 0x89, 0x96, 0x7f, 0x54, 0x13, 0x9f, 0xf9, 0xfc, 0x45, 0x81, 0xe9, 0xbc, 0x4f, 0x6b, 0x64, 0xb2, - 0x40, 0xc1, 0x17, 0x3d, 0x32, 0x59, 0xa0, 0xe8, 0x8b, 0x1e, 0xed, 0x55, 0xce, 0x41, 0x27, 0x17, - 0xfa, 0x73, 0x10, 0x2f, 0x44, 0x5f, 0x8f, 0x89, 0x5f, 0x7c, 0x49, 0xca, 0xc0, 0xcc, 0x47, 0x6e, - 0x92, 0x7a, 0x2c, 0xe7, 0xb3, 0xb5, 0x3e, 0x7a, 0xac, 0x1e, 0x5b, 0x24, 0xf4, 0x98, 0xe0, 0x49, - 0x5e, 0x8f, 0xed, 0x0c, 0x77, 0xfe, 0xe7, 0x76, 0x7d, 0xf4, 0x98, 0x80, 0xbb, 0x7c, 0xe7, 0xf3, - 0xa7, 0xb3, 0xca, 0x17, 0x4f, 0x67, 0x95, 0x2f, 0x9f, 0xce, 0x2a, 0x9f, 0x3c, 0x9b, 0xdd, 0xf3, - 0xc5, 0xb3, 0xd9, 0x3d, 0xff, 0x78, 0x36, 0xbb, 0xe7, 0xb1, 0xde, 0xb4, 0x58, 0x6b, 0xbd, 0x56, - 0xaa, 0x3b, 0x6b, 0xb9, 0x55, 0xfc, 0xa6, 0x70, 0x76, 0xba, 0x1d, 0xea, 0xd5, 0x46, 0xf8, 0x57, - 0x91, 0x97, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xb7, 0x2c, 0x68, 0xde, 0x2a, 0x00, 0x00, + // 2488 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcf, 0x6f, 0xdc, 0xc6, + 0x15, 0x36, 0xad, 0x48, 0x96, 0x9e, 0x7e, 0x58, 0x1e, 0xcb, 0xbf, 0x68, 0x5b, 0x96, 0xa9, 0x38, + 0x96, 0x15, 0x7b, 0x19, 0xcb, 0x49, 0xac, 0xd8, 0x56, 0x6c, 0xad, 0x6b, 0x4b, 0x76, 0x52, 0x5b, + 0xd9, 0x55, 0x9b, 0xc2, 0x69, 0xbb, 0xe5, 0xee, 0x8e, 0x76, 0xd9, 0xac, 0xc8, 0x0d, 0x39, 0x52, + 0xb4, 0x51, 0x85, 0x16, 0x3d, 0x06, 0x3d, 0x18, 0x28, 0xd0, 0xde, 0x8a, 0x5c, 0xda, 0x5b, 0x8b, + 0x22, 0x40, 0xd1, 0x02, 0x45, 0x0f, 0x3d, 0x35, 0x87, 0x1e, 0x52, 0x14, 0x28, 0xda, 0x4b, 0x1b, + 0xd8, 0xed, 0xff, 0x51, 0x70, 0xf8, 0x48, 0x0e, 0xb9, 0x5c, 0xee, 0xac, 0xb2, 0x39, 0x69, 0x39, + 0x33, 0xef, 0xcd, 0xf7, 0xbd, 0x79, 0x33, 0xf3, 0x3e, 0x91, 0x30, 0x65, 0x97, 0x5d, 0xea, 0x6c, + 0x53, 0x47, 0xff, 0x60, 0x8b, 0x3a, 0xad, 0x5c, 0xd3, 0xb1, 0x99, 0x4d, 0x4e, 0x7f, 0x44, 0x99, + 0x51, 0xa9, 0x1b, 0xa6, 0x95, 0xe3, 0xbf, 0x6c, 0x87, 0xe6, 0x82, 0x81, 0xea, 0xd1, 0x8a, 0xbd, + 0xb9, 0x69, 0x5b, 0xba, 0xff, 0xc7, 0xb7, 0x50, 0xe7, 0x2b, 0xb6, 0xbb, 0x69, 0xbb, 0x7a, 0xd9, + 0x70, 0xa9, 0xef, 0x4a, 0xdf, 0xbe, 0x5a, 0xa6, 0xcc, 0xb8, 0xaa, 0x37, 0x8d, 0x9a, 0x69, 0x19, + 0xcc, 0x0c, 0xc7, 0x4e, 0xd5, 0xec, 0x9a, 0xcd, 0x7f, 0xea, 0xde, 0x2f, 0x6c, 0x3d, 0x53, 0xb3, + 0xed, 0x5a, 0x83, 0xea, 0x46, 0xd3, 0xd4, 0x0d, 0xcb, 0xb2, 0x19, 0x37, 0x71, 0xb1, 0xf7, 0x58, + 0x88, 0xb3, 0x6c, 0x34, 0x1a, 0x36, 0x0b, 0x5c, 0x45, 0xcd, 0x0d, 0x63, 0x93, 0x62, 0xeb, 0x69, + 0xa1, 0xd5, 0xae, 0xbc, 0x5f, 0xaa, 0x53, 0xa3, 0x4a, 0x9d, 0xb6, 0x4e, 0x4e, 0xb0, 0x64, 0xd9, + 0x56, 0x85, 0x06, 0xd3, 0x9c, 0x8b, 0x3a, 0x1d, 0xdb, 0x75, 0xfd, 0x11, 0x1b, 0x0d, 0xa3, 0xd6, + 0x8e, 0xe3, 0x7d, 0xda, 0xaa, 0x51, 0xab, 0xcd, 0xa9, 0x65, 0x57, 0x69, 0xc9, 0xa8, 0x54, 0xec, + 0x2d, 0x2b, 0x00, 0x79, 0x22, 0xec, 0x0c, 0x7e, 0xb4, 0x39, 0x6b, 0x1a, 0x8e, 0xb1, 0x19, 0xcc, + 0x71, 0x36, 0x6a, 0xa6, 0x56, 0xd5, 0xb4, 0x6a, 0x71, 0x8c, 0x24, 0xec, 0x66, 0x2e, 0xb6, 0x69, + 0x0b, 0xa0, 0xbe, 0xe3, 0x05, 0x7d, 0x85, 0xb2, 0xbb, 0x1e, 0xe6, 0x47, 0xdc, 0xa0, 0x40, 0x3f, + 0xd8, 0xa2, 0x2e, 0x23, 0x53, 0x30, 0x68, 0x5a, 0x55, 0xba, 0x73, 0x52, 0x99, 0x51, 0xe6, 0x46, + 0x0a, 0xfe, 0x83, 0x66, 0xc3, 0xe9, 0x54, 0x1b, 0xb7, 0x69, 0x5b, 0x2e, 0x25, 0x6b, 0x30, 0x2a, + 0x34, 0x73, 0xd3, 0xd1, 0x85, 0xb9, 0x5c, 0x46, 0x66, 0xe4, 0x84, 0xf1, 0xf9, 0x17, 0x3e, 0xfb, + 0xf7, 0xb9, 0x03, 0x05, 0xd1, 0x85, 0x56, 0x45, 0x90, 0xcb, 0x8d, 0x46, 0x0a, 0xc8, 0xfb, 0x00, + 0x51, 0xa6, 0xe0, 0x74, 0x2f, 0xe5, 0xfc, 0xb4, 0xca, 0x79, 0x69, 0x95, 0xf3, 0x33, 0x14, 0xd3, + 0x2a, 0xb7, 0x66, 0xd4, 0x28, 0xda, 0x16, 0x04, 0x4b, 0xed, 0x0f, 0x0a, 0xf2, 0x4a, 0x4e, 0xd3, + 0x89, 0xd7, 0xc0, 0x97, 0xe4, 0x45, 0x56, 0x62, 0xc8, 0x0f, 0x72, 0xe4, 0x17, 0xbb, 0x22, 0xf7, + 0xe1, 0xc4, 0xa0, 0x6f, 0xc0, 0x99, 0x00, 0xf9, 0x9a, 0xbf, 0xf2, 0x5f, 0x4d, 0x88, 0xfe, 0xac, + 0xc0, 0xd9, 0x0e, 0x13, 0x61, 0x90, 0xde, 0x85, 0x89, 0x78, 0xee, 0x61, 0x9c, 0xe6, 0x33, 0xe3, + 0x14, 0xf3, 0x85, 0x91, 0x1a, 0x6f, 0x8a, 0x8d, 0xfd, 0x8b, 0xd5, 0x12, 0xcc, 0x70, 0x0a, 0xf1, + 0x39, 0x5b, 0x7c, 0x5d, 0x82, 0x78, 0x9d, 0x82, 0x61, 0x7f, 0x07, 0x9b, 0x55, 0x1e, 0xad, 0x81, + 0xc2, 0x21, 0xfe, 0xfc, 0xa0, 0xaa, 0xfd, 0x00, 0xce, 0x67, 0x98, 0x67, 0x44, 0x41, 0xe9, 0x43, + 0x14, 0xb4, 0x29, 0x20, 0xc1, 0xd6, 0x5b, 0x2f, 0x16, 0x11, 0xae, 0xf6, 0x18, 0x8e, 0xc6, 0x5a, + 0x11, 0xc5, 0x22, 0x0c, 0xac, 0x17, 0x8b, 0x38, 0xf5, 0x4c, 0xe6, 0xd4, 0xeb, 0xc5, 0x22, 0x4e, + 0xe8, 0x99, 0x68, 0xf7, 0xe0, 0x54, 0xe8, 0xd0, 0x75, 0x97, 0xab, 0x55, 0x87, 0xba, 0x61, 0x32, + 0xcd, 0xc1, 0x64, 0xd9, 0x64, 0x15, 0xdb, 0xb4, 0x4a, 0x61, 0x90, 0x0e, 0xf2, 0x20, 0x4d, 0x60, + 0xfb, 0x5d, 0x8c, 0xd5, 0x9d, 0xe8, 0x70, 0x11, 0xdd, 0x20, 0xbc, 0x49, 0x18, 0xa0, 0xac, 0x8e, + 0x47, 0x8b, 0xf7, 0xd3, 0x6b, 0x29, 0xb3, 0x0a, 0x77, 0x36, 0x52, 0xf0, 0x7e, 0x6a, 0x1f, 0x2b, + 0x30, 0xdf, 0xee, 0x22, 0xdf, 0xba, 0x6f, 0x5a, 0x46, 0xc3, 0xfc, 0x88, 0x56, 0x57, 0xa9, 0x59, + 0xab, 0xb3, 0x00, 0xda, 0x02, 0x1c, 0xdb, 0x08, 0x7a, 0x4a, 0x1e, 0xcb, 0x52, 0x9d, 0xf7, 0xe3, + 0x22, 0x1e, 0x0d, 0x3b, 0x9f, 0x50, 0x66, 0xf8, 0xa6, 0x3d, 0xd0, 0x79, 0x07, 0x5e, 0x96, 0xc2, + 0xd2, 0x03, 0xbf, 0xef, 0xc1, 0x71, 0xee, 0x72, 0xdd, 0x75, 0x57, 0x4d, 0x97, 0xd9, 0x4e, 0xab, + 0xdf, 0x5b, 0xf6, 0x97, 0x0a, 0x9c, 0x68, 0x9b, 0x02, 0x11, 0x2e, 0xc3, 0x30, 0x73, 0xdd, 0x52, + 0xc3, 0x74, 0x19, 0x6e, 0x53, 0xd9, 0x2c, 0x39, 0xc4, 0x5c, 0xf7, 0x6d, 0xd3, 0x65, 0xfd, 0xdb, + 0x96, 0xbf, 0x52, 0xe0, 0x88, 0xbf, 0xb1, 0x1c, 0x7b, 0x9b, 0x76, 0xdf, 0x88, 0xe4, 0x04, 0x1c, + 0x62, 0x3b, 0xa5, 0xba, 0xe1, 0xd6, 0x31, 0xa0, 0x43, 0x6c, 0x67, 0xd5, 0x70, 0xeb, 0x64, 0x16, + 0x06, 0x9b, 0x8e, 0x6d, 0x6f, 0x9c, 0x1c, 0xe0, 0x68, 0xc6, 0x73, 0x58, 0x6f, 0xac, 0x79, 0x8d, + 0x05, 0xbf, 0x8f, 0x9c, 0x05, 0xc0, 0x2b, 0xde, 0x73, 0xf0, 0x02, 0x77, 0x30, 0xc2, 0x5b, 0xb8, + 0x8f, 0x53, 0x30, 0xcc, 0x76, 0x4a, 0xfe, 0xdd, 0x37, 0xe8, 0xcf, 0xcb, 0x76, 0x1e, 0xf0, 0xdb, + 0x6f, 0x1e, 0xb7, 0x20, 0xe2, 0xc4, 0x50, 0x4e, 0xc1, 0xe0, 0xb6, 0xd1, 0x40, 0x94, 0xc3, 0x05, + 0xff, 0x21, 0xdc, 0xae, 0x6b, 0xfc, 0x96, 0x0e, 0xb6, 0xeb, 0xb7, 0x70, 0xbb, 0x06, 0xad, 0xe1, + 0x6a, 0x0c, 0xf9, 0xb7, 0x39, 0xae, 0xf6, 0x6c, 0xf6, 0x61, 0xc1, 0x87, 0xe2, 0x72, 0xa0, 0xa1, + 0x56, 0x87, 0x29, 0xee, 0x79, 0xd5, 0x70, 0xbf, 0x69, 0x33, 0x5a, 0x0d, 0xc2, 0xf8, 0x32, 0x1c, + 0xf1, 0xab, 0x9f, 0x92, 0x59, 0xa5, 0x16, 0x33, 0x37, 0x4c, 0xea, 0x60, 0x62, 0x4e, 0xfa, 0x1d, + 0x0f, 0xc2, 0x76, 0x32, 0x0b, 0xe3, 0xdb, 0x36, 0xa3, 0x4e, 0xc9, 0xf0, 0x33, 0x1c, 0xc3, 0x3b, + 0xc6, 0x1b, 0x31, 0xeb, 0xb5, 0x57, 0xe1, 0x58, 0x62, 0x26, 0x64, 0x71, 0x1a, 0x46, 0xea, 0x86, + 0x5b, 0xf2, 0x06, 0x07, 0xc1, 0x18, 0xae, 0xe3, 0x20, 0xed, 0xeb, 0x30, 0xcd, 0xad, 0xf2, 0x7c, + 0xce, 0x7c, 0x2b, 0x9a, 0x75, 0x3f, 0x48, 0x35, 0x06, 0x23, 0x9e, 0x5f, 0x87, 0x67, 0x62, 0x1b, + 0x6c, 0xa5, 0x1d, 0x36, 0xc9, 0xc3, 0x88, 0xf7, 0x5c, 0x62, 0xad, 0x26, 0xe5, 0xbc, 0x26, 0x16, + 0x2e, 0x64, 0x86, 0xd9, 0xf3, 0xbf, 0xde, 0x6a, 0xd2, 0xc2, 0xf0, 0x36, 0xfe, 0xd2, 0x7e, 0x7f, + 0x10, 0xce, 0x75, 0x64, 0x81, 0x51, 0xe8, 0x29, 0xe0, 0x6f, 0xc2, 0x10, 0x07, 0xe9, 0x45, 0x7a, + 0x80, 0x6f, 0xf3, 0x6e, 0x88, 0x38, 0xe3, 0x02, 0x5a, 0x91, 0x77, 0x61, 0xd2, 0xef, 0xe5, 0x3b, + 0xc9, 0xe7, 0x36, 0xc0, 0xb9, 0x5d, 0xce, 0xf4, 0xf4, 0x38, 0x32, 0xe2, 0x14, 0x0f, 0xdb, 0xf1, + 0x06, 0xf2, 0x08, 0xc6, 0x91, 0x85, 0xcb, 0x0c, 0xb6, 0xe5, 0xf2, 0x7d, 0x32, 0xb1, 0x70, 0x29, + 0xd3, 0xab, 0x1f, 0x95, 0x22, 0x37, 0x28, 0x8c, 0x95, 0x85, 0x27, 0x8d, 0xc0, 0x24, 0x0f, 0xdc, + 0x63, 0x1c, 0x5b, 0xa4, 0x4c, 0x5b, 0x84, 0x93, 0xc9, 0xb6, 0x30, 0x8a, 0x67, 0x60, 0x24, 0x70, + 0xeb, 0xd7, 0x11, 0x23, 0x85, 0xa8, 0x41, 0x3b, 0x8e, 0xc9, 0x5e, 0xdc, 0x6a, 0x36, 0x6d, 0x87, + 0xd1, 0x2a, 0x3f, 0xa7, 0x5d, 0xed, 0x1e, 0x16, 0x43, 0x89, 0xf6, 0xd0, 0xeb, 0x05, 0x18, 0xe2, + 0xd8, 0x83, 0xd2, 0x24, 0x3c, 0x20, 0xfc, 0x3b, 0x1c, 0x3b, 0xb5, 0xdb, 0xa0, 0xc5, 0xaa, 0x5c, + 0x7f, 0xc3, 0xdd, 0xb7, 0x1d, 0xd9, 0x4a, 0xc1, 0x81, 0xd9, 0x4c, 0x07, 0x08, 0xe7, 0x2d, 0x18, + 0xf3, 0x3d, 0xc4, 0x36, 0xbf, 0x44, 0x5d, 0x89, 0xc7, 0xc7, 0x68, 0x25, 0x7a, 0xd0, 0xce, 0x24, + 0xca, 0xf9, 0xf8, 0xc1, 0x63, 0x25, 0x0a, 0xf7, 0xc4, 0x01, 0xf4, 0x38, 0x15, 0xc9, 0x65, 0x59, + 0x24, 0x3c, 0x27, 0x63, 0x68, 0x04, 0x71, 0xf1, 0xc8, 0xae, 0xd2, 0x65, 0x5f, 0xdc, 0x64, 0x8b, + 0x8b, 0xef, 0x47, 0x18, 0x63, 0x36, 0x51, 0xb4, 0x44, 0xa1, 0x24, 0x15, 0x2d, 0xd1, 0xcf, 0xa8, + 0x15, 0x3d, 0x88, 0xba, 0x22, 0x05, 0x5f, 0xbf, 0x6e, 0xe0, 0x4f, 0x05, 0x5d, 0x91, 0x46, 0xe9, + 0x21, 0x8c, 0x0a, 0xcd, 0x52, 0xba, 0x22, 0xc6, 0x48, 0x78, 0xe8, 0xdf, 0x75, 0x3c, 0x83, 0x27, + 0xb5, 0x97, 0x2a, 0xa1, 0xa0, 0xbd, 0xef, 0xe9, 0xd9, 0x20, 0x99, 0x7e, 0xa4, 0xe0, 0x31, 0x98, + 0x36, 0x04, 0xa9, 0x7d, 0x07, 0x26, 0x93, 0x72, 0x58, 0x2e, 0xab, 0xe2, 0xfe, 0xf0, 0x96, 0x3b, + 0x5c, 0x89, 0x37, 0x6b, 0x27, 0xf0, 0x12, 0x5a, 0xa1, 0xec, 0x2d, 0x2e, 0xaa, 0x03, 0x6c, 0xdf, + 0xc0, 0xb2, 0x4a, 0xe8, 0x40, 0x44, 0x37, 0x61, 0xc8, 0xd7, 0xdf, 0x52, 0x97, 0x2c, 0x1a, 0xa3, + 0x89, 0x76, 0x0e, 0xd5, 0x4f, 0xb1, 0x6e, 0x7f, 0x18, 0x9c, 0x57, 0x77, 0x85, 0x94, 0xf1, 0x62, + 0x32, 0xdd, 0x69, 0x04, 0x02, 0xf8, 0x2e, 0x1c, 0x6d, 0x18, 0x2e, 0x2b, 0x05, 0x73, 0x94, 0xc4, + 0x3c, 0xce, 0x65, 0xa2, 0x79, 0xdb, 0x70, 0x59, 0xdc, 0xe9, 0x91, 0x46, 0xb2, 0x49, 0x7b, 0x88, + 0x18, 0xf3, 0x0d, 0x63, 0x93, 0xa6, 0xdd, 0xb0, 0x97, 0x60, 0x92, 0xff, 0xcb, 0xa3, 0xfd, 0x66, + 0x3a, 0xcc, 0xdb, 0x85, 0xfb, 0xb5, 0x12, 0x5c, 0xd7, 0xed, 0xbe, 0xc2, 0x9a, 0x05, 0xd0, 0x99, + 0xb5, 0x61, 0x23, 0x09, 0x2d, 0xfb, 0x7a, 0xf0, 0x86, 0x7b, 0xa5, 0x96, 0x37, 0x95, 0xb5, 0x61, + 0x6b, 0x34, 0xda, 0x1d, 0x7e, 0x1f, 0xad, 0xd8, 0x4e, 0xb5, 0xef, 0xd2, 0xf5, 0xb7, 0x4a, 0xa4, + 0x91, 0xe3, 0xf3, 0x20, 0x95, 0x95, 0x04, 0x95, 0x01, 0x39, 0x2a, 0x98, 0x9b, 0x11, 0xa1, 0xfe, + 0xed, 0xc1, 0x22, 0x2a, 0x55, 0x0c, 0x3f, 0x3f, 0x6a, 0x97, 0xad, 0x2a, 0x97, 0x82, 0x12, 0x05, + 0xf2, 0x14, 0x0c, 0x72, 0xf1, 0x89, 0x6a, 0xc6, 0x7f, 0xd0, 0x36, 0x50, 0xbf, 0xa6, 0x3b, 0xed, + 0xb0, 0xac, 0x03, 0xbd, 0x2f, 0xab, 0x70, 0xb6, 0xe6, 0x79, 0x59, 0xcd, 0xff, 0x95, 0xd6, 0xef, + 0x55, 0xfd, 0x44, 0x11, 0xb3, 0x47, 0x98, 0x26, 0x94, 0xc0, 0xe3, 0xe2, 0x7f, 0xf2, 0x82, 0x2b, + 0xff, 0x68, 0x70, 0xe5, 0x8b, 0x36, 0x63, 0xe5, 0xe8, 0xa1, 0x8f, 0xff, 0x6f, 0x58, 0xc6, 0x55, + 0x5c, 0xa1, 0x4c, 0x98, 0x2d, 0xef, 0x55, 0xce, 0xf5, 0x20, 0x1c, 0x71, 0x35, 0xe2, 0x85, 0x63, + 0x4c, 0x50, 0x23, 0xda, 0x7b, 0xb8, 0x66, 0xe9, 0x2e, 0x90, 0xea, 0xeb, 0x30, 0x26, 0x52, 0xc5, + 0xa0, 0xa6, 0x32, 0x1d, 0x15, 0x98, 0x6a, 0xb7, 0xa2, 0x63, 0x5c, 0x18, 0xe3, 0x55, 0x6c, 0x12, + 0x49, 0xa6, 0xfd, 0x30, 0x95, 0x1d, 0x5a, 0x23, 0xb2, 0xf7, 0x80, 0x88, 0xc8, 0x78, 0x31, 0x49, + 0x11, 0xdf, 0x95, 0x2e, 0x59, 0x95, 0x70, 0x39, 0x59, 0x4e, 0xb4, 0x2c, 0x3c, 0x9d, 0x83, 0x41, + 0x8e, 0x80, 0x3c, 0x55, 0x60, 0xc8, 0x2f, 0x3c, 0x88, 0x9e, 0xe9, 0xb5, 0x5d, 0x92, 0xa9, 0xaf, + 0xc8, 0x1b, 0xf8, 0xa4, 0xb4, 0xd9, 0x1f, 0xff, 0xfd, 0xbf, 0x3f, 0x3d, 0x78, 0x96, 0x9c, 0xd6, + 0xbd, 0xf1, 0x57, 0xb8, 0xa9, 0x9e, 0xf8, 0xb7, 0x2c, 0xf9, 0x93, 0x02, 0xc3, 0x81, 0x42, 0x22, + 0x57, 0xbb, 0xcf, 0x91, 0xd0, 0x6d, 0xea, 0x42, 0x2f, 0x26, 0x08, 0xec, 0x21, 0x07, 0xf6, 0x35, + 0x92, 0x4f, 0x05, 0x16, 0x6a, 0x33, 0x7d, 0xb7, 0x4d, 0xa0, 0xec, 0xe9, 0xbb, 0x31, 0x05, 0xb5, + 0x47, 0xfe, 0xa1, 0x00, 0x69, 0x57, 0x39, 0xe4, 0x66, 0x77, 0x58, 0x1d, 0x15, 0x9e, 0x7a, 0x6b, + 0x7f, 0xc6, 0xc8, 0xee, 0x1e, 0x67, 0x77, 0x9b, 0x2c, 0xa5, 0xb2, 0x43, 0x4a, 0xe5, 0x96, 0xc0, + 0x2a, 0x8d, 0x28, 0xf9, 0x85, 0x02, 0xa3, 0x82, 0xe2, 0x20, 0x57, 0xba, 0x83, 0x12, 0x86, 0xab, + 0xaf, 0xf5, 0x34, 0x3c, 0x04, 0x7f, 0x89, 0x83, 0x9f, 0x25, 0xe7, 0x53, 0xc1, 0x87, 0x15, 0x81, + 0x4b, 0x19, 0xf9, 0xb5, 0x02, 0x87, 0x13, 0x02, 0x46, 0x26, 0x81, 0x12, 0x26, 0xea, 0x1b, 0x3d, + 0x9b, 0x84, 0x60, 0x2f, 0x73, 0xb0, 0x2f, 0x91, 0x17, 0x53, 0xc1, 0xba, 0x09, 0x6c, 0xff, 0x51, + 0xe0, 0x78, 0xba, 0xd0, 0x21, 0xb7, 0xbb, 0x63, 0xc8, 0xd4, 0x58, 0xea, 0x9d, 0xfd, 0x3b, 0x40, + 0x2e, 0x79, 0xce, 0xe5, 0x16, 0xb9, 0x91, 0xca, 0xa5, 0x46, 0x59, 0x49, 0x14, 0x3e, 0xa5, 0x0d, + 0xdb, 0xf1, 0x1b, 0xf4, 0xdd, 0xe0, 0xdc, 0xdb, 0x23, 0x9f, 0x2a, 0x30, 0x11, 0x9f, 0x86, 0x5c, + 0xef, 0x15, 0x58, 0xc0, 0x68, 0xb1, 0x77, 0x43, 0x64, 0x72, 0x85, 0x33, 0xb9, 0x48, 0x2e, 0x48, + 0x31, 0xf1, 0x40, 0xc7, 0xf4, 0x81, 0x1c, 0xe2, 0x76, 0x31, 0x24, 0x89, 0x38, 0x45, 0xde, 0x68, + 0xaf, 0x70, 0xc4, 0xf3, 0x64, 0x2e, 0x15, 0xb1, 0x20, 0xc7, 0xf4, 0x5d, 0xae, 0x00, 0xf7, 0xbc, + 0xdc, 0x9f, 0x10, 0x3c, 0x2d, 0x37, 0x1a, 0x32, 0xb8, 0x53, 0x45, 0x9c, 0x0c, 0xee, 0x74, 0x59, + 0xa6, 0xcd, 0x71, 0xdc, 0x1a, 0x99, 0xe9, 0x86, 0x9b, 0xfc, 0x51, 0x81, 0xc3, 0x09, 0xc5, 0x22, + 0x73, 0x44, 0x76, 0x94, 0x56, 0x32, 0x47, 0x64, 0x67, 0xd1, 0xd5, 0x25, 0x45, 0x92, 0x7a, 0x8c, + 0xfc, 0x4c, 0x81, 0x21, 0x5f, 0xe7, 0x90, 0x05, 0xa9, 0x79, 0x63, 0x52, 0x4b, 0xbd, 0xd6, 0x93, + 0x8d, 0xd4, 0xe5, 0xe9, 0xab, 0x2d, 0xf2, 0x17, 0x05, 0x8e, 0xb4, 0xe9, 0x28, 0x72, 0x43, 0xe2, + 0x44, 0xeb, 0x20, 0xcf, 0xd4, 0x9b, 0xfb, 0xb2, 0x45, 0xcc, 0x6f, 0x70, 0xcc, 0xd7, 0xc8, 0x55, + 0x11, 0x73, 0xe0, 0x45, 0x38, 0x18, 0xeb, 0xf6, 0x87, 0x09, 0x71, 0x47, 0xfe, 0xa6, 0xc0, 0x91, + 0x36, 0x0d, 0x25, 0xc3, 0xa4, 0x93, 0x88, 0x93, 0x61, 0xd2, 0x51, 0xb4, 0x69, 0x77, 0x39, 0x93, + 0x25, 0x72, 0x33, 0xfd, 0x0e, 0xe5, 0x85, 0x7f, 0xf2, 0x0a, 0x4d, 0x28, 0xc6, 0x3d, 0xaf, 0xb4, + 0x21, 0x2b, 0x94, 0x25, 0xd4, 0x14, 0x91, 0xdb, 0x6f, 0x29, 0x42, 0x4f, 0xe6, 0xaa, 0xea, 0x20, + 0xdd, 0xb4, 0x05, 0x4e, 0xe8, 0x32, 0x99, 0xef, 0x78, 0x28, 0x1a, 0x8d, 0x46, 0xc9, 0xe7, 0xe0, + 0x20, 0xd0, 0x2f, 0x14, 0x38, 0xc6, 0x9d, 0xb9, 0x09, 0x11, 0x44, 0x96, 0xa4, 0x63, 0x9b, 0xa6, + 0xc8, 0xd4, 0x37, 0xf7, 0x6b, 0x8e, 0x64, 0x56, 0x39, 0x99, 0x3c, 0xb9, 0x93, 0xbd, 0x3a, 0xfe, + 0x16, 0x36, 0xac, 0xaa, 0xff, 0x86, 0x51, 0xb8, 0xa9, 0xf4, 0x5d, 0xde, 0xb2, 0xe7, 0x9d, 0x4b, + 0xe1, 0x12, 0x09, 0xca, 0xe6, 0xba, 0x64, 0xa0, 0x93, 0xa2, 0x4d, 0x5d, 0xec, 0xdd, 0xb0, 0xc7, + 0x05, 0x12, 0x94, 0x1a, 0xf9, 0x97, 0x02, 0x53, 0x69, 0x82, 0x47, 0x66, 0x7d, 0x32, 0xb4, 0x96, + 0xcc, 0xfa, 0x64, 0xe9, 0x2c, 0x89, 0x5a, 0x22, 0x26, 0x76, 0xca, 0x2d, 0x2e, 0xea, 0xbc, 0x2d, + 0x14, 0x08, 0xbc, 0x3d, 0xf2, 0x3f, 0x05, 0xd4, 0x14, 0xc5, 0x84, 0x29, 0x41, 0x6e, 0xf5, 0x0a, + 0x51, 0x54, 0x6b, 0xea, 0xd2, 0x3e, 0xad, 0xa5, 0xf4, 0x43, 0x1b, 0x3f, 0x2e, 0xe6, 0xa2, 0x84, + 0x34, 0xab, 0x62, 0xcd, 0xf4, 0x13, 0x05, 0x06, 0xf9, 0x7b, 0x32, 0x92, 0x93, 0x10, 0x58, 0xc2, + 0x8b, 0x3f, 0x55, 0x97, 0x1e, 0x8f, 0xb0, 0x35, 0x0e, 0xfb, 0x0c, 0x51, 0xd3, 0xf5, 0x18, 0x07, + 0xf1, 0x1b, 0x05, 0xc6, 0x63, 0x2f, 0x6f, 0xc9, 0xeb, 0x52, 0xb1, 0x6a, 0x7b, 0x07, 0xae, 0x5e, + 0xef, 0xd9, 0x4e, 0xaa, 0xaa, 0xf6, 0xa2, 0xcb, 0x5c, 0x37, 0x10, 0x60, 0xe4, 0xe7, 0x07, 0x61, + 0x3a, 0xfb, 0x6d, 0x33, 0x59, 0xe9, 0x11, 0x49, 0xa7, 0x77, 0xe7, 0xea, 0xea, 0x97, 0x77, 0x84, + 0x1c, 0xcb, 0x9c, 0xe3, 0xb7, 0xc9, 0x13, 0x19, 0x8e, 0xa5, 0x3a, 0x7f, 0x29, 0x6d, 0x56, 0x8c, + 0x86, 0xbe, 0x9b, 0xfa, 0xf2, 0x7e, 0x4f, 0xdf, 0x4d, 0xbe, 0xa0, 0xdf, 0x23, 0x1f, 0x2b, 0xfc, + 0xe3, 0x06, 0x19, 0xa5, 0x1f, 0xfb, 0x56, 0x42, 0x46, 0xe9, 0xc7, 0x3f, 0xa3, 0xd0, 0x66, 0x38, + 0x1d, 0x95, 0x9c, 0x4c, 0xa5, 0xe3, 0x81, 0xf8, 0x44, 0x01, 0x88, 0x5e, 0xaf, 0x13, 0x89, 0x92, + 0xa8, 0xed, 0x7d, 0xbf, 0xfa, 0x6a, 0x6f, 0x46, 0x88, 0xed, 0x22, 0xc7, 0x76, 0x9e, 0x9c, 0x4b, + 0xc5, 0xc6, 0x22, 0x4c, 0xbf, 0x53, 0x60, 0x32, 0xf6, 0x7d, 0x89, 0x57, 0x55, 0xcb, 0x5d, 0xb9, + 0x69, 0x5f, 0x14, 0xa9, 0x37, 0xf6, 0x63, 0x8a, 0xa0, 0xe7, 0x39, 0xe8, 0x17, 0x89, 0x96, 0xbe, + 0x55, 0x63, 0x9f, 0xfd, 0xfc, 0x55, 0x81, 0xa9, 0xb4, 0x4f, 0x6d, 0x64, 0x6e, 0x81, 0x8c, 0x2f, + 0x7c, 0x64, 0x6e, 0x81, 0xac, 0x2f, 0x7c, 0xb4, 0xd7, 0x38, 0x07, 0x9d, 0x5c, 0xe9, 0xce, 0x21, + 0x21, 0x22, 0x63, 0x5f, 0x80, 0xf5, 0xa0, 0x20, 0xe3, 0xf1, 0x5f, 0xec, 0xdd, 0x50, 0x4a, 0x8f, + 0x55, 0x22, 0x8b, 0x98, 0x1e, 0x13, 0x3c, 0xc9, 0xeb, 0xb1, 0xfd, 0xe1, 0x4e, 0xff, 0xfc, 0xae, + 0x8b, 0x1e, 0x13, 0x70, 0xe7, 0x1f, 0x7c, 0xf6, 0x6c, 0x5a, 0xf9, 0xfc, 0xd9, 0xb4, 0xf2, 0xc5, + 0xb3, 0x69, 0xe5, 0xe9, 0xf3, 0xe9, 0x03, 0x9f, 0x3f, 0x9f, 0x3e, 0xf0, 0xcf, 0xe7, 0xd3, 0x07, + 0x9e, 0xe8, 0x35, 0x93, 0xd5, 0xb7, 0xca, 0xb9, 0x8a, 0xbd, 0x99, 0x5a, 0xc5, 0xef, 0x08, 0x7b, + 0xa7, 0xd5, 0xa4, 0x6e, 0x79, 0x88, 0x7f, 0x25, 0x79, 0xed, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x07, 0xed, 0xea, 0x3d, 0xee, 0x2a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2792,10 +2791,10 @@ type QueryClient interface { // Queries a list of ObserversByChainAndType items. ObserverSet(ctx context.Context, in *QueryObserverSet, opts ...grpc.CallOption) (*QueryObserverSetResponse, error) SupportedChains(ctx context.Context, in *QuerySupportedChains, opts ...grpc.CallOption) (*QuerySupportedChainsResponse, error) - // Queries a list of GetClientParamsForChain items. - GetCoreParamsForChain(ctx context.Context, in *QueryGetCoreParamsForChainRequest, opts ...grpc.CallOption) (*QueryGetCoreParamsForChainResponse, error) - // Queries a list of GetCoreParams items. - GetCoreParams(ctx context.Context, in *QueryGetCoreParamsRequest, opts ...grpc.CallOption) (*QueryGetCoreParamsResponse, error) + // Queries a list of GetChainParamsForChain items. + GetChainParamsForChain(ctx context.Context, in *QueryGetChainParamsForChainRequest, opts ...grpc.CallOption) (*QueryGetChainParamsForChainResponse, error) + // Queries a list of GetChainParams items. + GetChainParams(ctx context.Context, in *QueryGetChainParamsRequest, opts ...grpc.CallOption) (*QueryGetChainParamsResponse, error) // Queries a nodeAccount by index. NodeAccount(ctx context.Context, in *QueryGetNodeAccountRequest, opts ...grpc.CallOption) (*QueryGetNodeAccountResponse, error) // Queries a list of nodeAccount items. @@ -2883,18 +2882,18 @@ func (c *queryClient) SupportedChains(ctx context.Context, in *QuerySupportedCha return out, nil } -func (c *queryClient) GetCoreParamsForChain(ctx context.Context, in *QueryGetCoreParamsForChainRequest, opts ...grpc.CallOption) (*QueryGetCoreParamsForChainResponse, error) { - out := new(QueryGetCoreParamsForChainResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetCoreParamsForChain", in, out, opts...) +func (c *queryClient) GetChainParamsForChain(ctx context.Context, in *QueryGetChainParamsForChainRequest, opts ...grpc.CallOption) (*QueryGetChainParamsForChainResponse, error) { + out := new(QueryGetChainParamsForChainResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetChainParamsForChain", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *queryClient) GetCoreParams(ctx context.Context, in *QueryGetCoreParamsRequest, opts ...grpc.CallOption) (*QueryGetCoreParamsResponse, error) { - out := new(QueryGetCoreParamsResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetCoreParams", in, out, opts...) +func (c *queryClient) GetChainParams(ctx context.Context, in *QueryGetChainParamsRequest, opts ...grpc.CallOption) (*QueryGetChainParamsResponse, error) { + out := new(QueryGetChainParamsResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/GetChainParams", in, out, opts...) if err != nil { return nil, err } @@ -3092,10 +3091,10 @@ type QueryServer interface { // Queries a list of ObserversByChainAndType items. ObserverSet(context.Context, *QueryObserverSet) (*QueryObserverSetResponse, error) SupportedChains(context.Context, *QuerySupportedChains) (*QuerySupportedChainsResponse, error) - // Queries a list of GetClientParamsForChain items. - GetCoreParamsForChain(context.Context, *QueryGetCoreParamsForChainRequest) (*QueryGetCoreParamsForChainResponse, error) - // Queries a list of GetCoreParams items. - GetCoreParams(context.Context, *QueryGetCoreParamsRequest) (*QueryGetCoreParamsResponse, error) + // Queries a list of GetChainParamsForChain items. + GetChainParamsForChain(context.Context, *QueryGetChainParamsForChainRequest) (*QueryGetChainParamsForChainResponse, error) + // Queries a list of GetChainParams items. + GetChainParams(context.Context, *QueryGetChainParamsRequest) (*QueryGetChainParamsResponse, error) // Queries a nodeAccount by index. NodeAccount(context.Context, *QueryGetNodeAccountRequest) (*QueryGetNodeAccountResponse, error) // Queries a list of nodeAccount items. @@ -3149,11 +3148,11 @@ func (*UnimplementedQueryServer) ObserverSet(ctx context.Context, req *QueryObse func (*UnimplementedQueryServer) SupportedChains(ctx context.Context, req *QuerySupportedChains) (*QuerySupportedChainsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SupportedChains not implemented") } -func (*UnimplementedQueryServer) GetCoreParamsForChain(ctx context.Context, req *QueryGetCoreParamsForChainRequest) (*QueryGetCoreParamsForChainResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetCoreParamsForChain not implemented") +func (*UnimplementedQueryServer) GetChainParamsForChain(ctx context.Context, req *QueryGetChainParamsForChainRequest) (*QueryGetChainParamsForChainResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChainParamsForChain not implemented") } -func (*UnimplementedQueryServer) GetCoreParams(ctx context.Context, req *QueryGetCoreParamsRequest) (*QueryGetCoreParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetCoreParams not implemented") +func (*UnimplementedQueryServer) GetChainParams(ctx context.Context, req *QueryGetChainParamsRequest) (*QueryGetChainParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChainParams not implemented") } func (*UnimplementedQueryServer) NodeAccount(ctx context.Context, req *QueryGetNodeAccountRequest) (*QueryGetNodeAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method NodeAccount not implemented") @@ -3310,38 +3309,38 @@ func _Query_SupportedChains_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -func _Query_GetCoreParamsForChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryGetCoreParamsForChainRequest) +func _Query_GetChainParamsForChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetChainParamsForChainRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).GetCoreParamsForChain(ctx, in) + return srv.(QueryServer).GetChainParamsForChain(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/zetachain.zetacore.observer.Query/GetCoreParamsForChain", + FullMethod: "/zetachain.zetacore.observer.Query/GetChainParamsForChain", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).GetCoreParamsForChain(ctx, req.(*QueryGetCoreParamsForChainRequest)) + return srv.(QueryServer).GetChainParamsForChain(ctx, req.(*QueryGetChainParamsForChainRequest)) } return interceptor(ctx, in, info, handler) } -func _Query_GetCoreParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryGetCoreParamsRequest) +func _Query_GetChainParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetChainParamsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).GetCoreParams(ctx, in) + return srv.(QueryServer).GetChainParams(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/zetachain.zetacore.observer.Query/GetCoreParams", + FullMethod: "/zetachain.zetacore.observer.Query/GetChainParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).GetCoreParams(ctx, req.(*QueryGetCoreParamsRequest)) + return srv.(QueryServer).GetChainParams(ctx, req.(*QueryGetChainParamsRequest)) } return interceptor(ctx, in, info, handler) } @@ -3731,12 +3730,12 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_SupportedChains_Handler, }, { - MethodName: "GetCoreParamsForChain", - Handler: _Query_GetCoreParamsForChain_Handler, + MethodName: "GetChainParamsForChain", + Handler: _Query_GetChainParamsForChain_Handler, }, { - MethodName: "GetCoreParams", - Handler: _Query_GetCoreParams_Handler, + MethodName: "GetChainParams", + Handler: _Query_GetChainParams_Handler, }, { MethodName: "NodeAccount", @@ -4842,7 +4841,7 @@ func (m *QuerySupportedChainsResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } -func (m *QueryGetCoreParamsForChainRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryGetChainParamsForChainRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4852,12 +4851,12 @@ func (m *QueryGetCoreParamsForChainRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryGetCoreParamsForChainRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsForChainRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetCoreParamsForChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsForChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4870,7 +4869,7 @@ func (m *QueryGetCoreParamsForChainRequest) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } -func (m *QueryGetCoreParamsForChainResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryGetChainParamsForChainResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4880,19 +4879,19 @@ func (m *QueryGetCoreParamsForChainResponse) Marshal() (dAtA []byte, err error) return dAtA[:n], nil } -func (m *QueryGetCoreParamsForChainResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsForChainResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetCoreParamsForChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsForChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.CoreParams != nil { + if m.ChainParams != nil { { - size, err := m.CoreParams.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ChainParams.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -4905,7 +4904,7 @@ func (m *QueryGetCoreParamsForChainResponse) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } -func (m *QueryGetCoreParamsRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryGetChainParamsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4915,12 +4914,12 @@ func (m *QueryGetCoreParamsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryGetCoreParamsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetCoreParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4928,7 +4927,7 @@ func (m *QueryGetCoreParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *QueryGetCoreParamsResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryGetChainParamsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4938,19 +4937,19 @@ func (m *QueryGetCoreParamsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryGetCoreParamsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetCoreParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryGetChainParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.CoreParams != nil { + if m.ChainParams != nil { { - size, err := m.CoreParams.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ChainParams.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -6140,7 +6139,7 @@ func (m *QuerySupportedChainsResponse) Size() (n int) { return n } -func (m *QueryGetCoreParamsForChainRequest) Size() (n int) { +func (m *QueryGetChainParamsForChainRequest) Size() (n int) { if m == nil { return 0 } @@ -6152,20 +6151,20 @@ func (m *QueryGetCoreParamsForChainRequest) Size() (n int) { return n } -func (m *QueryGetCoreParamsForChainResponse) Size() (n int) { +func (m *QueryGetChainParamsForChainResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.CoreParams != nil { - l = m.CoreParams.Size() + if m.ChainParams != nil { + l = m.ChainParams.Size() n += 1 + l + sovQuery(uint64(l)) } return n } -func (m *QueryGetCoreParamsRequest) Size() (n int) { +func (m *QueryGetChainParamsRequest) Size() (n int) { if m == nil { return 0 } @@ -6174,14 +6173,14 @@ func (m *QueryGetCoreParamsRequest) Size() (n int) { return n } -func (m *QueryGetCoreParamsResponse) Size() (n int) { +func (m *QueryGetChainParamsResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.CoreParams != nil { - l = m.CoreParams.Size() + if m.ChainParams != nil { + l = m.ChainParams.Size() n += 1 + l + sovQuery(uint64(l)) } return n @@ -9117,7 +9116,7 @@ func (m *QuerySupportedChainsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetChainParamsForChainRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9140,10 +9139,10 @@ func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetChainParamsForChainRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetChainParamsForChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -9186,7 +9185,7 @@ func (m *QueryGetCoreParamsForChainRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetChainParamsForChainResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9209,15 +9208,15 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetChainParamsForChainResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsForChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetChainParamsForChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9244,10 +9243,10 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CoreParams == nil { - m.CoreParams = &CoreParams{} + if m.ChainParams == nil { + m.ChainParams = &ChainParams{} } - if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ChainParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9272,7 +9271,7 @@ func (m *QueryGetCoreParamsForChainResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryGetChainParamsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9295,10 +9294,10 @@ func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetChainParamsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetChainParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -9322,7 +9321,7 @@ func (m *QueryGetCoreParamsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryGetChainParamsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9345,15 +9344,15 @@ func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryGetCoreParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryGetChainParamsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryGetCoreParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryGetChainParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9380,10 +9379,10 @@ func (m *QueryGetCoreParamsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CoreParams == nil { - m.CoreParams = &CoreParamsList{} + if m.ChainParams == nil { + m.ChainParams = &ChainParamsList{} } - if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ChainParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index 8d99fcea64..a58fb7ea00 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -217,8 +217,8 @@ func local_request_Query_SupportedChains_0(ctx context.Context, marshaler runtim } -func request_Query_GetCoreParamsForChain_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGetCoreParamsForChainRequest +func request_Query_GetChainParamsForChain_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetChainParamsForChainRequest var metadata runtime.ServerMetadata var ( @@ -239,13 +239,13 @@ func request_Query_GetCoreParamsForChain_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) } - msg, err := client.GetCoreParamsForChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.GetChainParamsForChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_GetCoreParamsForChain_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGetCoreParamsForChainRequest +func local_request_Query_GetChainParamsForChain_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetChainParamsForChainRequest var metadata runtime.ServerMetadata var ( @@ -266,25 +266,25 @@ func local_request_Query_GetCoreParamsForChain_0(ctx context.Context, marshaler return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) } - msg, err := server.GetCoreParamsForChain(ctx, &protoReq) + msg, err := server.GetChainParamsForChain(ctx, &protoReq) return msg, metadata, err } -func request_Query_GetCoreParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGetCoreParamsRequest +func request_Query_GetChainParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetChainParamsRequest var metadata runtime.ServerMetadata - msg, err := client.GetCoreParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.GetChainParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_GetCoreParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryGetCoreParamsRequest +func local_request_Query_GetChainParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetChainParamsRequest var metadata runtime.ServerMetadata - msg, err := server.GetCoreParams(ctx, &protoReq) + msg, err := server.GetChainParams(ctx, &protoReq) return msg, metadata, err } @@ -1246,7 +1246,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_GetCoreParamsForChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_GetChainParamsForChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -1257,7 +1257,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_GetCoreParamsForChain_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_GetChainParamsForChain_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -1265,11 +1265,11 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_GetCoreParamsForChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_GetChainParamsForChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_GetCoreParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_GetChainParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -1280,7 +1280,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_GetCoreParams_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_GetChainParams_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -1288,7 +1288,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_GetCoreParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_GetChainParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -1893,7 +1893,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_GetCoreParamsForChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_GetChainParamsForChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -1902,18 +1902,18 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_GetCoreParamsForChain_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_GetChainParamsForChain_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_GetCoreParamsForChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_GetChainParamsForChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_GetCoreParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_GetChainParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -1922,14 +1922,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_GetCoreParams_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_GetChainParams_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_GetCoreParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_GetChainParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2347,9 +2347,9 @@ var ( pattern_Query_SupportedChains_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "supportedChains"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_GetCoreParamsForChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "get_client_params_for_chain", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GetChainParamsForChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "get_chain_params_for_chain", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_GetCoreParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_core_params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GetChainParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_chain_params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_NodeAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "nodeAccount", "index"}, "", runtime.AssumeColonVerbOpt(false))) @@ -2403,9 +2403,9 @@ var ( forward_Query_SupportedChains_0 = runtime.ForwardResponseMessage - forward_Query_GetCoreParamsForChain_0 = runtime.ForwardResponseMessage + forward_Query_GetChainParamsForChain_0 = runtime.ForwardResponseMessage - forward_Query_GetCoreParams_0 = runtime.ForwardResponseMessage + forward_Query_GetChainParams_0 = runtime.ForwardResponseMessage forward_Query_NodeAccount_0 = runtime.ForwardResponseMessage diff --git a/x/observer/types/tx.pb.go b/x/observer/types/tx.pb.go index 43d63bdabe..bd9bceaf1e 100644 --- a/x/observer/types/tx.pb.go +++ b/x/observer/types/tx.pb.go @@ -246,23 +246,23 @@ func (m *MsgAddBlockHeaderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAddBlockHeaderResponse proto.InternalMessageInfo -type MsgUpdateCoreParams struct { - Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` - CoreParams *CoreParams `protobuf:"bytes,2,opt,name=coreParams,proto3" json:"coreParams,omitempty"` +type MsgUpdateChainParams struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ChainParams *ChainParams `protobuf:"bytes,2,opt,name=chainParams,proto3" json:"chainParams,omitempty"` } -func (m *MsgUpdateCoreParams) Reset() { *m = MsgUpdateCoreParams{} } -func (m *MsgUpdateCoreParams) String() string { return proto.CompactTextString(m) } -func (*MsgUpdateCoreParams) ProtoMessage() {} -func (*MsgUpdateCoreParams) Descriptor() ([]byte, []int) { +func (m *MsgUpdateChainParams) Reset() { *m = MsgUpdateChainParams{} } +func (m *MsgUpdateChainParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateChainParams) ProtoMessage() {} +func (*MsgUpdateChainParams) Descriptor() ([]byte, []int) { return fileDescriptor_1bcd40fa296a2b1d, []int{4} } -func (m *MsgUpdateCoreParams) XXX_Unmarshal(b []byte) error { +func (m *MsgUpdateChainParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgUpdateCoreParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgUpdateChainParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgUpdateCoreParams.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgUpdateChainParams.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -272,47 +272,47 @@ func (m *MsgUpdateCoreParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *MsgUpdateCoreParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgUpdateCoreParams.Merge(m, src) +func (m *MsgUpdateChainParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateChainParams.Merge(m, src) } -func (m *MsgUpdateCoreParams) XXX_Size() int { +func (m *MsgUpdateChainParams) XXX_Size() int { return m.Size() } -func (m *MsgUpdateCoreParams) XXX_DiscardUnknown() { - xxx_messageInfo_MsgUpdateCoreParams.DiscardUnknown(m) +func (m *MsgUpdateChainParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateChainParams.DiscardUnknown(m) } -var xxx_messageInfo_MsgUpdateCoreParams proto.InternalMessageInfo +var xxx_messageInfo_MsgUpdateChainParams proto.InternalMessageInfo -func (m *MsgUpdateCoreParams) GetCreator() string { +func (m *MsgUpdateChainParams) GetCreator() string { if m != nil { return m.Creator } return "" } -func (m *MsgUpdateCoreParams) GetCoreParams() *CoreParams { +func (m *MsgUpdateChainParams) GetChainParams() *ChainParams { if m != nil { - return m.CoreParams + return m.ChainParams } return nil } -type MsgUpdateCoreParamsResponse struct { +type MsgUpdateChainParamsResponse struct { } -func (m *MsgUpdateCoreParamsResponse) Reset() { *m = MsgUpdateCoreParamsResponse{} } -func (m *MsgUpdateCoreParamsResponse) String() string { return proto.CompactTextString(m) } -func (*MsgUpdateCoreParamsResponse) ProtoMessage() {} -func (*MsgUpdateCoreParamsResponse) Descriptor() ([]byte, []int) { +func (m *MsgUpdateChainParamsResponse) Reset() { *m = MsgUpdateChainParamsResponse{} } +func (m *MsgUpdateChainParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateChainParamsResponse) ProtoMessage() {} +func (*MsgUpdateChainParamsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_1bcd40fa296a2b1d, []int{5} } -func (m *MsgUpdateCoreParamsResponse) XXX_Unmarshal(b []byte) error { +func (m *MsgUpdateChainParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgUpdateCoreParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgUpdateChainParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgUpdateCoreParamsResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgUpdateChainParamsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -322,17 +322,105 @@ func (m *MsgUpdateCoreParamsResponse) XXX_Marshal(b []byte, deterministic bool) return b[:n], nil } } -func (m *MsgUpdateCoreParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgUpdateCoreParamsResponse.Merge(m, src) +func (m *MsgUpdateChainParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateChainParamsResponse.Merge(m, src) } -func (m *MsgUpdateCoreParamsResponse) XXX_Size() int { +func (m *MsgUpdateChainParamsResponse) XXX_Size() int { return m.Size() } -func (m *MsgUpdateCoreParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MsgUpdateCoreParamsResponse.DiscardUnknown(m) +func (m *MsgUpdateChainParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateChainParamsResponse.DiscardUnknown(m) } -var xxx_messageInfo_MsgUpdateCoreParamsResponse proto.InternalMessageInfo +var xxx_messageInfo_MsgUpdateChainParamsResponse proto.InternalMessageInfo + +type MsgRemoveChainParams struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + ChainId int64 `protobuf:"varint,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *MsgRemoveChainParams) Reset() { *m = MsgRemoveChainParams{} } +func (m *MsgRemoveChainParams) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveChainParams) ProtoMessage() {} +func (*MsgRemoveChainParams) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{6} +} +func (m *MsgRemoveChainParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveChainParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveChainParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRemoveChainParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveChainParams.Merge(m, src) +} +func (m *MsgRemoveChainParams) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveChainParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveChainParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveChainParams proto.InternalMessageInfo + +func (m *MsgRemoveChainParams) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgRemoveChainParams) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +type MsgRemoveChainParamsResponse struct { +} + +func (m *MsgRemoveChainParamsResponse) Reset() { *m = MsgRemoveChainParamsResponse{} } +func (m *MsgRemoveChainParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveChainParamsResponse) ProtoMessage() {} +func (*MsgRemoveChainParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1bcd40fa296a2b1d, []int{7} +} +func (m *MsgRemoveChainParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveChainParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveChainParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRemoveChainParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveChainParamsResponse.Merge(m, src) +} +func (m *MsgRemoveChainParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveChainParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveChainParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveChainParamsResponse proto.InternalMessageInfo type MsgAddObserver struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` @@ -345,7 +433,7 @@ func (m *MsgAddObserver) Reset() { *m = MsgAddObserver{} } func (m *MsgAddObserver) String() string { return proto.CompactTextString(m) } func (*MsgAddObserver) ProtoMessage() {} func (*MsgAddObserver) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{6} + return fileDescriptor_1bcd40fa296a2b1d, []int{8} } func (m *MsgAddObserver) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -409,7 +497,7 @@ func (m *MsgAddObserverResponse) Reset() { *m = MsgAddObserverResponse{} func (m *MsgAddObserverResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddObserverResponse) ProtoMessage() {} func (*MsgAddObserverResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{7} + return fileDescriptor_1bcd40fa296a2b1d, []int{9} } func (m *MsgAddObserverResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -448,7 +536,7 @@ func (m *MsgAddBlameVote) Reset() { *m = MsgAddBlameVote{} } func (m *MsgAddBlameVote) String() string { return proto.CompactTextString(m) } func (*MsgAddBlameVote) ProtoMessage() {} func (*MsgAddBlameVote) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{8} + return fileDescriptor_1bcd40fa296a2b1d, []int{10} } func (m *MsgAddBlameVote) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -505,7 +593,7 @@ func (m *MsgAddBlameVoteResponse) Reset() { *m = MsgAddBlameVoteResponse func (m *MsgAddBlameVoteResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddBlameVoteResponse) ProtoMessage() {} func (*MsgAddBlameVoteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{9} + return fileDescriptor_1bcd40fa296a2b1d, []int{11} } func (m *MsgAddBlameVoteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -546,7 +634,7 @@ func (m *MsgUpdateCrosschainFlags) Reset() { *m = MsgUpdateCrosschainFla func (m *MsgUpdateCrosschainFlags) String() string { return proto.CompactTextString(m) } func (*MsgUpdateCrosschainFlags) ProtoMessage() {} func (*MsgUpdateCrosschainFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{10} + return fileDescriptor_1bcd40fa296a2b1d, []int{12} } func (m *MsgUpdateCrosschainFlags) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -617,7 +705,7 @@ func (m *MsgUpdateCrosschainFlagsResponse) Reset() { *m = MsgUpdateCross func (m *MsgUpdateCrosschainFlagsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateCrosschainFlagsResponse) ProtoMessage() {} func (*MsgUpdateCrosschainFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{11} + return fileDescriptor_1bcd40fa296a2b1d, []int{13} } func (m *MsgUpdateCrosschainFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -655,7 +743,7 @@ func (m *MsgUpdateKeygen) Reset() { *m = MsgUpdateKeygen{} } func (m *MsgUpdateKeygen) String() string { return proto.CompactTextString(m) } func (*MsgUpdateKeygen) ProtoMessage() {} func (*MsgUpdateKeygen) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{12} + return fileDescriptor_1bcd40fa296a2b1d, []int{14} } func (m *MsgUpdateKeygen) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -705,7 +793,7 @@ func (m *MsgUpdateKeygenResponse) Reset() { *m = MsgUpdateKeygenResponse func (m *MsgUpdateKeygenResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateKeygenResponse) ProtoMessage() {} func (*MsgUpdateKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_1bcd40fa296a2b1d, []int{13} + return fileDescriptor_1bcd40fa296a2b1d, []int{15} } func (m *MsgUpdateKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -739,8 +827,10 @@ func init() { proto.RegisterType((*MsgUpdateObserverResponse)(nil), "zetachain.zetacore.observer.MsgUpdateObserverResponse") proto.RegisterType((*MsgAddBlockHeader)(nil), "zetachain.zetacore.observer.MsgAddBlockHeader") proto.RegisterType((*MsgAddBlockHeaderResponse)(nil), "zetachain.zetacore.observer.MsgAddBlockHeaderResponse") - proto.RegisterType((*MsgUpdateCoreParams)(nil), "zetachain.zetacore.observer.MsgUpdateCoreParams") - proto.RegisterType((*MsgUpdateCoreParamsResponse)(nil), "zetachain.zetacore.observer.MsgUpdateCoreParamsResponse") + proto.RegisterType((*MsgUpdateChainParams)(nil), "zetachain.zetacore.observer.MsgUpdateChainParams") + proto.RegisterType((*MsgUpdateChainParamsResponse)(nil), "zetachain.zetacore.observer.MsgUpdateChainParamsResponse") + proto.RegisterType((*MsgRemoveChainParams)(nil), "zetachain.zetacore.observer.MsgRemoveChainParams") + proto.RegisterType((*MsgRemoveChainParamsResponse)(nil), "zetachain.zetacore.observer.MsgRemoveChainParamsResponse") proto.RegisterType((*MsgAddObserver)(nil), "zetachain.zetacore.observer.MsgAddObserver") proto.RegisterType((*MsgAddObserverResponse)(nil), "zetachain.zetacore.observer.MsgAddObserverResponse") proto.RegisterType((*MsgAddBlameVote)(nil), "zetachain.zetacore.observer.MsgAddBlameVote") @@ -754,64 +844,66 @@ func init() { func init() { proto.RegisterFile("observer/tx.proto", fileDescriptor_1bcd40fa296a2b1d) } var fileDescriptor_1bcd40fa296a2b1d = []byte{ - // 903 bytes of a gzipped FileDescriptorProto + // 939 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0x36, 0xe3, 0xc4, 0xb1, 0xc7, 0xae, 0x63, 0x6f, 0xec, 0x58, 0x96, 0x6b, 0xc5, 0xe0, 0xa5, - 0x6e, 0xeb, 0x4a, 0x8e, 0xd2, 0x16, 0x6d, 0x81, 0x1e, 0xec, 0xfe, 0x38, 0x42, 0x91, 0xda, 0x20, - 0x50, 0x1f, 0x7a, 0x21, 0x96, 0xdc, 0x31, 0x45, 0x84, 0xda, 0x15, 0xb8, 0x54, 0x63, 0x15, 0x68, - 0xdf, 0xa0, 0x68, 0x5f, 0xa5, 0xef, 0xd0, 0x43, 0x8e, 0x39, 0xf6, 0x54, 0x14, 0xf6, 0xa9, 0x4f, - 0xd0, 0x6b, 0xc0, 0x5d, 0x72, 0x25, 0x4a, 0x32, 0x2d, 0xe5, 0x24, 0xee, 0xcc, 0x37, 0xdf, 0xcc, - 0x37, 0x33, 0xe4, 0x0a, 0xd6, 0x85, 0x27, 0x31, 0xfe, 0x09, 0xe3, 0x46, 0x72, 0x59, 0xef, 0xc6, - 0x22, 0x11, 0x64, 0xe7, 0x67, 0x4c, 0xa8, 0xdf, 0xa6, 0x21, 0xaf, 0xab, 0x27, 0x11, 0x63, 0x3d, - 0x47, 0x55, 0x1f, 0xfa, 0xa2, 0xd3, 0x11, 0xbc, 0xa1, 0x7f, 0x74, 0x44, 0x75, 0x23, 0x10, 0x81, - 0x50, 0x8f, 0x8d, 0xf4, 0x29, 0xb7, 0x1a, 0x6a, 0x2f, 0xa2, 0x1d, 0xcc, 0xac, 0x8f, 0x8d, 0xd5, - 0x8f, 0x85, 0x94, 0x2a, 0x8f, 0x7b, 0x11, 0xd1, 0x40, 0x66, 0x80, 0x2d, 0x03, 0xc8, 0x1f, 0x32, - 0xc7, 0xa6, 0x71, 0x74, 0x69, 0x4c, 0x3b, 0x39, 0x7e, 0x77, 0x60, 0x46, 0xce, 0x42, 0x1e, 0xb8, - 0x5c, 0x70, 0x1f, 0x73, 0x37, 0x19, 0x08, 0x94, 0x99, 0xcd, 0xfe, 0xcf, 0x82, 0xf5, 0xe7, 0x32, - 0xf8, 0xa1, 0xcb, 0x68, 0x82, 0xa7, 0x99, 0x9f, 0x54, 0xe0, 0xbe, 0x1f, 0x23, 0x4d, 0x44, 0x5c, - 0xb1, 0xf6, 0xac, 0xfd, 0x25, 0x27, 0x3f, 0x92, 0x43, 0xd8, 0x10, 0x11, 0x73, 0x73, 0x26, 0x97, - 0x32, 0x16, 0xa3, 0x94, 0x95, 0x3b, 0x0a, 0x46, 0x44, 0xc4, 0x72, 0x92, 0x23, 0xed, 0x49, 0x23, - 0x38, 0xbe, 0x1c, 0x8f, 0x98, 0xd7, 0x11, 0x1c, 0x5f, 0x8e, 0x46, 0x9c, 0xc3, 0x3b, 0x3d, 0x55, - 0x8f, 0x1b, 0x23, 0x95, 0x82, 0x57, 0xee, 0xee, 0x59, 0xfb, 0xab, 0xcd, 0x27, 0xf5, 0x92, 0x69, - 0xd4, 0x73, 0x12, 0xad, 0xc4, 0x51, 0x81, 0xce, 0x4a, 0x6f, 0xe8, 0x64, 0xef, 0xc0, 0xf6, 0x98, - 0x54, 0x07, 0x65, 0x57, 0x70, 0x89, 0xf6, 0x9f, 0xba, 0x11, 0x47, 0x8c, 0x1d, 0x47, 0xc2, 0x7f, - 0xf1, 0x0c, 0x29, 0x2b, 0x6d, 0xc4, 0x36, 0x2c, 0xea, 0x81, 0x85, 0x4c, 0x89, 0x9f, 0x77, 0xee, - 0xab, 0x73, 0x8b, 0x91, 0x5d, 0x00, 0x2f, 0xe5, 0x70, 0xdb, 0x54, 0xb6, 0x95, 0xce, 0x15, 0x67, - 0x49, 0x59, 0x9e, 0x51, 0xd9, 0x26, 0x8f, 0x60, 0xa1, 0x8d, 0x61, 0xd0, 0x4e, 0x94, 0xae, 0x79, - 0x27, 0x3b, 0x91, 0xc3, 0xd4, 0x9e, 0x66, 0xad, 0xdc, 0xdb, 0xb3, 0xf6, 0x97, 0x9b, 0xa4, 0x9e, - 0x6d, 0x96, 0xae, 0xe5, 0x6b, 0x9a, 0xd0, 0xe3, 0xbb, 0xaf, 0xfe, 0x79, 0x3c, 0xe7, 0x64, 0xb8, - 0x4c, 0x50, 0xb1, 0x64, 0x23, 0xe8, 0x12, 0x1e, 0x1a, 0xb5, 0x5f, 0x89, 0x18, 0xcf, 0xd4, 0xa6, - 0x94, 0x28, 0x3a, 0x01, 0xf0, 0x0d, 0x4e, 0x69, 0x5a, 0x6e, 0xbe, 0x57, 0xda, 0xf3, 0x01, 0xad, - 0x33, 0x14, 0x6a, 0xef, 0xc2, 0xce, 0x84, 0xcc, 0xa6, 0xb0, 0xbf, 0x2c, 0x58, 0xd5, 0x65, 0x4f, - 0xb1, 0x6f, 0xef, 0xc3, 0xda, 0x0d, 0xbb, 0xf6, 0x40, 0x8c, 0xac, 0xcd, 0x17, 0xb0, 0xad, 0x4a, - 0x8c, 0x42, 0xe4, 0x89, 0x1b, 0xc4, 0x94, 0x27, 0x88, 0x6e, 0xb7, 0xe7, 0xbd, 0xc0, 0x7e, 0xb6, - 0x6d, 0x5b, 0x03, 0xc0, 0x89, 0xf6, 0x9f, 0x29, 0x37, 0x79, 0x02, 0x9b, 0x94, 0x31, 0x97, 0x0b, - 0x86, 0x2e, 0xf5, 0x7d, 0xd1, 0xe3, 0x89, 0x2b, 0x78, 0xd4, 0x57, 0x23, 0x5a, 0x74, 0x08, 0x65, - 0xec, 0x7b, 0xc1, 0xf0, 0x48, 0xbb, 0x4e, 0x79, 0xd4, 0xb7, 0x2b, 0xf0, 0xa8, 0xa8, 0xc2, 0x08, - 0xfc, 0xdd, 0x82, 0x07, 0xf9, 0x5c, 0x68, 0x07, 0xcf, 0x45, 0x82, 0x6f, 0xb7, 0x48, 0x27, 0xe9, - 0x22, 0xd1, 0x0e, 0xba, 0x21, 0xbf, 0x10, 0x4a, 0xc2, 0x72, 0xd3, 0x2e, 0x9d, 0x88, 0x4a, 0x98, - 0x6d, 0xc9, 0x92, 0x8a, 0x6d, 0xf1, 0x0b, 0x61, 0x6f, 0xc3, 0xd6, 0x48, 0x41, 0xa6, 0xd8, 0xff, - 0xef, 0x40, 0x65, 0x30, 0x2d, 0xf3, 0x1d, 0xfa, 0x36, 0xfd, 0x0c, 0x95, 0x54, 0xfd, 0x01, 0xac, - 0x85, 0xb2, 0xc5, 0x3d, 0xd1, 0xe3, 0xec, 0x1b, 0x4e, 0xbd, 0x08, 0x99, 0x2a, 0x70, 0xd1, 0x19, - 0xb3, 0x93, 0x03, 0x58, 0x0f, 0xe5, 0x69, 0x2f, 0x29, 0x80, 0x75, 0x63, 0xc7, 0x1d, 0xa4, 0x0d, - 0x9b, 0x01, 0x95, 0x67, 0x71, 0xe8, 0x63, 0x8b, 0xa7, 0xe9, 0x24, 0xaa, 0x62, 0xb2, 0xb7, 0xa2, - 0x59, 0xaa, 0xff, 0x64, 0x52, 0xa4, 0x33, 0x99, 0x90, 0xfc, 0x02, 0xef, 0x7a, 0x83, 0x17, 0xe7, - 0x1c, 0xe3, 0xf0, 0x22, 0xf4, 0x69, 0x12, 0x0a, 0xad, 0xbe, 0xb2, 0xa0, 0x12, 0x7e, 0x7e, 0x4b, - 0xc3, 0x6f, 0x26, 0x70, 0x4a, 0xe9, 0x6d, 0x1b, 0xf6, 0x6e, 0x6a, 0xbc, 0x99, 0xce, 0x91, 0xda, - 0x24, 0x8d, 0xf9, 0x0e, 0xfb, 0x01, 0xf2, 0x92, 0x99, 0x6c, 0xc0, 0x3d, 0x95, 0x30, 0x5b, 0x23, - 0x7d, 0xc8, 0x66, 0x3f, 0x4c, 0x91, 0xb3, 0x37, 0xaf, 0x16, 0x60, 0xfe, 0xb9, 0x0c, 0x88, 0x80, - 0xe5, 0xe1, 0xb7, 0xf1, 0xc3, 0x52, 0xc5, 0xc5, 0xa5, 0xaf, 0x3e, 0x9d, 0x01, 0x9c, 0x27, 0x26, - 0x97, 0xb0, 0x3a, 0x72, 0xe3, 0xd4, 0x6f, 0xa3, 0x29, 0xe2, 0xab, 0x9f, 0xce, 0x86, 0x37, 0x99, - 0x7f, 0x85, 0xb5, 0xb1, 0x4f, 0xe2, 0xe1, 0x74, 0x5c, 0x83, 0x88, 0xea, 0x67, 0xb3, 0x46, 0x98, - 0xfc, 0x31, 0xac, 0x14, 0xbe, 0x0b, 0x07, 0x53, 0xb4, 0xcf, 0xa0, 0xab, 0x1f, 0xcf, 0x82, 0x36, - 0x39, 0x7f, 0xb3, 0x60, 0x73, 0xf2, 0xfb, 0xfd, 0xc9, 0x94, 0x3a, 0x8a, 0x61, 0xd5, 0x2f, 0xdf, - 0x2a, 0x6c, 0xb8, 0x07, 0x85, 0x8d, 0x3e, 0x98, 0x8e, 0x4e, 0xa3, 0x6f, 0xef, 0xc1, 0xa4, 0x55, - 0x4f, 0x37, 0x6e, 0xe4, 0x6a, 0xaf, 0x4f, 0xd5, 0x4b, 0x83, 0xbf, 0x7d, 0xe3, 0x26, 0xdf, 0xc3, - 0xc7, 0xad, 0x57, 0x57, 0x35, 0xeb, 0xf5, 0x55, 0xcd, 0xfa, 0xf7, 0xaa, 0x66, 0xfd, 0x71, 0x5d, - 0x9b, 0x7b, 0x7d, 0x5d, 0x9b, 0xfb, 0xfb, 0xba, 0x36, 0xf7, 0x63, 0x23, 0x08, 0x93, 0x76, 0xcf, - 0x4b, 0xaf, 0xf9, 0x46, 0xca, 0xf8, 0x91, 0x22, 0x6f, 0xe4, 0xe4, 0x8d, 0xcb, 0xc6, 0xe0, 0x0f, - 0x5b, 0xbf, 0x8b, 0xd2, 0x5b, 0x50, 0xff, 0xd9, 0x9e, 0xbe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xb7, - 0xd1, 0x06, 0xc3, 0xaa, 0x0a, 0x00, 0x00, + 0x10, 0x36, 0xe3, 0xc4, 0x3f, 0x23, 0xd7, 0x89, 0xb7, 0x76, 0x2c, 0x2b, 0x89, 0x62, 0xf0, 0xe4, + 0xb6, 0xae, 0x14, 0x2b, 0x6d, 0x81, 0x14, 0xe8, 0xc1, 0xee, 0x8f, 0xa3, 0x06, 0xa9, 0x0d, 0x02, + 0xf5, 0xa1, 0x17, 0x62, 0xc9, 0x1d, 0x53, 0x44, 0xa8, 0x5d, 0x81, 0x4b, 0x25, 0x56, 0xd1, 0x1e, + 0xfa, 0x00, 0x45, 0xfb, 0x2a, 0x7d, 0x87, 0x1e, 0x72, 0xcc, 0xb1, 0xa7, 0xa2, 0xb0, 0x4f, 0xed, + 0x0b, 0xf4, 0x1a, 0x70, 0x49, 0xae, 0x44, 0x51, 0xa2, 0xe4, 0x9c, 0xc4, 0xdd, 0xfd, 0xe6, 0x9b, + 0xf9, 0x66, 0xbf, 0x5d, 0x2d, 0x6c, 0x08, 0x47, 0x62, 0xf8, 0x12, 0xc3, 0x66, 0x74, 0xd1, 0xe8, + 0x85, 0x22, 0x12, 0xe4, 0xde, 0x8f, 0x18, 0x51, 0xb7, 0x43, 0x7d, 0xde, 0x50, 0x5f, 0x22, 0xc4, + 0x46, 0x86, 0xaa, 0xbd, 0xef, 0x8a, 0x6e, 0x57, 0xf0, 0x66, 0xf2, 0x93, 0x44, 0xd4, 0x36, 0x3d, + 0xe1, 0x09, 0xf5, 0xd9, 0x8c, 0xbf, 0xb2, 0x59, 0x4d, 0xed, 0x04, 0xb4, 0x8b, 0xe9, 0xec, 0x43, + 0x3d, 0xeb, 0x86, 0x42, 0x4a, 0x95, 0xc7, 0x3e, 0x0f, 0xa8, 0x27, 0x53, 0xc0, 0xb6, 0x06, 0x64, + 0x1f, 0xe9, 0xc2, 0x96, 0x5e, 0xe8, 0xd1, 0x90, 0x76, 0x33, 0xfc, 0x83, 0xe1, 0x34, 0x72, 0xe6, + 0x73, 0xcf, 0xe6, 0x82, 0xbb, 0x98, 0x2d, 0x93, 0xa1, 0x40, 0x99, 0xce, 0x99, 0xff, 0x1a, 0xb0, + 0xf1, 0x5c, 0x7a, 0xdf, 0xf7, 0x18, 0x8d, 0xf0, 0x24, 0x5d, 0x27, 0x55, 0x58, 0x76, 0x43, 0xa4, + 0x91, 0x08, 0xab, 0xc6, 0xae, 0xb1, 0xb7, 0x6a, 0x65, 0x43, 0xf2, 0x08, 0x36, 0x45, 0xc0, 0xec, + 0x8c, 0xc9, 0xa6, 0x8c, 0x85, 0x28, 0x65, 0xf5, 0x86, 0x82, 0x11, 0x11, 0xb0, 0x8c, 0xe4, 0x30, + 0x59, 0x89, 0x23, 0x38, 0xbe, 0x2a, 0x46, 0x2c, 0x26, 0x11, 0x1c, 0x5f, 0x8d, 0x47, 0x9c, 0xc1, + 0x7b, 0x7d, 0x55, 0x8f, 0x1d, 0x22, 0x95, 0x82, 0x57, 0x6f, 0xee, 0x1a, 0x7b, 0xeb, 0xad, 0x83, + 0x46, 0xc9, 0x6e, 0x34, 0x32, 0x92, 0x44, 0x89, 0xa5, 0x02, 0xad, 0xb5, 0xfe, 0xc8, 0xc8, 0xbc, + 0x07, 0x3b, 0x05, 0xa9, 0x16, 0xca, 0x9e, 0xe0, 0x12, 0xcd, 0x3f, 0x92, 0x46, 0x1c, 0x32, 0x76, + 0x14, 0x08, 0xf7, 0xc5, 0x53, 0xa4, 0xac, 0xb4, 0x11, 0x3b, 0xb0, 0x92, 0x6c, 0x98, 0xcf, 0x94, + 0xf8, 0x45, 0x6b, 0x59, 0x8d, 0xdb, 0x8c, 0x3c, 0x00, 0x70, 0x62, 0x0e, 0xbb, 0x43, 0x65, 0x47, + 0xe9, 0x5c, 0xb3, 0x56, 0xd5, 0xcc, 0x53, 0x2a, 0x3b, 0xe4, 0x2e, 0x2c, 0x75, 0xd0, 0xf7, 0x3a, + 0x91, 0xd2, 0xb5, 0x68, 0xa5, 0x23, 0xf2, 0x28, 0x9e, 0x8f, 0xb3, 0x56, 0x6f, 0xed, 0x1a, 0x7b, + 0x95, 0x16, 0x69, 0xa4, 0xce, 0x4a, 0x6a, 0xf9, 0x8a, 0x46, 0xf4, 0xe8, 0xe6, 0xeb, 0xbf, 0x1f, + 0x2e, 0x58, 0x29, 0x2e, 0x15, 0x94, 0x2f, 0x59, 0x0b, 0xfa, 0x09, 0x36, 0xb5, 0xda, 0x2f, 0xe3, + 0xca, 0x4e, 0x95, 0x55, 0x4a, 0x24, 0x7d, 0x0b, 0x15, 0x77, 0x08, 0x54, 0xaa, 0x2a, 0xad, 0xbd, + 0xd2, 0xae, 0x8f, 0x10, 0x5b, 0xa3, 0xc1, 0x66, 0x1d, 0xee, 0x4f, 0xca, 0xae, 0xab, 0x7b, 0xa6, + 0xaa, 0xb3, 0xb0, 0x2b, 0x5e, 0xce, 0x59, 0xdd, 0xf4, 0x86, 0xa7, 0xc9, 0x0a, 0x64, 0x3a, 0xd9, + 0x9f, 0x06, 0xac, 0x27, 0x8d, 0x9a, 0xc3, 0xe1, 0x1f, 0xc0, 0x9d, 0x29, 0xee, 0xbe, 0x2d, 0xc6, + 0x8c, 0xfa, 0x39, 0xec, 0xa8, 0x96, 0x04, 0x3e, 0xf2, 0xc8, 0xf6, 0x42, 0xca, 0x23, 0x44, 0xbb, + 0xd7, 0x77, 0x5e, 0xe0, 0x20, 0xf5, 0xf7, 0xf6, 0x10, 0x70, 0x9c, 0xac, 0x9f, 0xaa, 0x65, 0x72, + 0x00, 0x5b, 0x94, 0x31, 0x9b, 0x0b, 0x86, 0x36, 0x75, 0x5d, 0xd1, 0xe7, 0x91, 0x2d, 0x78, 0x30, + 0x50, 0xa6, 0x58, 0xb1, 0x08, 0x65, 0xec, 0x3b, 0xc1, 0xf0, 0x30, 0x59, 0x3a, 0xe1, 0xc1, 0xc0, + 0xac, 0xc2, 0xdd, 0xbc, 0x0a, 0x2d, 0xf0, 0x37, 0x03, 0x6e, 0x67, 0x4e, 0xa0, 0x5d, 0x3c, 0x13, + 0x11, 0xbe, 0x9b, 0x75, 0x8f, 0x63, 0xeb, 0xd2, 0x2e, 0xda, 0x3e, 0x3f, 0x17, 0x4a, 0x42, 0xa5, + 0x65, 0x96, 0x3a, 0x40, 0x25, 0x4c, 0x7d, 0xb9, 0xaa, 0x62, 0xdb, 0xfc, 0x5c, 0x98, 0x3b, 0xb0, + 0x3d, 0x56, 0x90, 0x2e, 0xf6, 0xff, 0x1b, 0x50, 0x1d, 0x7a, 0x43, 0xdf, 0x7c, 0xdf, 0xc4, 0x17, + 0x5f, 0x49, 0xd5, 0x1f, 0xc2, 0x1d, 0x5f, 0xb6, 0xb9, 0x23, 0xfa, 0x9c, 0x7d, 0xcd, 0xa9, 0x13, + 0x20, 0x53, 0x05, 0xae, 0x58, 0x85, 0x79, 0xb2, 0x0f, 0x1b, 0xbe, 0x3c, 0xe9, 0x47, 0x39, 0x70, + 0xd2, 0xd8, 0xe2, 0x02, 0xe9, 0xc0, 0x96, 0x47, 0xe5, 0x69, 0xe8, 0xbb, 0xd8, 0xe6, 0x71, 0x3a, + 0x89, 0xaa, 0x98, 0xf4, 0x1c, 0xb6, 0x4a, 0xf5, 0x1f, 0x4f, 0x8a, 0xb4, 0x26, 0x13, 0x92, 0x9f, + 0xe1, 0xbe, 0x33, 0x3c, 0xaa, 0x67, 0x18, 0xfa, 0xe7, 0xbe, 0x4b, 0x23, 0x5f, 0x24, 0xea, 0xab, + 0x4b, 0x2a, 0xe1, 0x93, 0x19, 0x0d, 0x9f, 0x4e, 0x60, 0x95, 0xd2, 0x9b, 0x26, 0xec, 0x4e, 0x6b, + 0xbc, 0xde, 0x9d, 0x43, 0xe5, 0xa4, 0x04, 0xf3, 0x0c, 0x07, 0x1e, 0xf2, 0x92, 0x3d, 0xd9, 0x84, + 0x5b, 0x2a, 0x61, 0x6a, 0xa3, 0x64, 0x90, 0xee, 0xfd, 0x28, 0x45, 0xc6, 0xde, 0xfa, 0x6f, 0x19, + 0x16, 0x9f, 0x4b, 0x8f, 0x08, 0xa8, 0x8c, 0x9e, 0xc6, 0x8f, 0x4a, 0x15, 0xe7, 0x4d, 0x5f, 0x7b, + 0x7c, 0x0d, 0x70, 0x96, 0x98, 0x5c, 0xc0, 0xfa, 0xd8, 0x7f, 0x5c, 0x63, 0x16, 0x4d, 0x1e, 0x5f, + 0xfb, 0xec, 0x7a, 0x78, 0x9d, 0xf9, 0x17, 0x03, 0x36, 0x8a, 0xb7, 0xf0, 0xc1, 0x7c, 0x6c, 0x23, + 0x21, 0xb5, 0x27, 0xd7, 0x0e, 0xc9, 0xd5, 0x50, 0xbc, 0x6b, 0x67, 0xd6, 0x50, 0x08, 0x99, 0x5d, + 0xc3, 0xd4, 0x4b, 0x98, 0x84, 0xb0, 0x96, 0xbb, 0x9f, 0xf6, 0xe7, 0xd8, 0x46, 0x8d, 0xae, 0x7d, + 0x72, 0x1d, 0xb4, 0xce, 0xf9, 0xab, 0x01, 0x5b, 0x93, 0xef, 0x99, 0x4f, 0xe7, 0x6c, 0x66, 0x3e, + 0xac, 0xf6, 0xc5, 0x3b, 0x85, 0x8d, 0xf6, 0x20, 0x77, 0xb2, 0xf6, 0xe7, 0xa3, 0x4b, 0xd0, 0xb3, + 0x7b, 0x30, 0xe9, 0xc8, 0xc5, 0xce, 0x1f, 0x7b, 0xd4, 0x34, 0xe6, 0xea, 0xa5, 0xc6, 0xcf, 0x76, + 0xfe, 0xe4, 0x17, 0xc8, 0x51, 0xfb, 0xf5, 0x65, 0xdd, 0x78, 0x73, 0x59, 0x37, 0xfe, 0xb9, 0xac, + 0x1b, 0xbf, 0x5f, 0xd5, 0x17, 0xde, 0x5c, 0xd5, 0x17, 0xfe, 0xba, 0xaa, 0x2f, 0xfc, 0xd0, 0xf4, + 0xfc, 0xa8, 0xd3, 0x77, 0xe2, 0x07, 0x4e, 0x33, 0x66, 0xfc, 0x58, 0x91, 0x37, 0x33, 0xf2, 0xe6, + 0x45, 0x73, 0xf8, 0x54, 0x1d, 0xf4, 0x50, 0x3a, 0x4b, 0xea, 0xb5, 0xfa, 0xf8, 0x6d, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x9f, 0xe7, 0x2f, 0x7d, 0xa4, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -828,7 +920,8 @@ const _ = grpc.SupportPackageIsVersion4 type MsgClient interface { AddObserver(ctx context.Context, in *MsgAddObserver, opts ...grpc.CallOption) (*MsgAddObserverResponse, error) UpdateObserver(ctx context.Context, in *MsgUpdateObserver, opts ...grpc.CallOption) (*MsgUpdateObserverResponse, error) - UpdateCoreParams(ctx context.Context, in *MsgUpdateCoreParams, opts ...grpc.CallOption) (*MsgUpdateCoreParamsResponse, error) + UpdateChainParams(ctx context.Context, in *MsgUpdateChainParams, opts ...grpc.CallOption) (*MsgUpdateChainParamsResponse, error) + RemoveChainParams(ctx context.Context, in *MsgRemoveChainParams, opts ...grpc.CallOption) (*MsgRemoveChainParamsResponse, error) AddBlameVote(ctx context.Context, in *MsgAddBlameVote, opts ...grpc.CallOption) (*MsgAddBlameVoteResponse, error) UpdateCrosschainFlags(ctx context.Context, in *MsgUpdateCrosschainFlags, opts ...grpc.CallOption) (*MsgUpdateCrosschainFlagsResponse, error) UpdateKeygen(ctx context.Context, in *MsgUpdateKeygen, opts ...grpc.CallOption) (*MsgUpdateKeygenResponse, error) @@ -861,9 +954,18 @@ func (c *msgClient) UpdateObserver(ctx context.Context, in *MsgUpdateObserver, o return out, nil } -func (c *msgClient) UpdateCoreParams(ctx context.Context, in *MsgUpdateCoreParams, opts ...grpc.CallOption) (*MsgUpdateCoreParamsResponse, error) { - out := new(MsgUpdateCoreParamsResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Msg/UpdateCoreParams", in, out, opts...) +func (c *msgClient) UpdateChainParams(ctx context.Context, in *MsgUpdateChainParams, opts ...grpc.CallOption) (*MsgUpdateChainParamsResponse, error) { + out := new(MsgUpdateChainParamsResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Msg/UpdateChainParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RemoveChainParams(ctx context.Context, in *MsgRemoveChainParams, opts ...grpc.CallOption) (*MsgRemoveChainParamsResponse, error) { + out := new(MsgRemoveChainParamsResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Msg/RemoveChainParams", in, out, opts...) if err != nil { return nil, err } @@ -910,7 +1012,8 @@ func (c *msgClient) AddBlockHeader(ctx context.Context, in *MsgAddBlockHeader, o type MsgServer interface { AddObserver(context.Context, *MsgAddObserver) (*MsgAddObserverResponse, error) UpdateObserver(context.Context, *MsgUpdateObserver) (*MsgUpdateObserverResponse, error) - UpdateCoreParams(context.Context, *MsgUpdateCoreParams) (*MsgUpdateCoreParamsResponse, error) + UpdateChainParams(context.Context, *MsgUpdateChainParams) (*MsgUpdateChainParamsResponse, error) + RemoveChainParams(context.Context, *MsgRemoveChainParams) (*MsgRemoveChainParamsResponse, error) AddBlameVote(context.Context, *MsgAddBlameVote) (*MsgAddBlameVoteResponse, error) UpdateCrosschainFlags(context.Context, *MsgUpdateCrosschainFlags) (*MsgUpdateCrosschainFlagsResponse, error) UpdateKeygen(context.Context, *MsgUpdateKeygen) (*MsgUpdateKeygenResponse, error) @@ -927,8 +1030,11 @@ func (*UnimplementedMsgServer) AddObserver(ctx context.Context, req *MsgAddObser func (*UnimplementedMsgServer) UpdateObserver(ctx context.Context, req *MsgUpdateObserver) (*MsgUpdateObserverResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateObserver not implemented") } -func (*UnimplementedMsgServer) UpdateCoreParams(ctx context.Context, req *MsgUpdateCoreParams) (*MsgUpdateCoreParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateCoreParams not implemented") +func (*UnimplementedMsgServer) UpdateChainParams(ctx context.Context, req *MsgUpdateChainParams) (*MsgUpdateChainParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateChainParams not implemented") +} +func (*UnimplementedMsgServer) RemoveChainParams(ctx context.Context, req *MsgRemoveChainParams) (*MsgRemoveChainParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveChainParams not implemented") } func (*UnimplementedMsgServer) AddBlameVote(ctx context.Context, req *MsgAddBlameVote) (*MsgAddBlameVoteResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddBlameVote not implemented") @@ -983,20 +1089,38 @@ func _Msg_UpdateObserver_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } -func _Msg_UpdateCoreParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgUpdateCoreParams) +func _Msg_UpdateChainParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateChainParams) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(MsgServer).UpdateCoreParams(ctx, in) + return srv.(MsgServer).UpdateChainParams(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/zetachain.zetacore.observer.Msg/UpdateCoreParams", + FullMethod: "/zetachain.zetacore.observer.Msg/UpdateChainParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).UpdateCoreParams(ctx, req.(*MsgUpdateCoreParams)) + return srv.(MsgServer).UpdateChainParams(ctx, req.(*MsgUpdateChainParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RemoveChainParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRemoveChainParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RemoveChainParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Msg/RemoveChainParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RemoveChainParams(ctx, req.(*MsgRemoveChainParams)) } return interceptor(ctx, in, info, handler) } @@ -1086,8 +1210,12 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Handler: _Msg_UpdateObserver_Handler, }, { - MethodName: "UpdateCoreParams", - Handler: _Msg_UpdateCoreParams_Handler, + MethodName: "UpdateChainParams", + Handler: _Msg_UpdateChainParams_Handler, + }, + { + MethodName: "RemoveChainParams", + Handler: _Msg_RemoveChainParams_Handler, }, { MethodName: "AddBlameVote", @@ -1262,7 +1390,7 @@ func (m *MsgAddBlockHeaderResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *MsgUpdateCoreParams) Marshal() (dAtA []byte, err error) { +func (m *MsgUpdateChainParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1272,19 +1400,19 @@ func (m *MsgUpdateCoreParams) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgUpdateCoreParams) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgUpdateChainParams) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgUpdateCoreParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgUpdateChainParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.CoreParams != nil { + if m.ChainParams != nil { { - size, err := m.CoreParams.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ChainParams.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1304,7 +1432,65 @@ func (m *MsgUpdateCoreParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *MsgUpdateCoreParamsResponse) Marshal() (dAtA []byte, err error) { +func (m *MsgUpdateChainParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateChainParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateChainParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRemoveChainParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgRemoveChainParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRemoveChainParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ChainId != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x10 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRemoveChainParamsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1314,12 +1500,12 @@ func (m *MsgUpdateCoreParamsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgUpdateCoreParamsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgRemoveChainParamsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgUpdateCoreParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgRemoveChainParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1705,7 +1891,7 @@ func (m *MsgAddBlockHeaderResponse) Size() (n int) { return n } -func (m *MsgUpdateCoreParams) Size() (n int) { +func (m *MsgUpdateChainParams) Size() (n int) { if m == nil { return 0 } @@ -1715,14 +1901,39 @@ func (m *MsgUpdateCoreParams) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - if m.CoreParams != nil { - l = m.CoreParams.Size() + if m.ChainParams != nil { + l = m.ChainParams.Size() n += 1 + l + sovTx(uint64(l)) } return n } -func (m *MsgUpdateCoreParamsResponse) Size() (n int) { +func (m *MsgUpdateChainParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRemoveChainParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.ChainId != 0 { + n += 1 + sovTx(uint64(m.ChainId)) + } + return n +} + +func (m *MsgRemoveChainParamsResponse) Size() (n int) { if m == nil { return 0 } @@ -2310,7 +2521,7 @@ func (m *MsgAddBlockHeaderResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { +func (m *MsgUpdateChainParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2333,10 +2544,10 @@ func (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgUpdateCoreParams: wiretype end group for non-group") + return fmt.Errorf("proto: MsgUpdateChainParams: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgUpdateCoreParams: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgUpdateChainParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2373,7 +2584,7 @@ func (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CoreParams", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainParams", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2400,13 +2611,164 @@ func (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.CoreParams == nil { - m.CoreParams = &CoreParams{} + if m.ChainParams == nil { + m.ChainParams = &ChainParams{} + } + if err := m.ChainParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateChainParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - if err := m.CoreParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateChainParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateChainParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { return err } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRemoveChainParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRemoveChainParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRemoveChainParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2428,7 +2790,7 @@ func (m *MsgUpdateCoreParams) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgUpdateCoreParamsResponse) Unmarshal(dAtA []byte) error { +func (m *MsgRemoveChainParamsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2451,10 +2813,10 @@ func (m *MsgUpdateCoreParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgUpdateCoreParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgRemoveChainParamsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgUpdateCoreParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgRemoveChainParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index e69f8d1a74..9a427a3701 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -61,7 +61,7 @@ type BitcoinChainClient struct { 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.CoreParams + params observertypes.ChainParams db *gorm.DB stop chan struct{} @@ -106,13 +106,13 @@ func (ob *BitcoinChainClient) WithChain(chain common.Chain) { ob.chain = chain } -func (ob *BitcoinChainClient) SetCoreParams(params observertypes.CoreParams) { +func (ob *BitcoinChainClient) SetChainParams(params observertypes.ChainParams) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.params = params } -func (ob *BitcoinChainClient) GetCoreParams() observertypes.CoreParams { +func (ob *BitcoinChainClient) GetChainParams() observertypes.ChainParams { ob.Mu.Lock() defer ob.Mu.Unlock() return ob.params @@ -150,7 +150,7 @@ func NewBitcoinClient( ob.includedTxHashes = make(map[string]uint64) ob.includedTxResults = make(map[string]btcjson.GetTransactionResult) ob.broadcastedTx = make(map[string]string) - ob.params = btcCfg.CoreParams + ob.params = btcCfg.ChainParams // initialize the Client ob.logger.ChainLogger.Info().Msgf("Chain %s endpoint %s", ob.chain.String(), btcCfg.RPCHost) @@ -253,7 +253,7 @@ func (ob *BitcoinChainClient) GetBaseGasPrice() *big.Int { } func (ob *BitcoinChainClient) WatchInTx() { - ticker, err := NewDynamicTicker("Bitcoin_WatchInTx", ob.GetCoreParams().InTxTicker) + ticker, err := NewDynamicTicker("Bitcoin_WatchInTx", ob.GetChainParams().InTxTicker) if err != nil { ob.logger.WatchInTx.Error().Err(err).Msg("WatchInTx error") return @@ -267,7 +267,7 @@ func (ob *BitcoinChainClient) WatchInTx() { if err != nil { ob.logger.WatchInTx.Error().Err(err).Msg("WatchInTx error observing in tx") } - ticker.UpdateInterval(ob.GetCoreParams().InTxTicker, ob.logger.WatchInTx) + ticker.UpdateInterval(ob.GetChainParams().InTxTicker, ob.logger.WatchInTx) case <-ob.stop: ob.logger.WatchInTx.Info().Msg("WatchInTx stopped") return @@ -332,7 +332,7 @@ func (ob *BitcoinChainClient) observeInTx() error { // skip if current height is too low // #nosec G701 always in range - confirmedBlockNum := cnt - int64(ob.GetCoreParams().ConfirmationCount) + confirmedBlockNum := cnt - int64(ob.GetChainParams().ConfirmationCount) if confirmedBlockNum < 0 { return fmt.Errorf("observeInTxBTC: skipping observer, current block number %d is too low", cnt) } @@ -492,7 +492,7 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 } func (ob *BitcoinChainClient) WatchGasPrice() { - ticker, err := NewDynamicTicker("Bitcoin_WatchGasPrice", ob.GetCoreParams().GasPriceTicker) + ticker, err := NewDynamicTicker("Bitcoin_WatchGasPrice", ob.GetChainParams().GasPriceTicker) if err != nil { ob.logger.WatchGasPrice.Error().Err(err).Msg("WatchGasPrice error") return @@ -506,7 +506,7 @@ func (ob *BitcoinChainClient) WatchGasPrice() { if err != nil { ob.logger.WatchGasPrice.Error().Err(err).Msg("PostGasPrice error on " + ob.chain.String()) } - ticker.UpdateInterval(ob.GetCoreParams().GasPriceTicker, ob.logger.WatchGasPrice) + ticker.UpdateInterval(ob.GetChainParams().GasPriceTicker, ob.logger.WatchGasPrice) case <-ob.stop: ob.logger.WatchGasPrice.Info().Msg("WatchGasPrice stopped") return @@ -717,7 +717,7 @@ func GetBtcEvent( } func (ob *BitcoinChainClient) WatchUTXOS() { - ticker, err := NewDynamicTicker("Bitcoin_WatchUTXOS", ob.GetCoreParams().WatchUtxoTicker) + ticker, err := NewDynamicTicker("Bitcoin_WatchUTXOS", ob.GetChainParams().WatchUtxoTicker) if err != nil { ob.logger.WatchUTXOS.Error().Err(err).Msg("WatchUTXOS error") return @@ -731,7 +731,7 @@ func (ob *BitcoinChainClient) WatchUTXOS() { if err != nil { ob.logger.WatchUTXOS.Error().Err(err).Msg("error fetching btc utxos") } - ticker.UpdateInterval(ob.GetCoreParams().WatchUtxoTicker, ob.logger.WatchUTXOS) + ticker.UpdateInterval(ob.GetChainParams().WatchUtxoTicker, ob.logger.WatchUTXOS) case <-ob.stop: ob.logger.WatchUTXOS.Info().Msg("WatchUTXOS stopped") return @@ -994,7 +994,7 @@ func (ob *BitcoinChainClient) GetCctxParams(nonce uint64) (types.OutboundTxParam } func (ob *BitcoinChainClient) observeOutTx() { - ticker, err := NewDynamicTicker("Bitcoin_observeOutTx", ob.GetCoreParams().OutTxTicker) + ticker, err := NewDynamicTicker("Bitcoin_observeOutTx", ob.GetChainParams().OutTxTicker) if err != nil { ob.logger.ObserveOutTx.Error().Err(err).Msg("observeOutTx: error creating ticker") return @@ -1032,7 +1032,7 @@ func (ob *BitcoinChainClient) observeOutTx() { } } } - ticker.UpdateInterval(ob.GetCoreParams().OutTxTicker, ob.logger.ObserveOutTx) + ticker.UpdateInterval(ob.GetChainParams().OutTxTicker, ob.logger.ObserveOutTx) case <-ob.stop: ob.logger.ObserveOutTx.Info().Msg("observeOutTx stopped") return diff --git a/zetaclient/config/types.go b/zetaclient/config/types.go index 8ae117f138..54ebccfce9 100644 --- a/zetaclient/config/types.go +++ b/zetaclient/config/types.go @@ -32,13 +32,13 @@ type ClientConfiguration struct { } type EVMConfig struct { - observertypes.CoreParams + observertypes.ChainParams Chain common.Chain Endpoint string } type BTCConfig struct { - observertypes.CoreParams + observertypes.ChainParams // the following are rpcclient ConnConfig fields RPCUsername string @@ -157,13 +157,13 @@ func (c *Config) GetKeyringBackend() KeyringBackend { return c.KeyringBackend } -// UpdateCoreParams updates core params for all chains +// UpdateChainParams updates core params for all chains // this must be the ONLY function that writes to core params -func (c *Config) UpdateCoreParams( +func (c *Config) UpdateChainParams( keygen *observertypes.Keygen, newChains []common.Chain, - evmCoreParams map[int64]*observertypes.CoreParams, - btcCoreParams *observertypes.CoreParams, + evmChainParams map[int64]*observertypes.ChainParams, + btcChainParams *observertypes.ChainParams, init bool, logger zerolog.Logger, ) { @@ -175,36 +175,45 @@ func (c *Config) UpdateCoreParams( return newChains[i].ChainId < newChains[j].ChainId }) if len(newChains) == 0 { - logger.Warn().Msg("UpdateCoreParams: No chains enabled in ZeroCore") + logger.Warn().Msg("UpdateChainParams: No chains enabled in ZeroCore") } // Add some warnings if chain list changes at runtime if !init { if len(c.ChainsEnabled) != len(newChains) { - logger.Warn().Msgf("UpdateCoreParams: ChainsEnabled changed at runtime!! current: %v, new: %v", c.ChainsEnabled, newChains) - } - for i, chain := range newChains { - if chain != c.ChainsEnabled[i] { - logger.Warn().Msgf("UpdateCoreParams: ChainsEnabled changed at runtime!! current: %v, new: %v", c.ChainsEnabled, newChains) + logger.Warn().Msgf( + "UpdateChainParams: ChainsEnabled changed at runtime!! current: %v, new: %v", + c.ChainsEnabled, + newChains, + ) + } else { + for i, chain := range newChains { + if chain != c.ChainsEnabled[i] { + logger.Warn().Msgf( + "UpdateChainParams: ChainsEnabled changed at runtime!! current: %v, new: %v", + c.ChainsEnabled, + newChains, + ) + } } } } c.Keygen = *keygen c.ChainsEnabled = newChains - // update core params for bitcoin if it has config in file - if c.BitcoinConfig != nil && btcCoreParams != nil { - c.BitcoinConfig.CoreParams = *btcCoreParams + // update chain params for bitcoin if it has config in file + if c.BitcoinConfig != nil && btcChainParams != nil { + c.BitcoinConfig.ChainParams = *btcChainParams } // update core params for evm chains we have configs in file - for _, params := range evmCoreParams { + for _, params := range evmChainParams { curCfg, found := c.EVMChainConfigs[params.ChainId] if found { - curCfg.CoreParams = *params + curCfg.ChainParams = *params } } } -// Make a separate (deep) copy of the config +// Clone makes a separate (deep) copy of the config func (c *Config) Clone() *Config { c.cfgLock.RLock() defer c.cfgLock.RUnlock() @@ -245,17 +254,17 @@ func (c *Config) Clone() *Config { return copied } -// ValidateCoreParams performs some basic checks on core params -func ValidateCoreParams(coreParams *observertypes.CoreParams) error { - if coreParams == nil { - return fmt.Errorf("invalid core params: nil") +// ValidateChainParams performs some basic checks on core params +func ValidateChainParams(chainParams *observertypes.ChainParams) error { + if chainParams == nil { + return fmt.Errorf("invalid chain params: nil") } - chain := common.GetChainFromChainID(coreParams.ChainId) + chain := common.GetChainFromChainID(chainParams.ChainId) if chain == nil { - return fmt.Errorf("invalid core params: chain %d not supported", coreParams.ChainId) + return fmt.Errorf("invalid chain params: chain %d not supported", chainParams.ChainId) } - if coreParams.ConfirmationCount < 1 { - return fmt.Errorf("invalid core params: ConfirmationCount %d", coreParams.ConfirmationCount) + if chainParams.ConfirmationCount < 1 { + return fmt.Errorf("invalid chain params: ConfirmationCount %d", chainParams.ConfirmationCount) } // zeta chain skips the rest of the checks for now if chain.IsZetaChain() { @@ -263,35 +272,35 @@ func ValidateCoreParams(coreParams *observertypes.CoreParams) error { } // check tickers - if coreParams.GasPriceTicker < 1 { - return fmt.Errorf("invalid core params: GasPriceTicker %d", coreParams.GasPriceTicker) + if chainParams.GasPriceTicker < 1 { + return fmt.Errorf("invalid chain params: GasPriceTicker %d", chainParams.GasPriceTicker) } - if coreParams.InTxTicker < 1 { - return fmt.Errorf("invalid core params: InTxTicker %d", coreParams.InTxTicker) + if chainParams.InTxTicker < 1 { + return fmt.Errorf("invalid chain params: InTxTicker %d", chainParams.InTxTicker) } - if coreParams.OutTxTicker < 1 { - return fmt.Errorf("invalid core params: OutTxTicker %d", coreParams.OutTxTicker) + if chainParams.OutTxTicker < 1 { + return fmt.Errorf("invalid chain params: OutTxTicker %d", chainParams.OutTxTicker) } - if coreParams.OutboundTxScheduleInterval < 1 { - return fmt.Errorf("invalid core params: OutboundTxScheduleInterval %d", coreParams.OutboundTxScheduleInterval) + if chainParams.OutboundTxScheduleInterval < 1 { + return fmt.Errorf("invalid chain params: OutboundTxScheduleInterval %d", chainParams.OutboundTxScheduleInterval) } - if coreParams.OutboundTxScheduleLookahead < 1 { - return fmt.Errorf("invalid core params: OutboundTxScheduleLookahead %d", coreParams.OutboundTxScheduleLookahead) + if chainParams.OutboundTxScheduleLookahead < 1 { + return fmt.Errorf("invalid chain params: OutboundTxScheduleLookahead %d", chainParams.OutboundTxScheduleLookahead) } // chain type specific checks - if common.IsBitcoinChain(coreParams.ChainId) && coreParams.WatchUtxoTicker < 1 { - return fmt.Errorf("invalid core params: watchUtxo ticker %d", coreParams.WatchUtxoTicker) + if common.IsBitcoinChain(chainParams.ChainId) && chainParams.WatchUtxoTicker < 1 { + return fmt.Errorf("invalid chain params: watchUtxo ticker %d", chainParams.WatchUtxoTicker) } - if common.IsEVMChain(coreParams.ChainId) { - if !validCoreContractAddress(coreParams.ZetaTokenContractAddress) { - return fmt.Errorf("invalid core params: zeta token contract address %s", coreParams.ZetaTokenContractAddress) + if common.IsEVMChain(chainParams.ChainId) { + if !validCoreContractAddress(chainParams.ZetaTokenContractAddress) { + return fmt.Errorf("invalid chain params: zeta token contract address %s", chainParams.ZetaTokenContractAddress) } - if !validCoreContractAddress(coreParams.ConnectorContractAddress) { - return fmt.Errorf("invalid core params: connector contract address %s", coreParams.ConnectorContractAddress) + if !validCoreContractAddress(chainParams.ConnectorContractAddress) { + return fmt.Errorf("invalid chain params: connector contract address %s", chainParams.ConnectorContractAddress) } - if !validCoreContractAddress(coreParams.Erc20CustodyContractAddress) { - return fmt.Errorf("invalid core params: erc20 custody contract address %s", coreParams.Erc20CustodyContractAddress) + if !validCoreContractAddress(chainParams.Erc20CustodyContractAddress) { + return fmt.Errorf("invalid chain params: erc20 custody contract address %s", chainParams.Erc20CustodyContractAddress) } } return nil diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 3cba7744da..005fa10260 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -85,7 +85,7 @@ type EVMChainClient struct { fileLogger *zerolog.Logger // for critical info logger EVMLog cfg *config.Config - params observertypes.CoreParams + params observertypes.ChainParams ts *TelemetryServer BlockCache *lru.Cache @@ -116,7 +116,7 @@ func NewEVMChainClient( ObserveOutTx: chainLogger.With().Str("module", "ObserveOutTx").Logger(), } ob.cfg = cfg - ob.params = evmCfg.CoreParams + ob.params = evmCfg.ChainParams ob.stop = make(chan struct{}) ob.chain = evmCfg.Chain ob.Mu = &sync.Mutex{} @@ -209,7 +209,7 @@ func (ob *EVMChainClient) WithZetaClient(bridge *ZetaCoreBridge) { ob.zetaClient = bridge } -func (ob *EVMChainClient) WithParams(params observertypes.CoreParams) { +func (ob *EVMChainClient) WithParams(params observertypes.ChainParams) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.params = params @@ -221,35 +221,35 @@ func (ob *EVMChainClient) SetConfig(cfg *config.Config) { ob.cfg = cfg } -func (ob *EVMChainClient) SetCoreParams(params observertypes.CoreParams) { +func (ob *EVMChainClient) SetChainParams(params observertypes.ChainParams) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.params = params } -func (ob *EVMChainClient) GetCoreParams() observertypes.CoreParams { +func (ob *EVMChainClient) GetChainParams() observertypes.ChainParams { ob.Mu.Lock() defer ob.Mu.Unlock() return ob.params } func (ob *EVMChainClient) GetConnectorContract() (*zetaconnector.ZetaConnectorNonEth, error) { - addr := ethcommon.HexToAddress(ob.GetCoreParams().ConnectorContractAddress) + addr := ethcommon.HexToAddress(ob.GetChainParams().ConnectorContractAddress) return FetchConnectorContract(addr, ob.evmClient) } func (ob *EVMChainClient) GetConnectorContractEth() (*zetaconnectoreth.ZetaConnectorEth, error) { - addr := ethcommon.HexToAddress(ob.GetCoreParams().ConnectorContractAddress) + addr := ethcommon.HexToAddress(ob.GetChainParams().ConnectorContractAddress) return FetchConnectorContractEth(addr, ob.evmClient) } func (ob *EVMChainClient) GetZetaTokenNonEthContract() (*zeta.ZetaNonEth, error) { - addr := ethcommon.HexToAddress(ob.GetCoreParams().ZetaTokenContractAddress) + addr := ethcommon.HexToAddress(ob.GetChainParams().ZetaTokenContractAddress) return FetchZetaZetaNonEthTokenContract(addr, ob.evmClient) } func (ob *EVMChainClient) GetERC20CustodyContract() (*erc20custody.ERC20Custody, error) { - addr := ethcommon.HexToAddress(ob.GetCoreParams().Erc20CustodyContractAddress) + addr := ethcommon.HexToAddress(ob.GetChainParams().Erc20CustodyContractAddress) return FetchERC20CustodyContract(addr, ob.evmClient) } @@ -299,7 +299,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co if !ob.isTxConfirmed(nonce) { return false, false, nil } - params := ob.GetCoreParams() + params := ob.GetChainParams() receipt, transaction := ob.GetTxNReceipt(nonce) sendID := fmt.Sprintf("%s-%d", ob.chain.String(), nonce) @@ -560,7 +560,7 @@ func (ob *EVMChainClient) observeOutTx() { } ob.logger.ObserveOutTx.Info().Msgf("observeOutTx using timeoutNonce %d seconds", timeoutNonce) - ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_observeOutTx_%d", ob.chain.ChainId), ob.GetCoreParams().OutTxTicker) + ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_observeOutTx_%d", ob.chain.ChainId), ob.GetChainParams().OutTxTicker) if err != nil { ob.logger.ObserveOutTx.Error().Err(err).Msg("failed to create ticker") return @@ -600,7 +600,7 @@ func (ob *EVMChainClient) observeOutTx() { } } } - ticker.UpdateInterval(ob.GetCoreParams().OutTxTicker, ob.logger.ObserveOutTx) + ticker.UpdateInterval(ob.GetChainParams().OutTxTicker, ob.logger.ObserveOutTx) case <-ob.stop: ob.logger.ObserveOutTx.Info().Msg("observeOutTx: stopped") return @@ -688,7 +688,7 @@ func (ob *EVMChainClient) confirmTxByHash(txHash string, nonce uint64) bool { log.Error().Msgf("confirmTxByHash: txHash %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) return false } - confHeight := receipt.BlockNumber.Uint64() + ob.GetCoreParams().ConfirmationCount + confHeight := receipt.BlockNumber.Uint64() + ob.GetChainParams().ConfirmationCount if confHeight >= math.MaxInt64 { log.Error().Msgf("confirmTxByHash: confHeight is too large for txHash %s nonce %d", txHash, nonce) return false @@ -735,7 +735,7 @@ func (ob *EVMChainClient) GetLastBlockHeight() uint64 { } func (ob *EVMChainClient) ExternalChainWatcher() { - ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_ExternalChainWatcher_%d", ob.chain.ChainId), ob.GetCoreParams().InTxTicker) + ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_ExternalChainWatcher_%d", ob.chain.ChainId), ob.GetChainParams().InTxTicker) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("NewDynamicTicker error") return @@ -751,7 +751,7 @@ func (ob *EVMChainClient) ExternalChainWatcher() { if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msg("observeInTX error") } - ticker.UpdateInterval(ob.GetCoreParams().InTxTicker, ob.logger.ExternalChainWatcher) + ticker.UpdateInterval(ob.GetChainParams().InTxTicker, ob.logger.ExternalChainWatcher) case <-ob.stop: ob.logger.ExternalChainWatcher.Info().Msg("ExternalChainWatcher stopped") return @@ -831,10 +831,10 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { counter.Inc() // skip if current height is too low - if header.Number.Uint64() < ob.GetCoreParams().ConfirmationCount { + if header.Number.Uint64() < ob.GetChainParams().ConfirmationCount { return fmt.Errorf("observeInTX: skipping observer, current block number %d is too low", header.Number.Uint64()) } - confirmedBlockNum := header.Number.Uint64() - ob.GetCoreParams().ConfirmationCount + confirmedBlockNum := header.Number.Uint64() - ob.GetChainParams().ConfirmationCount // skip if no new block is confirmed lastScanned := ob.GetLastBlockHeightScanned() @@ -1125,7 +1125,7 @@ func (ob *EVMChainClient) WatchGasPrice() { } } - ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_WatchGasPrice_%d", ob.chain.ChainId), ob.GetCoreParams().GasPriceTicker) + ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_WatchGasPrice_%d", ob.chain.ChainId), ob.GetChainParams().GasPriceTicker) if err != nil { ob.logger.WatchGasPrice.Error().Err(err).Msg("NewDynamicTicker error") return @@ -1144,7 +1144,7 @@ func (ob *EVMChainClient) WatchGasPrice() { ob.logger.WatchGasPrice.Error().Err(err).Msgf("PostGasPrice error at zeta block : %d ", height) } } - ticker.UpdateInterval(ob.GetCoreParams().GasPriceTicker, ob.logger.WatchGasPrice) + ticker.UpdateInterval(ob.GetChainParams().GasPriceTicker, ob.logger.WatchGasPrice) case <-ob.stop: ob.logger.WatchGasPrice.Info().Msg("WatchGasPrice stopped") return diff --git a/zetaclient/inbound_tracker.go b/zetaclient/inbound_tracker.go index 4a87eab268..e5c370b54f 100644 --- a/zetaclient/inbound_tracker.go +++ b/zetaclient/inbound_tracker.go @@ -16,7 +16,10 @@ import ( // ExternalChainWatcherForNewInboundTrackerSuggestions At each tick, gets a list of Inbound tracker suggestions from zeta-core and tries to check if the in-tx was confirmed. // If it was, it tries to broadcast the confirmation vote. If this zeta client has previously broadcast the vote, the tx would be rejected func (ob *EVMChainClient) ExternalChainWatcherForNewInboundTrackerSuggestions() { - ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_ExternalChainWatcher_InboundTrackerSuggestions_%d", ob.chain.ChainId), ob.GetCoreParams().InTxTicker) + ticker, err := NewDynamicTicker( + fmt.Sprintf("EVM_ExternalChainWatcher_InboundTrackerSuggestions_%d", ob.chain.ChainId), + ob.GetChainParams().InTxTicker, + ) if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msg("error creating ticker") return @@ -31,7 +34,7 @@ func (ob *EVMChainClient) ExternalChainWatcherForNewInboundTrackerSuggestions() if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msg("ObserveTrackerSuggestions error") } - ticker.UpdateInterval(ob.GetCoreParams().InTxTicker, ob.logger.ExternalChainWatcher) + ticker.UpdateInterval(ob.GetChainParams().InTxTicker, ob.logger.ExternalChainWatcher) case <-ob.stop: ob.logger.ExternalChainWatcher.Info().Msg("ExternalChainWatcher for inboundTrackerSuggestions stopped") return @@ -40,7 +43,7 @@ func (ob *EVMChainClient) ExternalChainWatcherForNewInboundTrackerSuggestions() } func (ob *BitcoinChainClient) ExternalChainWatcherForNewInboundTrackerSuggestions() { - ticker, err := NewDynamicTicker("Bitcoin_WatchInTx_InboundTrackerSuggestions", ob.GetCoreParams().InTxTicker) + ticker, err := NewDynamicTicker("Bitcoin_WatchInTx_InboundTrackerSuggestions", ob.GetChainParams().InTxTicker) if err != nil { ob.logger.WatchInTx.Err(err).Msg("error creating ticker") return @@ -54,7 +57,7 @@ func (ob *BitcoinChainClient) ExternalChainWatcherForNewInboundTrackerSuggestion if err != nil { ob.logger.WatchInTx.Error().Err(err).Msg("error observing in tx") } - ticker.UpdateInterval(ob.GetCoreParams().InTxTicker, ob.logger.WatchInTx) + ticker.UpdateInterval(ob.GetChainParams().InTxTicker, ob.logger.WatchInTx) case <-ob.stop: ob.logger.WatchInTx.Info().Msg("ExternalChainWatcher for BTC inboundTrackerSuggestions stopped") return diff --git a/zetaclient/interfaces.go b/zetaclient/interfaces.go index 30ef360930..fe2d0824c1 100644 --- a/zetaclient/interfaces.go +++ b/zetaclient/interfaces.go @@ -26,8 +26,8 @@ type ChainClient interface { Start() Stop() IsSendOutTxProcessed(sendHash string, nonce uint64, cointype common.CoinType, logger zerolog.Logger) (bool, bool, error) - SetCoreParams(observertypes.CoreParams) - GetCoreParams() observertypes.CoreParams + SetChainParams(observertypes.ChainParams) + GetChainParams() observertypes.ChainParams GetPromGauge(name string) (prometheus.Gauge, error) GetPromCounter(name string) (prometheus.Counter, error) GetTxID(nonce uint64) string diff --git a/zetaclient/query.go b/zetaclient/query.go index edc6e76d0e..99131ce6fc 100644 --- a/zetaclient/query.go +++ b/zetaclient/query.go @@ -39,37 +39,28 @@ func (b *ZetaCoreBridge) GetCrosschainFlags() (observertypes.CrosschainFlags, er return resp.CrosschainFlags, nil } -func (b *ZetaCoreBridge) GetCoreParamsForChainID(externalChainID int64) (*observertypes.CoreParams, error) { +func (b *ZetaCoreBridge) GetChainParamsForChainID(externalChainID int64) (*observertypes.ChainParams, error) { client := observertypes.NewQueryClient(b.grpcConn) - resp, err := client.GetCoreParamsForChain(context.Background(), &observertypes.QueryGetCoreParamsForChainRequest{ChainId: externalChainID}) + resp, err := client.GetChainParamsForChain(context.Background(), &observertypes.QueryGetChainParamsForChainRequest{ChainId: externalChainID}) if err != nil { - return &observertypes.CoreParams{}, err + return &observertypes.ChainParams{}, err } - return resp.CoreParams, nil + return resp.ChainParams, nil } -func (b *ZetaCoreBridge) GetCoreParams() ([]*observertypes.CoreParams, error) { +func (b *ZetaCoreBridge) GetChainParams() ([]*observertypes.ChainParams, error) { client := observertypes.NewQueryClient(b.grpcConn) var err error - resp := &observertypes.QueryGetCoreParamsResponse{} + resp := &observertypes.QueryGetChainParamsResponse{} for i := 0; i <= DefaultRetryCount; i++ { - resp, err = client.GetCoreParams(context.Background(), &observertypes.QueryGetCoreParamsRequest{}) + resp, err = client.GetChainParams(context.Background(), &observertypes.QueryGetChainParamsRequest{}) if err == nil { - return resp.CoreParams.CoreParams, nil + return resp.ChainParams.ChainParams, nil } time.Sleep(DefaultRetryInterval * time.Second) } - return nil, fmt.Errorf("failed to get core params | err %s", err.Error()) -} - -func (b *ZetaCoreBridge) GetObserverParams() (observertypes.Params, error) { - client := observertypes.NewQueryClient(b.grpcConn) - resp, err := client.Params(context.Background(), &observertypes.QueryParamsRequest{}) - if err != nil { - return observertypes.Params{}, err - } - return resp.Params, nil + return nil, fmt.Errorf("failed to get chain params | err %s", err.Error()) } func (b *ZetaCoreBridge) GetUpgradePlan() (*upgradetypes.Plan, error) { @@ -375,15 +366,6 @@ func (b *ZetaCoreBridge) GetAllOutTxTrackerByChain(chainID int64, order Order) ( return resp.OutTxTracker, nil } -func (b *ZetaCoreBridge) GetClientParams(chainID int64) (observertypes.QueryGetCoreParamsForChainResponse, error) { - client := observertypes.NewQueryClient(b.grpcConn) - resp, err := client.GetCoreParamsForChain(context.Background(), &observertypes.QueryGetCoreParamsForChainRequest{ChainId: chainID}) - if err != nil { - return observertypes.QueryGetCoreParamsForChainResponse{}, err - } - return *resp, nil -} - func (b *ZetaCoreBridge) GetPendingNoncesByChain(chainID int64) (observertypes.PendingNonces, error) { client := observertypes.NewQueryClient(b.grpcConn) resp, err := client.PendingNoncesByChain(context.Background(), &observertypes.QueryPendingNoncesByChainRequest{ChainId: chainID}) diff --git a/zetaclient/zetacore_bridge.go b/zetaclient/zetacore_bridge.go index 3540a0dc70..0a2b3b08c4 100644 --- a/zetaclient/zetacore_bridge.go +++ b/zetaclient/zetacore_bridge.go @@ -200,24 +200,27 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err b.pause <- struct{}{} // notify CoreObserver to stop ChainClients, Signers, and CoreObservder itself } - coreParams, err := b.GetCoreParams() + chainParams, err := b.GetChainParams() if err != nil { return err } - newEVMParams := make(map[int64]*observertypes.CoreParams) - var newBTCParams *observertypes.CoreParams + newEVMParams := make(map[int64]*observertypes.ChainParams) + var newBTCParams *observertypes.ChainParams - // check and update core params for each chain - for _, coreParam := range coreParams { - err := config.ValidateCoreParams(coreParam) + // check and update chain params for each chain + for _, chainParam := range chainParams { + err := config.ValidateChainParams(chainParam) if err != nil { - b.logger.Debug().Err(err).Msgf("Invalid core params for chain %s", common.GetChainFromChainID(coreParam.ChainId).ChainName) + b.logger.Debug().Err(err).Msgf( + "Invalid core params for chain %s", + common.GetChainFromChainID(chainParam.ChainId).ChainName, + ) } - if common.IsBitcoinChain(coreParam.ChainId) { - newBTCParams = coreParam + if common.IsBitcoinChain(chainParam.ChainId) { + newBTCParams = chainParam } else { - newEVMParams[coreParam.ChainId] = coreParam + newEVMParams[chainParam.ChainId] = chainParam } } @@ -233,7 +236,7 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err if err != nil { b.logger.Info().Msg("Unable to fetch keygen from zetacore") } - cfg.UpdateCoreParams(keyGen, newChains, newEVMParams, newBTCParams, init, b.logger) + cfg.UpdateChainParams(keyGen, newChains, newEVMParams, newBTCParams, init, b.logger) tss, err := b.GetCurrentTss() if err != nil { diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 4d6ee14c14..51078aefd2 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -262,8 +262,8 @@ func (co *CoreObserver) scheduleCctxEVM( } // #nosec G701 positive - interval := uint64(ob.GetCoreParams().OutboundTxScheduleInterval) - lookahead := ob.GetCoreParams().OutboundTxScheduleLookahead + 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 @@ -316,7 +316,7 @@ func (co *CoreObserver) scheduleCctxBTC( co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxBTC: chain client is not a bitcoin client") return } - lookahead := ob.GetCoreParams().OutboundTxScheduleLookahead + lookahead := ob.GetChainParams().OutboundTxScheduleLookahead // schedule at most one keysign per ticker for idx, cctx := range cctxList { @@ -352,18 +352,25 @@ func (co *CoreObserver) getUpdatedChainOb(chainID int64) (ChainClient, error) { return nil, err } // update chain client core parameters - curParams := chainOb.GetCoreParams() + curParams := chainOb.GetChainParams() if common.IsEVMChain(chainID) { evmCfg, found := co.cfg.GetEVMConfig(chainID) - if found && curParams != evmCfg.CoreParams { - chainOb.SetCoreParams(evmCfg.CoreParams) - co.logger.ZetaChainWatcher.Info().Msgf("updated core params for chainID %d, new params: %v", chainID, evmCfg.CoreParams) + if found && curParams != evmCfg.ChainParams { + chainOb.SetChainParams(evmCfg.ChainParams) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated chain params for chainID %d, new params: %v", + chainID, + evmCfg.ChainParams, + ) } } else if common.IsBitcoinChain(chainID) { _, btcCfg, found := co.cfg.GetBTCConfig() - if found && curParams != btcCfg.CoreParams { - chainOb.SetCoreParams(btcCfg.CoreParams) - co.logger.ZetaChainWatcher.Info().Msgf("updated core params for Bitcoin, new params: %v", btcCfg.CoreParams) + if found && curParams != btcCfg.ChainParams { + chainOb.SetChainParams(btcCfg.ChainParams) + co.logger.ZetaChainWatcher.Info().Msgf( + "updated chain params for Bitcoin, new params: %v", + btcCfg.ChainParams, + ) } } return chainOb, nil From 0642dbbb4a3d885e1d3e6ebf123d7f8ac3f0db5d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 9 Jan 2024 13:39:05 -0500 Subject: [PATCH 09/67] fix: btc decode address (#1528) * add checks for params * add wrapper function for btc decode address * remove checks fro prefixes * add check to see if address belongs to a network * fix unit tests * add changelog * remove unnecessary print statements * Update common/address.go Co-authored-by: Lucas Bertrand * Update common/address.go Co-authored-by: Lucas Bertrand * Update common/address.go Co-authored-by: Lucas Bertrand * fix lint * Update common/address.go Co-authored-by: Lucas Bertrand --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + common/address.go | 37 +++++++++++++++++++ common/address_test.go | 20 ++++++++++ common/chain.go | 2 +- .../smoketest/runner/setup_zeta.go | 4 +- x/crosschain/keeper/evm_hooks.go | 6 +-- zetaclient/bitcoin_client.go | 6 +-- zetaclient/btc_signer.go | 3 +- 8 files changed, 64 insertions(+), 15 deletions(-) diff --git a/changelog.md b/changelog.md index 4562c21d66..8cc99d1d24 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,7 @@ * fix docker build issues with version: golang:1.20-alpine3.18 * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta +* [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses ### Refactoring diff --git a/common/address.go b/common/address.go index 032a0b88b0..77b4234fed 100644 --- a/common/address.go +++ b/common/address.go @@ -1,8 +1,11 @@ package common import ( + "errors" + "fmt" "strings" + "github.com/btcsuite/btcutil" eth "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/zetacore/common/cosmos" ) @@ -41,3 +44,37 @@ func (addr Address) IsEmpty() bool { func (addr Address) String() string { return string(addr) } + +func ConvertRecoverToError(r interface{}) error { + switch x := r.(type) { + case string: + return errors.New(x) + case error: + return x + default: + return fmt.Errorf("%v", x) + } +} + +func DecodeBtcAddress(inputAddress string, chainID int64) (address btcutil.Address, err error) { + defer func() { + if r := recover(); r != nil { + err = ConvertRecoverToError(r) + err = fmt.Errorf("input address:%s, chainId:%d, err:%s", inputAddress, chainID, err.Error()) + return + } + }() + chainParams, err := GetBTCChainParams(chainID) + if err != nil { + return nil, err + } + if chainParams == nil { + return nil, fmt.Errorf("chain params not found") + } + address, err = btcutil.DecodeAddress(inputAddress, chainParams) + ok := address.IsForNet(chainParams) + if !ok { + return nil, fmt.Errorf("address is not for network %s", chainParams.Name) + } + return +} diff --git a/common/address_test.go b/common/address_test.go index 4487c48e28..af386c3bdc 100644 --- a/common/address_test.go +++ b/common/address_test.go @@ -20,3 +20,23 @@ func TestAddress(t *testing.T) { addr = NewAddress("0x90f2b1ae50e6018230e90a33f98c7844a0ab635a") require.EqualValuesf(t, "0x90f2b1ae50e6018230e90a33f98c7844a0ab635a", addr.String(), "address string should be equal") } + +func TestDecodeBtcAddress(t *testing.T) { + t.Run("invalid string", func(t *testing.T) { + _, err := DecodeBtcAddress("�U�ڷ���i߭����꿚�l", 18332) + require.ErrorContains(t, err, "runtime error: index out of range") + }) + t.Run("invalid chain", func(t *testing.T) { + _, err := DecodeBtcAddress("14CEjTd5ci3228J45GdnGeUKLSSeCWUQxK", 0) + require.ErrorContains(t, err, "is not a Bitcoin chain") + }) + t.Run("nil pointer dereference", func(t *testing.T) { + _, err := DecodeBtcAddress("tb1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", 18332) + require.ErrorContains(t, err, "runtime error: invalid memory address or nil pointer dereference") + }) + t.Run("valid address", func(t *testing.T) { + _, err := DecodeBtcAddress("bcrt1qy9pqmk2pd9sv63g27jt8r657wy0d9uee4x2dt2", 18444) + require.NoError(t, err) + }) + +} diff --git a/common/chain.go b/common/chain.go index ee2b26d855..d6762c1a91 100644 --- a/common/chain.go +++ b/common/chain.go @@ -52,7 +52,7 @@ func (chain Chain) EncodeAddress(b []byte) (string, error) { if err != nil { return "", err } - addr, err := btcutil.DecodeAddress(addrStr, chainParams) + addr, err := DecodeBtcAddress(addrStr, chain.ChainId) if err != nil { return "", err } diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go index 1a04830556..80a7606ba2 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/btcsuite/btcutil" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" @@ -38,7 +37,8 @@ func (sm *SmokeTestRunner) SetTSSAddresses() { } tssAddress := ethcommon.HexToAddress(res.Eth) - btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, common.BitcoinRegnetParams) + + btcTSSAddress, err := common.DecodeBtcAddress(res.Btc, common.BtcRegtestChain().ChainId) if err != nil { panic(err) } diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 85a7c1d8a0..e4c3ed5d4b 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -289,11 +289,7 @@ func (k Keeper) ParseZRC20WithdrawalEvent(ctx sdk.Context, log ethtypes.Log) (*z if event.Value.Cmp(big.NewInt(0)) <= 0 { return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String()) } - btcChainParams, err := common.GetBTCChainParams(chainID) - if err != nil { - return nil, err - } - addr, err := btcutil.DecodeAddress(string(event.To), btcChainParams) + addr, err := common.DecodeBtcAddress(string(event.To), chainID) if err != nil { return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid address %s: %s", event.To, err) } diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 9a427a3701..4e0651b45e 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -758,11 +758,7 @@ func (ob *BitcoinChainClient) FetchUTXOS() error { // List unspent. tssAddr := ob.Tss.BTCAddress() - bitcoinNetParams, err := common.BitcoinNetParamsFromChainID(ob.chain.ChainId) - if err != nil { - return fmt.Errorf("btc: error getting bitcoin net params : %v", err) - } - address, err := btcutil.DecodeAddress(tssAddr, bitcoinNetParams) + address, err := common.DecodeBtcAddress(tssAddr, ob.chain.ChainId) if err != nil { return fmt.Errorf("btc: error decoding wallet address (%s) : %s", tssAddr, err.Error()) } diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 761d233829..d175c9af71 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -301,8 +301,7 @@ func (signer *BTCSigner) TryProcessOutTx( logger.Error().Err(err).Msgf("cannot get bitcoin net params%v", err) return } - - addr, err := btcutil.DecodeAddress(params.Receiver, bitcoinNetParams) + addr, err := common.DecodeBtcAddress(params.Receiver, params.ReceiverChainId) if err != nil { logger.Error().Err(err).Msgf("cannot decode address %s ", params.Receiver) return From 179799d8556cebaa12df8afe0ef0e7c3d857e5c0 Mon Sep 17 00:00:00 2001 From: Grant Zukel <80433392+gzukel@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:18:29 -0700 Subject: [PATCH 10/67] ci: add pipeline to publish typescript libraries (#1544) * ci: add typescript publishing * uncommented docker login --- .github/workflows/build.yml | 12 ++++---- .github/workflows/publish-typescript.yaml | 34 +++++++++++++++++++++++ changelog.md | 3 ++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/publish-typescript.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d71ccd8f2a..ded55ff1e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,12 +104,12 @@ jobs: skip_aws_cli: "true" skip_docker_compose: "false" -# - name: Login to Docker Hub -# uses: docker/login-action@v2 -# if: github.event.repository.full_name == 'zetachain-chain/node' -# with: -# username: ${{ secrets.DOCKER_HUB_USERNAME }} -# password: ${{ secrets.DOCKER_HUB_READ_ONLY }} + - name: Login to Docker Hub + uses: docker/login-action@v2 + if: github.event.repository.full_name == 'zetachain-chain/node' + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_READ_ONLY }} - name: Build zetanode run: | diff --git a/.github/workflows/publish-typescript.yaml b/.github/workflows/publish-typescript.yaml new file mode 100644 index 0000000000..a5906d5047 --- /dev/null +++ b/.github/workflows/publish-typescript.yaml @@ -0,0 +1,34 @@ +name: Publish Typescript to NPM +on: + workflow_dispatch: + release: + types: [created] +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + + - name: Set Version + working-directory: typescript + run: | + version=$(cat app/setup_handlers.go | grep "const releaseVersion" | cut -d ' ' -f4 | tr -d '"') + npm version ${version} + sed -i 's/@zetachain\/blockchain-types/@zetachain\/node-types/' package.json + + - name: Install dependencies and build 🔧 + working-directory: typescript + run: npm ci && npm run build + + - name: Publish package on NPM 📦 + run: npm publish + working-directory: typescript + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/changelog.md b/changelog.md index 8cc99d1d24..17b3450361 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,8 @@ ## Unreleased +* ci: adding typescript publishing pipeline. + ### Breaking Changes * PendingNonces :Changed from `/zeta-chain/crosschain/pendingNonces/{chain_id}/{address}` to `/zeta-chain/observer/pendingNonces/{chain_id}/{address}` . It returns all the pending nonces for a chain id and address. This returns the current pending nonces for the chain. @@ -9,6 +11,7 @@ * ChainNoncesAll :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. ### Features + * [1395](https://github.com/zeta-chain/node/pull/1395) - Add state variable to track aborted zeta amount * [1410](https://github.com/zeta-chain/node/pull/1410) - `snapshots` commands * enable zetaclients to use dynamic gas price on zetachain - enables >0 min_gas_price in feemarket module From 89475e5d34bf6e6c7a2eea0c3b81e4d16d9d51ed Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:02:19 -0600 Subject: [PATCH 11/67] fix: additional checks for evm outbound tx and code enhancement to be defensive (#1530) * additional checks for evm outbound tx and code enhancement to be defensive * updaged changelog * fix unit test compile error * added more logs and updated changelog --- changelog.md | 1 + zetaclient/bitcoin_client.go | 138 +++++++++++++++++++++------------- zetaclient/btc_signer_test.go | 4 +- zetaclient/evm_client.go | 112 +++++++++++++++------------ 4 files changed, 149 insertions(+), 106 deletions(-) diff --git a/changelog.md b/changelog.md index 17b3450361..1a15cfa3a4 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ ### Fixes +* [1530](https://github.com/zeta-chain/node/pull/1530) - Outbound tx confirmation/inclusion enhancement * [1496](https://github.com/zeta-chain/node/issues/1496) - post block header for enabled EVM chains only * [1518](https://github.com/zeta-chain/node/pull/1518) - Avoid duplicate keysign if an outTx is already pending * fix Code4rena issue - zetaclients potentially miss inTx when PostSend (or other RPC) fails diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 4e0651b45e..2b9f242b56 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -57,9 +57,9 @@ type BitcoinChainClient struct { Mu *sync.Mutex // lock for all the maps, utxos and core params pendingNonce uint64 - includedTxHashes map[string]uint64 // key: tx hash - includedTxResults map[string]btcjson.GetTransactionResult // key: chain-tss-nonce - broadcastedTx map[string]string // key: chain-tss-nonce, value: outTx hash + includedTxHashes map[string]uint64 // 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 @@ -148,7 +148,7 @@ func NewBitcoinClient( ob.zetaClient = bridge ob.Tss = tss ob.includedTxHashes = make(map[string]uint64) - ob.includedTxResults = make(map[string]btcjson.GetTransactionResult) + ob.includedTxResults = make(map[string]*btcjson.GetTransactionResult) ob.broadcastedTx = make(map[string]string) ob.params = btcCfg.ChainParams @@ -442,24 +442,23 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 } // Try including this outTx broadcasted by myself - inMempool, err := ob.checkNSaveIncludedTx(txnHash, params) - if err != nil { - ob.logger.ObserveOutTx.Error().Err(err).Msg("IsSendOutTxProcessed: checkNSaveIncludedTx failed") + txResult, inMempool := ob.checkIncludedTx(txnHash, params) + if txResult == nil { + ob.logger.ObserveOutTx.Error().Err(err).Msg("IsSendOutTxProcessed: checkIncludedTx failed") return false, false, err - } - if inMempool { // to avoid unnecessary Tss keysign + } else if inMempool { // still in mempool (should avoid unnecessary Tss keysign) ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: outTx %s is still in mempool", outTxID) return true, false, nil + } else { // included + ob.setIncludedTx(nonce, txResult) } // Get tx result again in case it is just included - ob.Mu.Lock() - res, included = ob.includedTxResults[outTxID] - ob.Mu.Unlock() - if !included { + res = ob.getIncludedTx(nonce) + if res == nil { return false, false, nil } - ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: checkNSaveIncludedTx succeeded for outTx %s", outTxID) + ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: setIncludedTx succeeded for outTx %s", outTxID) } // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutTx() @@ -830,14 +829,11 @@ func (ob *BitcoinChainClient) refreshPendingNonce() { } func (ob *BitcoinChainClient) getOutTxidByNonce(nonce uint64, test bool) (string, error) { - ob.Mu.Lock() - res, included := ob.includedTxResults[ob.GetTxID(nonce)] - ob.Mu.Unlock() // 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 zetacore based on majority vote. - if included { + if res := ob.getIncludedTx(nonce); res != nil { return res.TxID, nil } if !test { // if not unit test, get cctx from zetacore @@ -1020,13 +1016,28 @@ func (ob *BitcoinChainClient) observeOutTx() { if len(tracker.HashList) > 1 { ob.logger.ObserveOutTx.Warn().Msgf("observeOutTx: oops, outTxID %s got multiple (%d) outTx hashes", outTxID, len(tracker.HashList)) } - // verify outTx hashes + // 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 + var txResult *btcjson.GetTransactionResult for _, txHash := range tracker.HashList { - _, err := ob.checkNSaveIncludedTx(txHash.TxHash, params) - if err != nil { - ob.logger.ObserveOutTx.Error().Err(err).Msg("observeOutTx: checkNSaveIncludedTx failed") + result, inMempool := ob.checkIncludedTx(txHash.TxHash, params) + if result != nil && !inMempool { // included + txCount++ + txResult = result + ob.logger.ObserveOutTx.Info().Msgf("observeOutTx: included outTx %s for chain %d nonce %d", txHash.TxHash, ob.chain.ChainId, tracker.Nonce) + if txCount > 1 { + ob.logger.ObserveOutTx.Error().Msgf( + "observeOutTx: checkIncludedTx passed, txCount %d chain %d nonce %d result %v", txCount, ob.chain.ChainId, tracker.Nonce, result) + } } } + if txCount == 1 { // should be only one txHash included for each nonce + ob.setIncludedTx(tracker.Nonce, txResult) + } else if txCount > 1 { + ob.removeIncludedTx(tracker.Nonce) // we can't tell which txHash is true, so we remove all (if any) to be safe + ob.logger.ObserveOutTx.Error().Msgf("observeOutTx: included multiple (%d) outTx for chain %d nonce %d", txCount, ob.chain.ChainId, tracker.Nonce) + } } ticker.UpdateInterval(ob.GetChainParams().OutTxTicker, ob.logger.ObserveOutTx) case <-ob.stop: @@ -1036,50 +1047,69 @@ func (ob *BitcoinChainClient) observeOutTx() { } } -// checkNSaveIncludedTx either includes a new outTx or update an existing outTx result. -// Returns inMempool, error -func (ob *BitcoinChainClient) checkNSaveIncludedTx(txHash string, params types.OutboundTxParams) (bool, error) { +// checkIncludedTx checks if a txHash is included and returns (txResult, inMempool) +// Note: if txResult is nil, then inMempool flag should be ignored. +func (ob *BitcoinChainClient) checkIncludedTx(txHash string, params types.OutboundTxParams) (*btcjson.GetTransactionResult, bool) { outTxID := ob.GetTxID(params.OutboundTxTssNonce) hash, getTxResult, err := ob.GetTxResultByHash(txHash) if err != nil { - return false, errors.Wrapf(err, "checkNSaveIncludedTx: error GetTxResultByHash: %s", txHash) + ob.logger.ObserveOutTx.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.ObserveOutTx.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(hash, getTxResult, params, params.OutboundTxTssNonce) if err != nil { - return false, errors.Wrapf(err, "checkNSaveIncludedTx: error verify bitcoin outTx %s outTxID %s", txHash, outTxID) + ob.logger.ObserveOutTx.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 +} - ob.Mu.Lock() - defer ob.Mu.Unlock() - nonce, foundHash := ob.includedTxHashes[txHash] - res, foundRes := ob.includedTxResults[outTxID] - - // include new outTx and enforce rigid 1-to-1 mapping: outTxID(nonce) <===> txHash - if !foundHash && !foundRes { - ob.includedTxHashes[txHash] = params.OutboundTxTssNonce - ob.includedTxResults[outTxID] = *getTxResult - if params.OutboundTxTssNonce >= ob.pendingNonce { // try increasing pending nonce on every newly included outTx - ob.pendingNonce = params.OutboundTxTssNonce + 1 - } - ob.logger.ObserveOutTx.Info().Msgf("checkNSaveIncludedTx: included new bitcoin outTx %s outTxID %s pending nonce %d", txHash, outTxID, ob.pendingNonce) - } - // update saved tx result as confirmations may increase - if foundHash && foundRes { - ob.includedTxResults[outTxID] = *getTxResult - if getTxResult.Confirmations > res.Confirmations { - ob.logger.ObserveOutTx.Info().Msgf("checkNSaveIncludedTx: bitcoin outTx %s got confirmations %d", txHash, getTxResult.Confirmations) - } - } - if !foundHash && foundRes { // be alert for duplicate payment!!! As we got a new hash paying same cctx. It might happen (e.g. majority of signers get crupted) - ob.logger.ObserveOutTx.Error().Msgf("checkNSaveIncludedTx: duplicate payment by bitcoin outTx %s outTxID %s, prior result %v, current result %v", txHash, outTxID, res, *getTxResult) +// setIncludedTx saves included tx result in memory +func (ob *BitcoinChainClient) 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.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 } - if foundHash && !foundRes { - ob.logger.ObserveOutTx.Error().Msgf("checkNSaveIncludedTx: unreachable code path! outTx %s outTxID %s, prior nonce %d, current nonce %d", txHash, outTxID, nonce, params.OutboundTxTssNonce) + ob.logger.ObserveOutTx.Info().Msgf("setIncludedTx: included new bitcoin outTx %s outTxID %s pending nonce %d", txHash, outTxID, ob.pendingNonce) + } else if txHash == res.TxID { // found same hash. + ob.includedTxResults[outTxID] = getTxResult // update tx result as confirmations may increase + if getTxResult.Confirmations > res.Confirmations { + ob.logger.ObserveOutTx.Info().Msgf("setIncludedTx: bitcoin outTx %s got confirmations %d", txHash, getTxResult.Confirmations) } - return false, nil + } else { // found other hash. + // be alert for duplicate payment!!! As we got a new hash paying same cctx (for whatever reason). + delete(ob.includedTxResults, outTxID) // we can't tell which txHash is true, so we remove all to be safe + ob.logger.ObserveOutTx.Error().Msgf("setIncludedTx: duplicate payment by bitcoin outTx %s outTxID %s, prior outTx %s", txHash, outTxID, res.TxID) } - return true, nil // in mempool +} + +// getIncludedTx gets the receipt and transaction from memory +func (ob *BitcoinChainClient) getIncludedTx(nonce uint64) *btcjson.GetTransactionResult { + ob.Mu.Lock() + defer ob.Mu.Unlock() + return ob.includedTxResults[ob.GetTxID(nonce)] +} + +// removeIncludedTx removes included tx's result from memory +func (ob *BitcoinChainClient) removeIncludedTx(nonce uint64) { + ob.Mu.Lock() + defer ob.Mu.Unlock() + delete(ob.includedTxResults, ob.GetTxID(nonce)) } // Basic TSS outTX checks: diff --git a/zetaclient/btc_signer_test.go b/zetaclient/btc_signer_test.go index 8bee941a98..5c12e67876 100644 --- a/zetaclient/btc_signer_test.go +++ b/zetaclient/btc_signer_test.go @@ -398,7 +398,7 @@ func createTestClient(t *testing.T) *BitcoinChainClient { client := &BitcoinChainClient{ Tss: tss, Mu: &sync.Mutex{}, - includedTxResults: make(map[string]btcjson.GetTransactionResult), + includedTxResults: make(map[string]*btcjson.GetTransactionResult), } // Create 10 dummy UTXOs (22.44 BTC in total) @@ -413,7 +413,7 @@ func createTestClient(t *testing.T) *BitcoinChainClient { func mineTxNSetNonceMark(ob *BitcoinChainClient, nonce uint64, txid string, preMarkIndex int) { // Mine transaction outTxID := ob.GetTxID(nonce) - ob.includedTxResults[outTxID] = btcjson.GetTransactionResult{TxID: txid} + ob.includedTxResults[outTxID] = &btcjson.GetTransactionResult{TxID: txid} // Set nonce mark tssAddress := ob.Tss.BTCAddressWitnessPubkeyHash().EncodeAddress() diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 005fa10260..badce4eca6 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -296,11 +296,11 @@ func (ob *EVMChainClient) Stop() { // returns: isIncluded, isConfirmed, Error // If isConfirmed, it also post to ZetaCore func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, cointype common.CoinType, logger zerolog.Logger) (bool, bool, error) { - if !ob.isTxConfirmed(nonce) { - return false, false, nil - } 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() @@ -543,13 +543,6 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co return false, false, nil } -// The lowest nonce we observe outTx for each chain -var lowestOutTxNonceToObserve = map[int64]uint64{ - 5: 113000, // Goerli - 97: 102600, // BSC testnet - 80001: 154500, // Mumbai -} - // FIXME: there's a chance that a txhash in OutTxChan may not deliver when Stop() is called // observeOutTx periodically checks all the txhash in potential outbound txs func (ob *EVMChainClient) observeOutTx() { @@ -558,7 +551,7 @@ func (ob *EVMChainClient) observeOutTx() { if err != nil || timeoutNonce <= 0 { timeoutNonce = 100 * 3 // process up to 100 hashes } - ob.logger.ObserveOutTx.Info().Msgf("observeOutTx using timeoutNonce %d seconds", timeoutNonce) + ob.logger.ObserveOutTx.Info().Msgf("observeOutTx: using timeoutNonce %d seconds", timeoutNonce) ticker, err := NewDynamicTicker(fmt.Sprintf("EVM_observeOutTx_%d", ob.chain.ChainId), ob.GetChainParams().OutTxTicker) if err != nil { @@ -577,28 +570,37 @@ func (ob *EVMChainClient) observeOutTx() { //FIXME: remove this timeout here to ensure that all trackers are queried outTimeout := time.After(time.Duration(timeoutNonce) * time.Second) TRACKERLOOP: - // Skip old gabbage trackers as we spent too much time on querying them for _, tracker := range trackers { nonceInt := tracker.Nonce - if nonceInt < lowestOutTxNonceToObserve[ob.chain.ChainId] { - continue - } if ob.isTxConfirmed(nonceInt) { // Go to next tracker if this one already has a confirmed tx continue } + txCount := 0 + var receipt *ethtypes.Receipt + var transaction *ethtypes.Transaction for _, txHash := range tracker.HashList { select { case <-outTimeout: - ob.logger.ObserveOutTx.Warn().Msgf("observeOutTx timeout on chain %d nonce %d", ob.chain.ChainId, nonceInt) + ob.logger.ObserveOutTx.Warn().Msgf("observeOutTx: timeout on chain %d nonce %d", ob.chain.ChainId, nonceInt) break TRACKERLOOP default: - if ob.confirmTxByHash(txHash.TxHash, nonceInt) { - ob.logger.ObserveOutTx.Info().Msgf("observeOutTx confirmed outTx %s for chain %d nonce %d", txHash.TxHash, ob.chain.ChainId, nonceInt) - break + if recpt, tx, ok := ob.checkConfirmedTx(txHash.TxHash, nonceInt); ok { + txCount++ + receipt = recpt + transaction = tx + ob.logger.ObserveOutTx.Info().Msgf("observeOutTx: confirmed outTx %s for chain %d nonce %d", txHash.TxHash, ob.chain.ChainId, nonceInt) + if txCount > 1 { + ob.logger.ObserveOutTx.Error().Msgf( + "observeOutTx: checkConfirmedTx passed, txCount %d chain %d nonce %d receipt %v transaction %v", txCount, ob.chain.ChainId, nonceInt, receipt, transaction) + } } - ob.logger.ObserveOutTx.Debug().Msgf("observeOutTx outTx %s for chain %d nonce %d not confirmed yet", txHash.TxHash, ob.chain.ChainId, nonceInt) } } + if txCount == 1 { // should be only one txHash confirmed for each nonce. + ob.SetTxNReceipt(nonceInt, receipt, transaction) + } else if txCount > 1 { // should not happen. We can't tell which txHash is true. It might happen (e.g. glitchy/hacked endpoint) + ob.logger.ObserveOutTx.Error().Msgf("observeOutTx: confirmed multiple (%d) outTx for chain %d nonce %d", txCount, ob.chain.ChainId, nonceInt) + } } ticker.UpdateInterval(ob.GetChainParams().OutTxTicker, ob.logger.ObserveOutTx) case <-ob.stop: @@ -611,47 +613,45 @@ func (ob *EVMChainClient) observeOutTx() { // SetPendingTx sets the pending transaction in memory func (ob *EVMChainClient) SetPendingTx(nonce uint64, transaction *ethtypes.Transaction) { ob.Mu.Lock() + defer ob.Mu.Unlock() ob.outTxPendingTransactions[ob.GetTxID(nonce)] = transaction - ob.Mu.Unlock() } // GetPendingTx gets the pending transaction from memory func (ob *EVMChainClient) GetPendingTx(nonce uint64) *ethtypes.Transaction { ob.Mu.Lock() - transaction := ob.outTxPendingTransactions[ob.GetTxID(nonce)] - ob.Mu.Unlock() - return transaction + defer ob.Mu.Unlock() + return ob.outTxPendingTransactions[ob.GetTxID(nonce)] } // SetTxNReceipt sets the receipt and transaction in memory func (ob *EVMChainClient) SetTxNReceipt(nonce uint64, receipt *ethtypes.Receipt, transaction *ethtypes.Transaction) { ob.Mu.Lock() + defer ob.Mu.Unlock() delete(ob.outTxPendingTransactions, ob.GetTxID(nonce)) // remove pending transaction, if any ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] = receipt ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] = transaction - ob.Mu.Unlock() } -// getTxNReceipt gets the receipt and transaction from memory +// GetTxNReceipt gets the receipt and transaction from memory func (ob *EVMChainClient) GetTxNReceipt(nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction) { ob.Mu.Lock() + defer ob.Mu.Unlock() receipt := ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] transaction := ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] - ob.Mu.Unlock() return receipt, transaction } // isTxConfirmed returns true if there is a confirmed tx for 'nonce' func (ob *EVMChainClient) isTxConfirmed(nonce uint64) bool { ob.Mu.Lock() - confirmed := ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] != nil && ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] != nil - ob.Mu.Unlock() - return confirmed + defer ob.Mu.Unlock() + return ob.outTXConfirmedReceipts[ob.GetTxID(nonce)] != nil && ob.outTXConfirmedTransactions[ob.GetTxID(nonce)] != nil } -// confirmTxByHash checks if a txHash is confirmed and saves transaction and receipt in memory -// returns true if confirmed or false otherwise -func (ob *EVMChainClient) confirmTxByHash(txHash string, nonce uint64) bool { +// checkConfirmedTx checks if a txHash is confirmed +// returns (receipt, transaction, true) if confirmed or (nil, nil, false) otherwise +func (ob *EVMChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Receipt, *ethtypes.Transaction, bool) { ctxt, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() @@ -659,15 +659,34 @@ func (ob *EVMChainClient) confirmTxByHash(txHash string, nonce uint64) bool { transaction, isPending, err := ob.evmClient.TransactionByHash(ctxt, ethcommon.HexToHash(txHash)) if err != nil { log.Error().Err(err).Msgf("confirmTxByHash: TransactionByHash error, txHash %s nonce %d", txHash, nonce) - return false + 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 false + 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 txHash %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 txHash %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 isPending { // save pending transaction + if transaction.Nonce() != nonce { // must match cctx nonce + log.Error().Msgf("confirmTxByHash: txHash %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 false + return nil, nil, false } // query receipt @@ -676,33 +695,26 @@ func (ob *EVMChainClient) confirmTxByHash(txHash string, nonce uint64) bool { if err != ethereum.NotFound { log.Warn().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) } - return false + 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 false + return nil, nil, false } - // check nonce and confirmations - if transaction.Nonce() != nonce { - log.Error().Msgf("confirmTxByHash: txHash %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) - return false - } + // check confirmations confHeight := receipt.BlockNumber.Uint64() + ob.GetChainParams().ConfirmationCount if confHeight >= math.MaxInt64 { log.Error().Msgf("confirmTxByHash: confHeight is too large for txHash %s nonce %d", txHash, nonce) - return false + return nil, nil, false } if confHeight > ob.GetLastBlockHeight() { log.Info().Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) - return false + return nil, nil, false } - // confirmed, save receipt and transaction - ob.SetTxNReceipt(nonce, receipt, transaction) - - return true + return receipt, transaction, true } // SetLastBlockHeightScanned set last block height scanned (not necessarily caught up with external block; could be slow/paused) From 0fe3dc526a3aff5c2bdf315bf2135da0a7d5e647 Mon Sep 17 00:00:00 2001 From: morde08 <10320821+morde08@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:38:47 -0800 Subject: [PATCH 12/67] feat: add monitoring(grafana, prometheus, ethbalance) for localnet testing (#1498) * add monitoring and blockscout for localnet testing * remove blockscout from this PR, update readme with grafana access instructions * add eth tss automation * update changelog.md * delete static addresses.txt file * update github changelog check workflow * update github changelog check workflow * add github head repo full name * switch to using pull request base and head for changelog diff * fix typo * update ethbalance image to be start of zetachain-exporter * change labeler workflow to run on pull_request_target instead of pull_request --------- Co-authored-by: Peter Lee Co-authored-by: morde08 Co-authored-by: Charlie <31941002+CharlieMc0@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- .github/workflows/change-log-check.yml | 2 +- .github/workflows/labeler.yml | 2 +- .gitignore | 8 + Makefile | 13 + changelog.md | 2 +- contrib/localnet/README.md | 24 + .../localnet/docker-compose-monitoring.yml | 47 + .../grafana/dashboards/cosmos_dashboard.json | 1458 +++++++++++++++++ .../localnet/grafana/dashboards/default.yaml | 8 + .../grafana/dashboards/eth_balance.json | 955 +++++++++++ .../dashboards/zetaclient_dashboard.json | 551 +++++++ contrib/localnet/grafana/datasource.yaml | 16 + contrib/localnet/grafana/get-tss-address.sh | 9 + contrib/localnet/prometheus/prometheus.yml | 39 + contrib/localnet/zetacored/common/app.toml | 2 +- contrib/localnet/zetacored/common/config.toml | 2 +- go.mod | 2 +- go.sum | 4 +- 18 files changed, 3136 insertions(+), 8 deletions(-) create mode 100644 contrib/localnet/docker-compose-monitoring.yml create mode 100644 contrib/localnet/grafana/dashboards/cosmos_dashboard.json create mode 100644 contrib/localnet/grafana/dashboards/default.yaml create mode 100644 contrib/localnet/grafana/dashboards/eth_balance.json create mode 100644 contrib/localnet/grafana/dashboards/zetaclient_dashboard.json create mode 100644 contrib/localnet/grafana/datasource.yaml create mode 100755 contrib/localnet/grafana/get-tss-address.sh create mode 100644 contrib/localnet/prometheus/prometheus.yml diff --git a/.github/workflows/change-log-check.yml b/.github/workflows/change-log-check.yml index 1e5374179f..6fe9ac2a9f 100644 --- a/.github/workflows/change-log-check.yml +++ b/.github/workflows/change-log-check.yml @@ -17,7 +17,7 @@ jobs: if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-changelog') }} run: | git fetch origin ${{ github.base_ref }} - CHANGELOG_DIFF=$(git diff origin/${{ github.base_ref }} origin/${{ github.head_ref }} -- changelog.md) + CHANGELOG_DIFF=$(git diff ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} -- changelog.md) echo "${CHANGELOG_DIFF}" if [ -z "$CHANGELOG_DIFF" ]; then echo "ERROR: No changes detected in CHANGELOG.md. Please update the changelog." diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 079b8dfa92..936823a405 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,6 +1,6 @@ name: "Pull Request Labeler" on: - pull_request: + pull_request_target: types: - opened - edited diff --git a/.gitignore b/.gitignore index d53a2695bd..6a53c9be7b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,11 @@ localnet/ganache/storage localnet/zetachain-monorepo /standalone-network/authz/tx.json /zetanode.log + +# Blockscout Files +contrib/localnet/blockscout/services/blockscout-db-data/* +contrib/localnet/blockscout/services/logs/* +contrib/localnet/blockscout/services/redis-data/* +contrib/localnet/blockscout/services/stats-db-data/* +contrib/localnet/grafana/addresses.txt +contrib/localnet/addresses.txt \ No newline at end of file diff --git a/Makefile b/Makefile index dd47b6a541..9bc41f0451 100644 --- a/Makefile +++ b/Makefile @@ -247,6 +247,19 @@ stateful-upgrade-source: stop-stateful-upgrade: cd contrib/localnet/ && $(DOCKER) compose -f docker-compose-stateful.yml down --remove-orphans +############################################################################### +### Monitoring ### +############################################################################### + +start-monitoring: + @echo "Starting monitoring services" + cd contrib/localnet/grafana/ && ./get-tss-address.sh + cd contrib/localnet/ && $(DOCKER) compose -f docker-compose-monitoring.yml up -d + +stop-monitoring: + @echo "Stopping monitoring services" + cd contrib/localnet/ && $(DOCKER) compose -f docker-compose-monitoring.yml down + ############################################################################### ### GoReleaser ### ############################################################################### diff --git a/changelog.md b/changelog.md index 1a15cfa3a4..f2ec931d7a 100644 --- a/changelog.md +++ b/changelog.md @@ -11,7 +11,7 @@ * ChainNoncesAll :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. ### Features - +* [1498](https://github.com/zeta-chain/node/pull/1498) - Add monitoring(grafana, prometheus, ethbalance) for localnet testing * [1395](https://github.com/zeta-chain/node/pull/1395) - Add state variable to track aborted zeta amount * [1410](https://github.com/zeta-chain/node/pull/1410) - `snapshots` commands * enable zetaclients to use dynamic gas price on zetachain - enables >0 min_gas_price in feemarket module diff --git a/contrib/localnet/README.md b/contrib/localnet/README.md index 467e0bc877..96143b06d5 100644 --- a/contrib/localnet/README.md +++ b/contrib/localnet/README.md @@ -76,6 +76,30 @@ which does the following docker compose command: # in zeta-node/contrib/localnet/orchestrator $ docker compose down --remove-orphans ``` +### Run monitoring setup +Before starting the monitoring setup, make sure the Zetacore API is up at http://localhost:1317. +You can also add any additional ETH addresses to monitor in zeta-node/contrib/localnet/grafana/addresses.txt file +```bash +# in zeta-node/ +make start-monitoring +``` +which does the following docker compose command: +```bash +# in zeta-node/contrib/localnet/ +$ docker compose -f docker-compose-monitoring.yml up -d +``` +### Grafana credentials and dashboards +The Grafana default credentials are admin:admin. The dashboards are located at http://localhost:3000. +### Stop monitoring setup +```bash +# in zeta-node/ +make stop-monitoring +``` +which does the following docker compose command: +```bash +# in zeta-node/contrib/localnet/ +$ docker compose -f docker-compose-monitoring.yml down --remove-orphans +``` ## Useful data diff --git a/contrib/localnet/docker-compose-monitoring.yml b/contrib/localnet/docker-compose-monitoring.yml new file mode 100644 index 0000000000..ad66f828ec --- /dev/null +++ b/contrib/localnet/docker-compose-monitoring.yml @@ -0,0 +1,47 @@ +version: '3' + +services: + grafana: + image: grafana/grafana:latest + container_name: grafana + hostname: grafana + volumes: + - ./grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml + - ./grafana/dashboards/:/etc/grafana/provisioning/dashboards + ports: + - "3000:3000" + networks: + mynetwork: + ipv4_address: 172.20.0.30 + + prometheus: + image: prom/prometheus:latest + container_name: prometheus + hostname: prometheus + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + networks: + mynetwork: + ipv4_address: 172.20.0.31 + + zetachain-exporter: + image: zetachain/zetachain-exporter:latest + container_name: zetachain-exporter + hostname: zetachain-exporter + volumes: + - ./grafana/addresses.txt:/app/addresses.txt + ports: + - "9015:9015" + networks: + mynetwork: + ipv4_address: 172.20.0.32 + environment: + - GETH=http://eth:8545 + +networks: + mynetwork: + ipam: + config: + - subnet: 172.20.0.0/24 \ No newline at end of file diff --git a/contrib/localnet/grafana/dashboards/cosmos_dashboard.json b/contrib/localnet/grafana/dashboards/cosmos_dashboard.json new file mode 100644 index 0000000000..85ca855f22 --- /dev/null +++ b/contrib/localnet/grafana/dashboards/cosmos_dashboard.json @@ -0,0 +1,1458 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "A Grafana dashboard compatible with all the cosmos-sdk and tendermint based blockchains.", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 11036, + "graphTooltip": 0, + "id": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 64, + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "refId": "A" + } + ], + "title": "$chain_id overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 62, + "links": [], + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "refId": "A" + } + ], + "transparent": true, + "type": "text" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 3 + }, + "hideTimeOverride": false, + "id": 4, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_height{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Block Height", + "type": "stat" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 3 + }, + "hideTimeOverride": false, + "id": 40, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_total_txs{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Total Transactions", + "type": "stat" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 3 + }, + "hideTimeOverride": true, + "id": 39, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_block_interval_seconds{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "timeFrom": "1h", + "title": "Avg Block Time", + "type": "stat" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 3 + }, + "hideTimeOverride": false, + "id": 47, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_validators_power{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "instant": false, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Bonded Tokens", + "type": "stat" + }, + { + "aliasColors": { + "Height for last 3 hours": "#447ebc", + "Total Transactions for last 3 hours": "#ef843c" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_validators{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Active", + "refId": "A" + }, + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_missing_validators{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "Missing", + "refId": "B" + }, + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_byzantine_validators{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Byzantine", + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Validators", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "locale", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "none", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": { + "Height for last 3 hours": "#447ebc", + "Total Transactions for last 3 hours": "#ef843c" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 48, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_validators_power{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Online", + "refId": "A" + }, + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_missing_validators_power{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "Missing", + "refId": "B" + }, + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_byzantine_validators_power{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Byzantine", + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Voting Power", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "none", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": { + "Height for last 3 hours": "#447ebc", + "Total Transactions for last 3 hours": "#ef843c" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 49, + "legend": { + "alignAsTable": false, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_block_size_bytes{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Block Size", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Block Size", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "bytes", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "none", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": { + "Height for last 3 hours": "#447ebc", + "Total Transactions for last 3 hours": "#ef843c" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 50, + "legend": { + "alignAsTable": false, + "avg": true, + "current": false, + "max": true, + "min": false, + "rightSide": false, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_consensus_num_txs{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "Transactions", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Transactions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "none", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 55, + "panels": [], + "repeat": "instance", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "refId": "A" + } + ], + "title": "instance overview: $instance", + "type": "row" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "max": 20, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#e24d42", + "value": null + }, + { + "color": "#ef843c", + "value": 2 + }, + { + "color": "#7eb26d", + "value": 5 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 22 + }, + "hideTimeOverride": true, + "id": 53, + "links": [], + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_p2p_peers{chain_id=\"$chain_id\", instance=~\"$instance\"}", + "format": "time_series", + "instant": true, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Connected Peers", + "type": "gauge" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "max": 50, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#7eb26d", + "value": null + }, + { + "color": "#ef843c", + "value": 10 + }, + { + "color": "#e24d42", + "value": 20 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 22 + }, + "hideTimeOverride": true, + "id": 56, + "links": [], + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_mempool_size{chain_id=\"$chain_id\", instance=~\"$instance\"}", + "format": "time_series", + "instant": true, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Unconfirmed Transactions", + "type": "gauge" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 22 + }, + "hideTimeOverride": true, + "id": 60, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_mempool_failed_txs{chain_id=\"$chain_id\", instance=~\"$instance\"}", + "format": "time_series", + "instant": true, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Failed Transactions", + "type": "stat" + }, + { + "datasource": { + "uid": "$DS" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 22 + }, + "hideTimeOverride": true, + "id": 61, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_mempool_recheck_times{chain_id=\"$chain_id\", instance=~\"$instance\"}", + "format": "time_series", + "instant": true, + "interval": "30s", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Recheck Times", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 26 + }, + "hiddenSeries": false, + "id": 59, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_p2p_peer_receive_bytes_total{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{peer_id}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Network Input", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "series", + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "uid": "$DS" + }, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 26 + }, + "hiddenSeries": false, + "id": 58, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "uid": "$DS" + }, + "expr": "tendermint_p2p_peer_send_bytes_total{chain_id=\"$chain_id\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{peer_id}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Network Output", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "series", + "show": false, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + } + ], + "refresh": "", + "schemaVersion": 38, + "tags": [ + "Blockchain", + "Cosmos" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "athens_101-1", + "value": "athens_101-1" + }, + "datasource": { + "uid": "$DS" + }, + "definition": "label_values(tendermint_consensus_height, chain_id)", + "hide": 0, + "includeAll": false, + "label": "Chain ID", + "multi": false, + "name": "chain_id", + "options": [], + "query": "label_values(tendermint_consensus_height, chain_id)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": "", + "current": { + "selected": false, + "text": "172.20.0.11:26660", + "value": "172.20.0.11:26660" + }, + "datasource": { + "uid": "$DS" + }, + "definition": "label_values(tendermint_consensus_height{chain_id=\"$chain_id\"}, instance)", + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": "label_values(tendermint_consensus_height{chain_id=\"$chain_id\"}, instance)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now/d", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Cosmos Dashboard", + "uid": "UJyurCTWz", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/contrib/localnet/grafana/dashboards/default.yaml b/contrib/localnet/grafana/dashboards/default.yaml new file mode 100644 index 0000000000..581a362406 --- /dev/null +++ b/contrib/localnet/grafana/dashboards/default.yaml @@ -0,0 +1,8 @@ +apiVersion: 1 + +providers: + - name: Default # A uniquely identifiable name for the provider + folder: Dashboards # The folder where to place the dashboards + type: file + options: + path: /etc/grafana/provisioning/dashboards # Path to dashboard files on disk (required) \ No newline at end of file diff --git a/contrib/localnet/grafana/dashboards/eth_balance.json b/contrib/localnet/grafana/dashboards/eth_balance.json new file mode 100644 index 0000000000..7cafe4c4d9 --- /dev/null +++ b/contrib/localnet/grafana/dashboards/eth_balance.json @@ -0,0 +1,955 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Graph Ethereum Wallet Balances", + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 6970, + "graphTooltip": 0, + "id": 4, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 0 + }, + "id": 3, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "eth_total_addresses", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Total Addresses Logged", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 16, + "x": 4, + "y": 0 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "topk(5, eth_balance)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Top 5 Balances", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": null + }, + { + "color": "#fce2de", + "value": 0 + }, + { + "color": "#d44a3a", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 11, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "(eth_balance_total - eth_balance_total offset 1m) / eth_balance_total", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Total ETH 1 Hour Change", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "dtdurations" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 4 + }, + "id": 2, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "eth_load_seconds", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Total Load Time", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": null + }, + { + "color": "#fce2de", + "value": 0 + }, + { + "color": "#d44a3a", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 20, + "y": 4 + }, + "id": 12, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "(eth_balance_total - eth_balance_total offset 24h) / eth_balance_total", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Total ETH 24 Hour Change", + "type": "stat" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 14, + "links": [], + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "
${name}
", + "mode": "html" + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "refId": "A" + } + ], + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 14, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "eth_balance{name=\"${name}\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "${name} ETH", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "${name} Balance", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "locale", + "label": "ETH", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "locale" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 14, + "y": 11 + }, + "id": 7, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "eth_balance{name=\"${name}\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "${name} ETH", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": null + }, + { + "color": "#fce2de", + "value": 0 + }, + { + "color": "#d44a3a", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 19, + "y": 11 + }, + "id": 8, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "(eth_balance{name=\"${name}\"} - eth_balance{name=\"${name}\"} offset 1h) / eth_balance{name=\"${name}\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "${name} ETH 1 Hour Change", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": null + }, + { + "color": "#fce2de", + "value": 0 + }, + { + "color": "#d44a3a", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 14, + "y": 15 + }, + "id": 10, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "(eth_balance{name=\"${name}\"} - eth_balance{name=\"${name}\"} offset 24h) / eth_balance{name=\"${name}\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "${name} ETH 24 Hour Change", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#299c46", + "value": null + }, + { + "color": "#fce2de", + "value": 0 + }, + { + "color": "#d44a3a", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 19, + "y": 15 + }, + "id": 9, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.2.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "(eth_balance{name=\"${name}\"} - eth_balance{name=\"${name}\"} offset 7d) / eth_balance{name=\"${name}\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "${name} ETH Week Change", + "type": "stat" + } + ], + "refresh": "", + "schemaVersion": 38, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "ethTSS", + "value": "ethTSS" + }, + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "definition": "", + "hide": 0, + "includeAll": false, + "label": "name", + "multi": false, + "name": "name", + "options": [], + "query": "label_values(eth_balance, name)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Ethereum Wallet Monitor", + "uid": "pgGHUOdmv", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/contrib/localnet/grafana/dashboards/zetaclient_dashboard.json b/contrib/localnet/grafana/dashboards/zetaclient_dashboard.json new file mode 100644 index 0000000000..68194ee1f9 --- /dev/null +++ b/contrib/localnet/grafana/dashboards/zetaclient_dashboard.json @@ -0,0 +1,551 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Dashboard for Zetaclient Metrics", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 6, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 6, + "panels": [], + "title": "Zetaclient Dashboard", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "zetaclient_pending_txs_goerli_localnet", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Pending Transaction Goerli Localnet", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "zetaclient_hotkey_burn_rate", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Hotkey Burn Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "zetaclient_pending_txs_btc_regtest", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Pending Transactions BTC", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "zetaclient_Outbound_tx_sign_count{instance=\"172.20.0.21:8886\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Outbound Transaction Sign Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "zetaclient_rpc_getBlockByNumber_count_goerli_localnet", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "BlockByNo Count Goerli/Localnet", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 38, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Zetaclient Dashboard", + "uid": "efac1ac6-2adb-4123-8833-a8634c5fa64d", + "version": 9, + "weekStart": "" +} \ No newline at end of file diff --git a/contrib/localnet/grafana/datasource.yaml b/contrib/localnet/grafana/datasource.yaml new file mode 100644 index 0000000000..59cd333a94 --- /dev/null +++ b/contrib/localnet/grafana/datasource.yaml @@ -0,0 +1,16 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + # Access mode - proxy (server in the UI) or direct (browser in the UI). + url: http://prometheus:9090 + jsonData: + httpMethod: POST + manageAlerts: true + prometheusType: Prometheus + prometheusVersion: 2.48.1 + cacheLevel: 'High' + disableRecordingRules: false + incrementalQueryOverlapWindow: 10m \ No newline at end of file diff --git a/contrib/localnet/grafana/get-tss-address.sh b/contrib/localnet/grafana/get-tss-address.sh new file mode 100755 index 0000000000..eae4b031af --- /dev/null +++ b/contrib/localnet/grafana/get-tss-address.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +/usr/sbin/sshd + +#retrieve value of ETH TSS Address from localnet +ethTSS_address=$(curl 'http://localhost:1317/zeta-chain/observer/get_tss_address' | jq -r '.eth') + +#write value of ETH TSS Address to addresses.txt file +printf "ethTSS:$ethTSS_address\n" > addresses.txt \ No newline at end of file diff --git a/contrib/localnet/prometheus/prometheus.yml b/contrib/localnet/prometheus/prometheus.yml new file mode 100644 index 0000000000..3c73f90385 --- /dev/null +++ b/contrib/localnet/prometheus/prometheus.yml @@ -0,0 +1,39 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: +# - "first_rules.yml" +# - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: "zetacore" + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ["172.20.0.11:26660"] + + - job_name: "zetaclient" + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ["172.20.0.21:8886"] + + - job_name: "ethbalance" + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ["172.20.0.32:9015"] \ No newline at end of file diff --git a/contrib/localnet/zetacored/common/app.toml b/contrib/localnet/zetacored/common/app.toml index 624e89d40c..7bbf48cf96 100644 --- a/contrib/localnet/zetacored/common/app.toml +++ b/contrib/localnet/zetacored/common/app.toml @@ -80,7 +80,7 @@ service-name = "" # Enabled enables the application telemetry functionality. When enabled, # an in-memory sink is also enabled by default. Operators may also enabled # other sinks such as Prometheus. -enabled = false +enabled = true # Enable prefixing gauge values with hostname. enable-hostname = false diff --git a/contrib/localnet/zetacored/common/config.toml b/contrib/localnet/zetacored/common/config.toml index 29b433e824..c0f955ea4b 100644 --- a/contrib/localnet/zetacored/common/config.toml +++ b/contrib/localnet/zetacored/common/config.toml @@ -451,7 +451,7 @@ psql-conn = "" # When true, Prometheus metrics are served under /metrics on # PrometheusListenAddr. # Check out the documentation for the list of available metrics. -prometheus = false +prometheus = true # Address to listen for Prometheus collector(s) connections prometheus_listen_addr = ":26660" diff --git a/go.mod b/go.mod index a8dd44e772..b583a97b16 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.16 // indirect + github.com/mattn/go-sqlite3 v1.14.19 // indirect gorm.io/driver/sqlite v1.4.4 gorm.io/gorm v1.24.6 ) diff --git a/go.sum b/go.sum index 238beaf820..da78e7283c 100644 --- a/go.sum +++ b/go.sum @@ -2154,8 +2154,8 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= +github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= From 7108038ef97d1df836edc213b0d28582a5b98125 Mon Sep 17 00:00:00 2001 From: Grant Zukel <80433392+gzukel@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:04:38 -0700 Subject: [PATCH 13/67] ci: Finalize typescript NPM package publish on release creation. (#1548) * ci: add typescript publishing --- .github/workflows/publish-typescript.yaml | 16 ++++++++++------ scripts/protoc-gen-typescript.sh | 2 +- typescript/package.json | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-typescript.yaml b/.github/workflows/publish-typescript.yaml index a5906d5047..890f867d8b 100644 --- a/.github/workflows/publish-typescript.yaml +++ b/.github/workflows/publish-typescript.yaml @@ -16,16 +16,20 @@ jobs: node-version: '20.x' registry-url: 'https://registry.npmjs.org' + - name: Install buf + run: | + curl -sSL https://github.com/bufbuild/buf/releases/download/v1.28.1/buf-Linux-x86_64 -o /usr/local/bin/buf + chmod +x /usr/local/bin/buf + + - name: Generate + run: | + make typescript + - name: Set Version working-directory: typescript run: | - version=$(cat app/setup_handlers.go | grep "const releaseVersion" | cut -d ' ' -f4 | tr -d '"') + version=$(cat ../app/setup_handlers.go | grep "const releaseVersion" | cut -d ' ' -f4 | tr -d '"') npm version ${version} - sed -i 's/@zetachain\/blockchain-types/@zetachain\/node-types/' package.json - - - name: Install dependencies and build 🔧 - working-directory: typescript - run: npm ci && npm run build - name: Publish package on NPM 📦 run: npm publish diff --git a/scripts/protoc-gen-typescript.sh b/scripts/protoc-gen-typescript.sh index 526d4773da..e56c951de1 100755 --- a/scripts/protoc-gen-typescript.sh +++ b/scripts/protoc-gen-typescript.sh @@ -8,7 +8,7 @@ rm -rf $DIR cat < $DIR/package.json { - "name": "@zetachain/blockchain-types", + "name": "@zetachain/node-types", "version": "0.0.0-set-on-publish", "description": "", "main": "", diff --git a/typescript/package.json b/typescript/package.json index 369d5cbb82..31e60016e1 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -1,5 +1,5 @@ { - "name": "@zetachain/blockchain-types", + "name": "@zetachain/node-types", "version": "0.0.0-set-on-publish", "description": "", "main": "", From 328319177b2672b005f028462b3076826dfd3f18 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Wed, 10 Jan 2024 12:46:10 -0800 Subject: [PATCH 14/67] test(`e2e`): improve stateful e2e testing (#1538) * support contracts in config * refactor stateful test * set back e2e test to previous implementation * stateful check some fixes * fix legacy query * use patched v11 for evm addresses * fix wait for logic * comment out tests * fix upgrade tests * go import * add comment for code to be removed * make generate * changelogs * fix typy * test tss height 20 * revert back keygen height --------- Co-authored-by: Tanmay --- Dockerfile-versioned | 5 +- Dockerfile-versioned-source | 23 +- Makefile | 2 +- app/setup_handlers.go | 2 +- changelog.md | 2 + cmd/zetaclientd/start_utils.go | 6 +- cmd/zetae2e/config/config.go | 21 + cmd/zetae2e/config/contracts.go | 28 + cmd/zetae2e/local/local.go | 83 ++- cmd/zetae2e/local/utils.go | 8 +- contrib/localnet/docker-compose.yml | 1 - .../orchestrator/Dockerfile-upgrade.fastbuild | 6 +- .../orchestrator/restart-zetaclientd.sh | 6 +- .../orchestrator/smoketest/config/config.go | 15 +- .../orchestrator/smoketest/runner/bitcoin.go | 33 +- .../orchestrator/smoketest/runner/evm.go | 1 - .../orchestrator/smoketest/runner/runner.go | 24 + .../smoketest/runner/setup_zeta.go | 39 +- .../smoketests/test_crosschain_swap.go | 7 +- .../smoketest/smoketests/test_zrc20_swap.go | 8 +- .../localnet/orchestrator/start-upgrade.sh | 77 +- contrib/localnet/orchestrator/start.sh | 13 +- contrib/localnet/scripts/genesis-stateful.sh | 34 +- contrib/localnet/scripts/genesis-upgrade.sh | 5 + .../scripts/start-zetaclientd-background.sh | 10 +- .../scripts/start-zetaclientd-genesis.sh | 4 +- docs/openapi/openapi.swagger.yaml | 46 +- proto/crosschain/query.proto | 21 + typescript/crosschain/query_pb.d.ts | 56 ++ x/crosschain/keeper/grpc_query.go | 12 + x/crosschain/types/query.pb.go | 703 ++++++++++++++---- x/crosschain/types/query.pb.gw.go | 65 ++ 32 files changed, 1068 insertions(+), 298 deletions(-) diff --git a/Dockerfile-versioned b/Dockerfile-versioned index c948817829..96e8c0e88e 100644 --- a/Dockerfile-versioned +++ b/Dockerfile-versioned @@ -1,4 +1,4 @@ -FROM golang:1.19-alpine +FROM golang:1.20-alpine3.18 ENV GOPATH /go ENV GOOS=linux @@ -38,10 +38,7 @@ RUN cp $GOPATH/bin/smoketest $GOPATH/bin/old/ RUN git clone https://github.com/zeta-chain/cosmos-sdk.git RUN cd cosmos-sdk && git checkout zetavisor-v0.1.5 RUN cd cosmos-sdk/cosmovisor && make zetavisor -# -#FROM golang:1.19-alpine -#RUN apk --no-cache add openssh jq tmux vim curl bash RUN ssh-keygen -A WORKDIR /root diff --git a/Dockerfile-versioned-source b/Dockerfile-versioned-source index a0ee08a782..f6b90d5126 100644 --- a/Dockerfile-versioned-source +++ b/Dockerfile-versioned-source @@ -1,4 +1,4 @@ -FROM golang:1.19-alpine +FROM golang:1.20-alpine3.18 ENV GOPATH /go ENV GOOS=linux @@ -9,12 +9,15 @@ ARG old_version 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 "" +# Build cosmovisor +RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.5.0 + WORKDIR /go/delivery/zeta-node RUN mkdir -p $GOPATH/bin/old RUN mkdir -p $GOPATH/bin/new -ENV NEW_VERSION=v42.0.0 +ENV NEW_VERSION=v12.0.0 # Build new release from the current source COPY go.mod /go/delivery/zeta-node/ @@ -22,10 +25,9 @@ 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-smoketest +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 cp $GOPATH/bin/smoketest $GOPATH/bin/new/ # Checkout and build old binary RUN git clone https://github.com/zeta-chain/node.git @@ -33,18 +35,9 @@ RUN cd node && git fetch RUN cd node && git checkout ${old_version} RUN cd node && make install -RUN cd node && make install-smoketest RUN cp $GOPATH/bin/zetacored $GOPATH/bin/old/ RUN cp $GOPATH/bin/zetaclientd $GOPATH/bin/old/ -RUN cp $GOPATH/bin/smoketest $GOPATH/bin/old/ - -RUN git clone https://github.com/zeta-chain/cosmos-sdk.git -RUN cd cosmos-sdk && git checkout zetavisor-v0.1.5 -RUN cd cosmos-sdk/cosmovisor && make zetavisor -# -#FROM golang:1.19-alpine -#RUN apk --no-cache add openssh jq tmux vim curl bash RUN ssh-keygen -A WORKDIR /root @@ -52,8 +45,8 @@ RUN cp /root/.ssh/localtest.pem.pub /root/.ssh/authorized_keys RUN cp /go/bin/zetaclientd /usr/local/bin RUN cp /go/bin/zetacored /usr/local/bin -RUN cp /go/bin/smoketest /usr/local/bin -RUN cp /go/bin/zetavisor /usr/local/bin +RUN cp /go/bin/zetae2e /usr/local/bin +RUN cp /go/bin/cosmovisor /usr/local/bin COPY contrib/localnet/scripts /root COPY contrib/localnet/preparams /root/preparams diff --git a/Makefile b/Makefile index 9bc41f0451..34862f40e3 100644 --- a/Makefile +++ b/Makefile @@ -240,7 +240,7 @@ stateful-upgrade: stateful-upgrade-source: @echo "--> Starting stateful smoketest" - $(DOCKER) build --build-arg old_version=v10.1.7 -t zetanode -f ./Dockerfile-versioned-source . + $(DOCKER) build --build-arg old_version=v11.0.0-patch-core-params -t zetanode -f ./Dockerfile-versioned-source . $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild . cd contrib/localnet/ && $(DOCKER) compose -f docker-compose-stateful.yml up -d diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 8948c68527..533679f243 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -9,7 +9,7 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -const releaseVersion = "v11.0.0" +const releaseVersion = "v12.0.0" func SetupHandlers(app *App) { app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { diff --git a/changelog.md b/changelog.md index f2ec931d7a..0498a869e1 100644 --- a/changelog.md +++ b/changelog.md @@ -59,6 +59,8 @@ ### Tests +* [1538](https://github.com/zeta-chain/node/pull/1538) - improve stateful e2e testing + ### CI * Removed private runners and unused GitHub Action diff --git a/cmd/zetaclientd/start_utils.go b/cmd/zetaclientd/start_utils.go index 1fcdc1945e..47ed135442 100644 --- a/cmd/zetaclientd/start_utils.go +++ b/cmd/zetaclientd/start_utils.go @@ -34,18 +34,18 @@ func validatePeer(seedPeer string) error { parsedPeer := strings.Split(seedPeer, "/") if len(parsedPeer) < 7 { - return errors.New("seed peer missing IP or ID") + return errors.New("seed peer missing IP or ID or both, seed: " + seedPeer) } seedIP := parsedPeer[2] seedID := parsedPeer[6] if net.ParseIP(seedIP) == nil { - return errors.New("invalid seed IP address") + return errors.New("invalid seed IP address format, seed: " + seedPeer) } if len(seedID) == 0 { - return errors.New("seed id is empty") + return errors.New("seed id is empty, seed: " + seedPeer) } return nil diff --git a/cmd/zetae2e/config/config.go b/cmd/zetae2e/config/config.go index f1635f768e..f307afa02e 100644 --- a/cmd/zetae2e/config/config.go +++ b/cmd/zetae2e/config/config.go @@ -74,3 +74,24 @@ func RunnerFromConfig( return sm, err } + +// ExportContractsFromRunner export contracts from the runner to config using a source config +func ExportContractsFromRunner(sm *runner.SmokeTestRunner, conf config.Config) config.Config { + // copy contracts from deployer runner + conf.Contracts.EVM.ZetaEthAddress = sm.ZetaEthAddr.Hex() + conf.Contracts.EVM.ConnectorEthAddr = sm.ConnectorEthAddr.Hex() + conf.Contracts.EVM.CustodyAddr = sm.ERC20CustodyAddr.Hex() + conf.Contracts.EVM.USDT = sm.USDTERC20Addr.Hex() + + conf.Contracts.ZEVM.SystemContractAddr = sm.SystemContractAddr.Hex() + conf.Contracts.ZEVM.ETHZRC20Addr = sm.ETHZRC20Addr.Hex() + conf.Contracts.ZEVM.USDTZRC20Addr = sm.USDTZRC20Addr.Hex() + conf.Contracts.ZEVM.BTCZRC20Addr = sm.BTCZRC20Addr.Hex() + conf.Contracts.ZEVM.UniswapFactoryAddr = sm.UniswapV2FactoryAddr.Hex() + conf.Contracts.ZEVM.UniswapRouterAddr = sm.UniswapV2RouterAddr.Hex() + conf.Contracts.ZEVM.ZEVMSwapAppAddr = sm.ZEVMSwapAppAddr.Hex() + conf.Contracts.ZEVM.ContextAppAddr = sm.ContextAppAddr.Hex() + conf.Contracts.ZEVM.TestDappAddr = sm.TestDAppAddr.Hex() + + return conf +} diff --git a/cmd/zetae2e/config/contracts.go b/cmd/zetae2e/config/contracts.go index 49ad44dc4c..c49ce98f8b 100644 --- a/cmd/zetae2e/config/contracts.go +++ b/cmd/zetae2e/config/contracts.go @@ -12,7 +12,9 @@ import ( "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-core/contracts/uniswapv2factory.sol" uniswapv2router "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/contextapp" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/erc20" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/zevmswap" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" ) @@ -133,6 +135,32 @@ func setContractsFromConfig(r *runner.SmokeTestRunner, conf config.Config) error return err } } + if c := conf.Contracts.ZEVM.ZEVMSwapAppAddr; c != "" { + if !ethcommon.IsHexAddress(c) { + return fmt.Errorf("invalid ZEVMSwapAppAddr: %s", c) + } + r.ZEVMSwapAppAddr = ethcommon.HexToAddress(c) + r.ZEVMSwapApp, err = zevmswap.NewZEVMSwapApp(r.ZEVMSwapAppAddr, r.ZevmClient) + if err != nil { + return err + } + } + if c := conf.Contracts.ZEVM.ContextAppAddr; c != "" { + if !ethcommon.IsHexAddress(c) { + return fmt.Errorf("invalid ContextAppAddr: %s", c) + } + r.ContextAppAddr = ethcommon.HexToAddress(c) + r.ContextApp, err = contextapp.NewContextApp(r.ContextAppAddr, r.ZevmClient) + if err != nil { + return err + } + } + if c := conf.Contracts.ZEVM.TestDappAddr; c != "" { + if !ethcommon.IsHexAddress(c) { + return fmt.Errorf("invalid TestDappAddr: %s", c) + } + r.TestDAppAddr = ethcommon.HexToAddress(c) + } return nil } diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 754f856aa6..72023b8e9b 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -3,11 +3,13 @@ package local import ( "context" "os" + "path/filepath" "time" "github.com/fatih/color" "github.com/spf13/cobra" zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" "golang.org/x/sync/errgroup" @@ -21,6 +23,9 @@ const ( flagTestAdmin = "test-admin" flagTestCustom = "test-custom" flagSkipRegular = "skip-regular" + flagSetupOnly = "setup-only" + flagConfigOut = "config-out" + flagSkipSetup = "skip-setup" ) var ( @@ -70,6 +75,21 @@ func NewLocalCmd() *cobra.Command { false, "set to true to skip regular tests", ) + cmd.Flags().Bool( + flagSetupOnly, + false, + "set to true to only setup the networks", + ) + cmd.Flags().String( + flagConfigOut, + "", + "config file to write the deployed contracts from the setup", + ) + cmd.Flags().Bool( + flagSkipSetup, + false, + "set to true to skip setup", + ) return cmd } @@ -101,6 +121,18 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if err != nil { panic(err) } + setupOnly, err := cmd.Flags().GetBool(flagSetupOnly) + if err != nil { + panic(err) + } + configOut, err := cmd.Flags().GetString(flagConfigOut) + if err != nil { + panic(err) + } + skipSetup, err := cmd.Flags().GetBool(flagSkipSetup) + if err != nil { + panic(err) + } testStartTime := time.Now() logger.Print("starting tests") @@ -130,8 +162,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { setCosmosConfig() // wait for Genesis - logger.Print("⏳ wait 70s for genesis") - time.Sleep(70 * time.Second) + // if setup is skipp, we assume that the genesis is already created + if !skipSetup { + logger.Print("⏳ wait 70s for genesis") + time.Sleep(70 * time.Second) + } // initialize deployer runner with config deployerRunner, err := zetae2econfig.RunnerFromConfig( @@ -150,17 +185,45 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } // wait for keygen to be completed - waitKeygenHeight(ctx, deployerRunner.CctxClient, logger) + // if setup is skipped, we assume that the keygen is already completed + if !skipSetup { + waitKeygenHeight(ctx, deployerRunner.CctxClient, logger) + } + + // query and set the TSS + deployerRunner.SetTSSAddresses() // setting up the networks - logger.Print("⚙️ setting up networks") - startTime := time.Now() + if !skipSetup { + logger.Print("⚙️ setting up networks") + startTime := time.Now() + deployerRunner.SetupEVM(contractsDeployed) + deployerRunner.SetZEVMContracts() + deployerRunner.MintUSDTOnEvm(10000) + logger.Print("✅ setup completed in %s", time.Since(startTime)) + deployerRunner.PrintContractAddresses() + } - deployerRunner.SetTSSAddresses() - deployerRunner.SetupEVM(contractsDeployed) - deployerRunner.SetZEVMContracts() - deployerRunner.MintUSDTOnEvm(10000) - logger.Print("✅ setup completed in %s", time.Since(startTime)) + // if a config output is specified, write the config + if configOut != "" { + newConfig := zetae2econfig.ExportContractsFromRunner(deployerRunner, conf) + configOut, err := filepath.Abs(configOut) + if err != nil { + panic(err) + } + + // write config into stdout + if err := config.WriteConfig(configOut, newConfig); err != nil { + panic(err) + } + + logger.Print("✅ config file written in %s", configOut) + } + + // if setup only, quit + if setupOnly { + os.Exit(0) + } // run tests var eg errgroup.Group diff --git a/cmd/zetae2e/local/utils.go b/cmd/zetae2e/local/utils.go index b1ac34924a..8e1ab210c1 100644 --- a/cmd/zetae2e/local/utils.go +++ b/cmd/zetae2e/local/utils.go @@ -2,6 +2,7 @@ package local import ( "context" + "path/filepath" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -27,6 +28,11 @@ func getConfig(cmd *cobra.Command) (config.Config, error) { return config.DefaultConfig(), nil } + configFile, err = filepath.Abs(configFile) + if err != nil { + return config.Config{}, err + } + return config.ReadConfig(configFile) } @@ -77,7 +83,7 @@ func waitKeygenHeight( cctxClient crosschaintypes.QueryClient, logger *runner.Logger, ) { - // wait for keygen to be completed. ~ height 30 + // wait for keygen to be completed keygenHeight := int64(60) logger.Print("⏳ wait height %v for keygen to be completed", keygenHeight) for { diff --git a/contrib/localnet/docker-compose.yml b/contrib/localnet/docker-compose.yml index a618bab292..14f1435776 100644 --- a/contrib/localnet/docker-compose.yml +++ b/contrib/localnet/docker-compose.yml @@ -6,7 +6,6 @@ networks: config: - subnet: 172.20.0.0/24 - services: rosetta: image: zetanode:latest diff --git a/contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild b/contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild index 3fb6b69e67..5cbccbc0a6 100644 --- a/contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild +++ b/contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild @@ -16,9 +16,7 @@ COPY contrib/localnet/orchestrator/start-upgrade.sh /work/ COPY contrib/localnet/orchestrator/restart-zetaclientd.sh /work/ RUN chmod +x /work/*.sh - -COPY --from=zeta /go/bin/old/smoketest /usr/local/bin/smoketest-old -COPY --from=zeta /go/bin/new/smoketest /usr/local/bin/smoketest-new -RUN chmod +x /usr/local/bin/smoketest-* +COPY --from=zeta /usr/local/bin/zetae2e /usr/local/bin/ +RUN chmod +x /usr/local/bin/zetae2e WORKDIR /work diff --git a/contrib/localnet/orchestrator/restart-zetaclientd.sh b/contrib/localnet/orchestrator/restart-zetaclientd.sh index d5f8b1becc..207eebf4aa 100644 --- a/contrib/localnet/orchestrator/restart-zetaclientd.sh +++ b/contrib/localnet/orchestrator/restart-zetaclientd.sh @@ -33,11 +33,13 @@ CURRENT_HEIGHT=0 while [[ $CURRENT_HEIGHT -lt $UPGRADE_HEIGHT ]] do - CURRENT_HEIGHT=$(curl zetacore0:26657/status | jq '.result.sync_info.latest_block_height' | tr -d '"') + CURRENT_HEIGHT=$(curl -s zetacore0:26657/status | jq '.result.sync_info.latest_block_height' | tr -d '"') + echo current height is "$CURRENT_HEIGHT", waiting for "$UPGRADE_HEIGHT" sleep 5 done -echo current height is "$CURRENT_HEIGHT", restarting zetaclients +echo upgrade height reached, restarting zetaclients + for NODE in "${CLIENT_LIST[@]}"; do ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem killall zetaclientd ssh -o "StrictHostKeyChecking no" "$NODE" -i ~/.ssh/localtest.pem "$GOPATH/bin/new/zetaclientd start < /dev/null > $HOME/zetaclient.log 2>&1 &" diff --git a/contrib/localnet/orchestrator/smoketest/config/config.go b/contrib/localnet/orchestrator/smoketest/config/config.go index 5685fe38c0..097bc58641 100644 --- a/contrib/localnet/orchestrator/smoketest/config/config.go +++ b/contrib/localnet/orchestrator/smoketest/config/config.go @@ -1,14 +1,12 @@ package config import ( + "errors" "os" "gopkg.in/yaml.v2" ) -// TODO: support pre-deployed addresses for zEVM contracts -// https://github.com/zeta-chain/node-private/issues/41 - // Config contains the configuration for the smoke test type Config struct { Accounts Accounts `yaml:"accounts"` @@ -55,6 +53,9 @@ type ZEVM struct { BTCZRC20Addr string `yaml:"btc_zrc20"` UniswapFactoryAddr string `yaml:"uniswap_factory"` UniswapRouterAddr string `yaml:"uniswap_router"` + ZEVMSwapAppAddr string `yaml:"zevm_swap_app"` + ContextAppAddr string `yaml:"context_app"` + TestDappAddr string `yaml:"test_dapp"` } func DefaultConfig() Config { @@ -77,6 +78,10 @@ func DefaultConfig() Config { // ReadConfig reads the config file func ReadConfig(file string) (config Config, err error) { + if file == "" { + return Config{}, errors.New("file name cannot be empty") + } + // #nosec G304 -- this is a config file b, err := os.ReadFile(file) if err != nil { @@ -91,6 +96,10 @@ func ReadConfig(file string) (config Config, err error) { // WriteConfig writes the config file func WriteConfig(file string, config Config) error { + if file == "" { + return errors.New("file name cannot be empty") + } + b, err := yaml.Marshal(config) if err != nil { return err diff --git a/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go b/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go index 0277710e69..9ee876a04e 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go +++ b/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go @@ -7,6 +7,9 @@ import ( "math/big" "time" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" @@ -65,7 +68,7 @@ func (sm *SmokeTestRunner) DepositBTC(testHeader bool) { panic(err) } amount2 := 0.05 + zetaclient.BtcDepositorFeeMin - _, err = sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount2, utxos[2:4], btc, sm.BTCDeployerAddress) + txHash2, err := sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount2, utxos[2:4], btc, sm.BTCDeployerAddress) if err != nil { panic(err) } @@ -86,25 +89,21 @@ func (sm *SmokeTestRunner) DepositBTC(testHeader bool) { sm.Logger.Info("testing if the deposit into BTC ZRC20 is successful...") - initialBalance, err := sm.BTCZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, txHash2.String(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + panic(fmt.Sprintf( + "expected mined status; got %s, message: %s", + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage), + ) + } + + balance, err := sm.BTCZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) if err != nil { panic(err) } - for { - time.Sleep(2 * time.Second) - balance, err := sm.BTCZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) - if err != nil { - panic(err) - } - diff := big.NewInt(0) - diff.Sub(balance, initialBalance) - sm.Logger.Info("BTC Difference in balance: %d", diff.Uint64()) - if diff.Cmp(big.NewInt(1.15*btcutil.SatoshiPerBitcoin)) != 0 { - sm.Logger.Info("waiting for BTC balance to show up in ZRC contract... current bal %d", balance) - } else { - sm.Logger.Info("BTC balance is in ZRC contract! Success") - break - } + if balance.Cmp(big.NewInt(0)) != 1 { + panic("balance should be positive") } // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks diff --git a/contrib/localnet/orchestrator/smoketest/runner/evm.go b/contrib/localnet/orchestrator/smoketest/runner/evm.go index fc0734e895..f2bb0aaea5 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/evm.go +++ b/contrib/localnet/orchestrator/smoketest/runner/evm.go @@ -110,7 +110,6 @@ func (sm *SmokeTestRunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg sm.Logger.Info(" Amount: %d", event.Amount) sm.Logger.Info(" Message: %x", event.Message) } - sm.Logger.Info("gas limit %d", sm.ZevmAuth.GasLimit) return tx.Hash() } diff --git a/contrib/localnet/orchestrator/smoketest/runner/runner.go b/contrib/localnet/orchestrator/smoketest/runner/runner.go index a09a351036..60698ac114 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/runner.go +++ b/contrib/localnet/orchestrator/smoketest/runner/runner.go @@ -306,3 +306,27 @@ func (sm *SmokeTestRunner) Lock() { func (sm *SmokeTestRunner) Unlock() { sm.mutex.Unlock() } + +// PrintContractAddresses prints the addresses of the contracts +// the printed contracts are grouped in a zevm and evm section +// there is a padding used to print the addresses at the same position +func (sm *SmokeTestRunner) PrintContractAddresses() { + // zevm contracts + sm.Logger.Print(" --- 📜zEVM contracts ---") + sm.Logger.Print("SystemContract: %s", sm.SystemContractAddr.Hex()) + sm.Logger.Print("ETHZRC20: %s", sm.ETHZRC20Addr.Hex()) + sm.Logger.Print("USDTZRC20: %s", sm.USDTZRC20Addr.Hex()) + sm.Logger.Print("BTCZRC20: %s", sm.BTCZRC20Addr.Hex()) + sm.Logger.Print("UniswapFactory: %s", sm.UniswapV2FactoryAddr.Hex()) + sm.Logger.Print("UniswapRouter: %s", sm.UniswapV2RouterAddr.Hex()) + sm.Logger.Print("ZEVMSwapApp: %s", sm.ZEVMSwapAppAddr.Hex()) + sm.Logger.Print("ContextApp: %s", sm.ContextAppAddr.Hex()) + sm.Logger.Print("TestDapp: %s", sm.TestDAppAddr.Hex()) + + // evm contracts + sm.Logger.Print(" --- 📜EVM contracts ---") + sm.Logger.Print("ZetaEth: %s", sm.ZetaEthAddr.Hex()) + sm.Logger.Print("ConnectorEth: %s", sm.ConnectorEthAddr.Hex()) + sm.Logger.Print("ERC20Custody: %s", sm.ERC20CustodyAddr.Hex()) + sm.Logger.Print("USDTERC20: %s", sm.USDTERC20Addr.Hex()) +} diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go index 80a7606ba2..5a266f3156 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go @@ -2,10 +2,11 @@ package runner import ( "math/big" + "strings" "time" + "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/accounts/abi/bind" - ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" @@ -15,6 +16,7 @@ import ( "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/contextapp" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/zevmswap" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -28,7 +30,14 @@ func (sm *SmokeTestRunner) SetTSSAddresses() { for { res, err = sm.ObserverClient.GetTssAddress(sm.Ctx, &observertypes.QueryGetTssAddressRequest{}) if err != nil { - sm.Logger.Info("cctxClient.TSS error %s", err.Error()) + // if error contains unknown method GetTssAddress for service, we might be using an older version of the chain for upgrade test + // we query the TSS address with legacy method + if strings.Contains(err.Error(), "unknown method GetTssAddress for service") { + sm.SetTSSAddressesLegacy() + return + } + + sm.Logger.Info("ObserverClient.TSS error %s", err.Error()) sm.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") time.Sleep(1 * time.Second) continue @@ -176,3 +185,29 @@ func (sm *SmokeTestRunner) SetupBTCZRC20() { } sm.BTCZRC20 = BTCZRC20 } + +// SetTSSAddressesLegacy set TSS addresses from information queried from ZetaChain using legacy TSS query +// TODO: remove this function after v12 once upgrade testing is no longer needed with v11 +func (sm *SmokeTestRunner) SetTSSAddressesLegacy() { + var err error + res := &crosschaintypes.QueryGetTssAddressResponse{} + for { + res, err = sm.CctxClient.GetTssAddress(sm.Ctx, &crosschaintypes.QueryGetTssAddressRequest{}) + if err != nil { + sm.Logger.Info("cctxClient.TSS (legacy) error %s", err.Error()) + sm.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") + time.Sleep(1 * time.Second) + continue + } + break + } + + tssAddress := ethcommon.HexToAddress(res.Eth) + btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, common.BitcoinRegnetParams) + if err != nil { + panic(err) + } + + sm.TSSAddress = tssAddress + sm.BTCTSSAddress = btcTSSAddress +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go index 166a6dfec2..1a1ce1aa3c 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go @@ -19,9 +19,9 @@ func TestCrosschainSwap(sm *runner.SmokeTestRunner) { // https://github.com/zeta-chain/node-private/issues/88 // it is kept as is for now to be consistent with the old implementation // if the tx fails due to already initialized, it will be ignored - txCreatePair, err := sm.UniswapV2Factory.CreatePair(sm.ZevmAuth, sm.USDTZRC20Addr, sm.BTCZRC20Addr) + _, err := sm.UniswapV2Factory.CreatePair(sm.ZevmAuth, sm.USDTZRC20Addr, sm.BTCZRC20Addr) if err != nil { - panic(err) + sm.Logger.Print("ℹ️create pair error") } txUSDTApprove, err := sm.USDTZRC20.Approve(sm.ZevmAuth, sm.UniswapV2RouterAddr, big.NewInt(1e18)) if err != nil { @@ -42,9 +42,6 @@ func TestCrosschainSwap(sm *runner.SmokeTestRunner) { panic(err) } - if receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, txCreatePair, sm.Logger, sm.ReceiptTimeout); receipt.Status != 1 { - panic("create pair failed") - } if receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, txUSDTApprove, sm.Logger, sm.ReceiptTimeout); receipt.Status != 1 { panic("usdt approve failed") } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_zrc20_swap.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_zrc20_swap.go index 1f96c46ff9..203fa1df0a 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_zrc20_swap.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_zrc20_swap.go @@ -17,10 +17,10 @@ func TestZRC20Swap(sm *runner.SmokeTestRunner) { // if the tx fails due to already initialized, it will be ignored tx, err := sm.UniswapV2Factory.CreatePair(sm.ZevmAuth, sm.USDTZRC20Addr, sm.ETHZRC20Addr) if err != nil { - panic(err) + sm.Logger.Print("ℹ️create pair error") + } else { + utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) } - receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) - //sm.Logger.Info("USDT-ETH pair receipt txhash %s status %d", receipt.TxHash, receipt.Status) usdtEthPair, err := sm.UniswapV2Factory.GetPair(&bind.CallOpts{}, sm.USDTZRC20Addr, sm.ETHZRC20Addr) if err != nil { @@ -32,7 +32,7 @@ func TestZRC20Swap(sm *runner.SmokeTestRunner) { if err != nil { panic(err) } - receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) sm.Logger.Info("USDT ZRC20 approval receipt txhash %s status %d", receipt.TxHash, receipt.Status) tx, err = sm.ETHZRC20.Approve(sm.ZevmAuth, sm.UniswapV2RouterAddr, big.NewInt(1e18)) diff --git a/contrib/localnet/orchestrator/start-upgrade.sh b/contrib/localnet/orchestrator/start-upgrade.sh index a9e123ad72..1d8c5aa570 100644 --- a/contrib/localnet/orchestrator/start-upgrade.sh +++ b/contrib/localnet/orchestrator/start-upgrade.sh @@ -1,42 +1,67 @@ #!/bin/bash -SMOKETEST_CMD=$1 +ZETAE2E_CMD=$1 echo "waiting for geth RPC to start..." -sleep 6 +sleep 2 + +# unlock the deployer account echo "funding deployer address 0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", value: web3.toWei(100,"ether")})' attach http://eth:8545 -echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 1 Ether" -geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth:8545 - -echo "waiting for 6s for the transaction to be mined" -sleep 6 -echo "the new balance of the deployer addrees:" -curl -sS http://eth:8545 \ - -X POST \ - -H "Content-Type: application/json" \ - --data '{"method":"eth_getBalance","params":["0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", "latest"],"id":1,"jsonrpc":"2.0"}' -curl -sS http://eth:8545 \ - -X POST \ - -H "Content-Type: application/json" \ - --data '{"method":"eth_getBalance","params":["0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", "latest"],"id":1,"jsonrpc":"2.0"}' -echo "running smoketest..." -smoketest-old "$SMOKETEST_CMD" -SMOKETEST_EXIT_CODE=$? -if [ $SMOKETEST_EXIT_CODE -ne 0 ]; then - echo "smoketest failed" + +# unlock erc20 tester accounts +echo "funding deployer address 0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6 with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6", value: web3.toWei(100,"ether")})' attach http://eth:8545 + +# unlock zeta tester accounts +echo "funding deployer address 0x5cC2fBb200A929B372e3016F1925DcF988E081fd with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x5cC2fBb200A929B372e3016F1925DcF988E081fd", value: web3.toWei(100,"ether")})' attach http://eth:8545 + +# unlock bitcoin tester accounts +echo "funding deployer address 0x283d810090EdF4043E75247eAeBcE848806237fD with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x283d810090EdF4043E75247eAeBcE848806237fD", value: web3.toWei(100,"ether")})' attach http://eth:8545 + +# unlock ethers tester accounts +echo "funding deployer address 0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A", value: web3.toWei(100,"ether")})' attach http://eth:8545 + +# unlock miscellaneous tests accounts +echo "funding deployer address 0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf", value: web3.toWei(100,"ether")})' attach http://eth:8545 + +# unlock advanced erc20 tests accounts +echo "funding deployer address 0xcC8487562AAc220ea4406196Ee902C7c076966af with 100 Ether" +geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea4406196Ee902C7c076966af", value: web3.toWei(100,"ether")})' attach http://eth:8545 + + +echo "running E2E command to setup the networks and populate the state..." + +zetae2e "$ZETAE2E_CMD" --config-out deployed.yml + +ZETAE2E_EXIT_CODE=$? +if [ $ZETAE2E_EXIT_CODE -ne 0 ]; then + echo "E2E setup failed" exit 1 fi +echo "E2E setup passed, waiting for upgrade height..." + # Restart zetaclients at upgrade height -/work/restart-zetaclientd.sh -u 400 -n 2 +/work/restart-zetaclientd.sh -u 180 -n 2 + +echo "waiting 10 seconds for node to restart..." + +sleep 10 + +echo "running E2E command to test the network after upgrade..." -smoketest-new "$SMOKETEST_CMD" --deployed --wait-for 405 +zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml -if [ $SMOKETEST_EXIT_CODE -eq 0 ]; then - echo "smoketest passed" +ZETAE2E_EXIT_CODE=$? +if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then + echo "E2E passed after upgrade" exit 0 else - echo "smoketest failed" + echo "E2E failed after upgrade" exit 1 fi \ No newline at end of file diff --git a/contrib/localnet/orchestrator/start.sh b/contrib/localnet/orchestrator/start.sh index e79cb3bb39..2c0901a2c2 100644 --- a/contrib/localnet/orchestrator/start.sh +++ b/contrib/localnet/orchestrator/start.sh @@ -33,22 +33,10 @@ geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0x90126d02E41c9eB2a10 echo "funding deployer address 0xcC8487562AAc220ea4406196Ee902C7c076966af with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xcC8487562AAc220ea4406196Ee902C7c076966af", value: web3.toWei(100,"ether")})' attach http://eth:8545 - # unlock the TSS account echo "funding TSS address 0xF421292cb0d3c97b90EEEADfcD660B893592c6A2 with 100 Ether" geth --exec 'eth.sendTransaction({from: eth.coinbase, to: "0xF421292cb0d3c97b90EEEADfcD660B893592c6A2", value: web3.toWei(100,"ether")})' attach http://eth:8545 -## wait for the transaction to be mined -#echo "waiting for 6s for the transaction to be mined" -#sleep 6 - -# note: uncomment the following lines to print the balance of the deployer address if debugging is needed -#echo "the new balance of the deployer address:" -#curl -sS http://eth:8545 \ -# -X POST \ -# -H "Content-Type: application/json" \ -# --data '{"method":"eth_getBalance","params":["0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", "latest"],"id":1,"jsonrpc":"2.0"}' - # run e2e tests echo "running e2e tests..." zetae2e "$ZETAE2E_CMD" @@ -56,6 +44,7 @@ ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then + cat /work/deployed.yml echo "e2e passed" exit 0 else diff --git a/contrib/localnet/scripts/genesis-stateful.sh b/contrib/localnet/scripts/genesis-stateful.sh index cf2923d5f2..5099fcfc4a 100755 --- a/contrib/localnet/scripts/genesis-stateful.sh +++ b/contrib/localnet/scripts/genesis-stateful.sh @@ -58,7 +58,7 @@ source ~/os-info.sh if [ $HOSTNAME != "zetacore0" ] then echo "Waiting for zetacore0 to create genesis.json" - sleep $((7*NUMOFNODES)) + sleep 10 echo "genesis.json created" fi @@ -91,7 +91,7 @@ then # 2. Add the observers , authorizations and required params to the genesis.json zetacored collect-observer-info - zetacored add-observer-list + zetacored add-observer-list --keygen-block 55 cat $HOME/.zetacored/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="azeta"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="azeta"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="azeta"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json @@ -103,8 +103,8 @@ then # set fungible admin account as admin for fungible token zetacored add-genesis-account zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk 100000000000000000000000000azeta zetacored add-genesis-account zeta1n0rn6sne54hv7w2uu93fl48ncyqz97d3kty6sh 100000000000000000000000000azeta # Funds the localnet_gov_admin account - cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][2]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json - + cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][0]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json + cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][1]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json # 3. Copy the genesis.json to all the nodes .And use it to create a gentx for every node zetacored gentx operator 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING @@ -151,36 +151,36 @@ then sed -i -e "/persistent_peers =/s/=.*/= \"$pps\"/" "$HOME"/.zetacored/config/config.toml fi -mkdir -p $DAEMON_HOME/zetavisor/genesis/bin -mkdir -p $DAEMON_HOME/zetavisor/upgrades/"$UpgradeName"/bin +mkdir -p $DAEMON_HOME/cosmovisor/genesis/bin +mkdir -p $DAEMON_HOME/cosmovisor/upgrades/"$UpgradeName"/bin -# Setup zetavisor +# Setup cosmovisor # Genesis -cp $GOPATH/bin/old/zetacored $DAEMON_HOME/zetavisor/genesis/bin -cp $GOPATH/bin/zetaclientd $DAEMON_HOME/zetavisor/genesis/bin +cp $GOPATH/bin/old/zetacored $DAEMON_HOME/cosmovisor/genesis/bin +cp $GOPATH/bin/zetaclientd $DAEMON_HOME/cosmovisor/genesis/bin #Upgrades -cp $GOPATH/bin/new/zetacored $DAEMON_HOME/zetavisor/upgrades/$UpgradeName/bin/ +cp $GOPATH/bin/new/zetacored $DAEMON_HOME/cosmovisor/upgrades/$UpgradeName/bin/ #Permissions -chmod +x $DAEMON_HOME/zetavisor/genesis/bin/zetacored -chmod +x $DAEMON_HOME/zetavisor/genesis/bin/zetaclientd -chmod +x $DAEMON_HOME/zetavisor/upgrades/$UpgradeName/bin/zetacored +chmod +x $DAEMON_HOME/cosmovisor/genesis/bin/zetacored +chmod +x $DAEMON_HOME/cosmovisor/genesis/bin/zetaclientd +chmod +x $DAEMON_HOME/cosmovisor/upgrades/$UpgradeName/bin/zetacored # 7 Start the nodes -zetavisor start --pruning=nothing --minimum-gas-prices=0.0001azeta --json-rpc.api eth,txpool,personal,net,debug,web3,miner --api.enable --home /root/.zetacored >> zetanode.log 2>&1 & +cosmovisor run start --pruning=nothing --minimum-gas-prices=0.0001azeta --json-rpc.api eth,txpool,personal,net,debug,web3,miner --api.enable --home /root/.zetacored >> zetanode.log 2>&1 & sleep 20 echo if [ $HOSTNAME = "zetacore0" ] then -/root/.zetacored/zetavisor/current/bin/zetacored tx gov submit-legacy-proposal software-upgrade $UpgradeName --from hotkey --deposit 100000000azeta --upgrade-height 400 --title $UpgradeName --description $UpgradeName --keyring-backend test --chain-id $CHAINID --yes --no-validate --fees=200azeta --broadcast-mode block +/root/.zetacored/cosmovisor/genesis/bin/zetacored tx gov submit-legacy-proposal software-upgrade $UpgradeName --from hotkey --deposit 100000000azeta --upgrade-height 180 --title $UpgradeName --description $UpgradeName --keyring-backend test --chain-id $CHAINID --yes --no-validate --fees=200azeta --broadcast-mode block fi sleep 8 -/root/.zetacored/zetavisor/current/bin/zetacored tx gov vote 1 yes --from operator --keyring-backend test --chain-id $CHAINID --yes --fees=200azeta --broadcast-mode block +/root/.zetacored/cosmovisor/genesis/bin/zetacored tx gov vote 1 yes --from operator --keyring-backend test --chain-id $CHAINID --yes --fees=200azeta --broadcast-mode block sleep 7 -/root/.zetacored/zetavisor/current/bin/zetacored query gov proposal 1 +/root/.zetacored/cosmovisor/genesis/bin/zetacored query gov proposal 1 tail -f zetanode.log \ No newline at end of file diff --git a/contrib/localnet/scripts/genesis-upgrade.sh b/contrib/localnet/scripts/genesis-upgrade.sh index 489d4f01b5..7e01983e66 100755 --- a/contrib/localnet/scripts/genesis-upgrade.sh +++ b/contrib/localnet/scripts/genesis-upgrade.sh @@ -88,6 +88,11 @@ then cat $HOME/.zetacored/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="500000000"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["gov"]["voting_params"]["voting_period"]="100s"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json + # set admin account + zetacored add-genesis-account zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk 100000000000000000000000000azeta + zetacored add-genesis-account zeta1n0rn6sne54hv7w2uu93fl48ncyqz97d3kty6sh 100000000000000000000000000azeta # Funds the localnet_gov_admin account + cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][0]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json + cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][1]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json # 3. Copy the genesis.json to all the nodes .And use it to create a gentx for every node zetacored gentx operator 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING diff --git a/contrib/localnet/scripts/start-zetaclientd-background.sh b/contrib/localnet/scripts/start-zetaclientd-background.sh index 76726958cc..74ee897fdf 100644 --- a/contrib/localnet/scripts/start-zetaclientd-background.sh +++ b/contrib/localnet/scripts/start-zetaclientd-background.sh @@ -7,8 +7,6 @@ HOSTNAME=$(hostname) cp /root/preparams/PreParams_$HOSTNAME.json /root/preParams.json num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" -#mv /root/zetacored/zetacored_$node /root/.zetacored -#mv /root/tss/$HOSTNAME /root/.tss echo "Wait for zetacore to exchange genesis file" sleep 30 @@ -20,13 +18,17 @@ if [ $HOSTNAME == "zetaclient0" ] then rm ~/.tss/* MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) - zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" + zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" zetaclientd start > $HOME/zetaclient.log 2>&1 & else num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) - SEED=$(curl --retry 10 --retry-delay 5 --retry-connrefused -s zetaclient0:8123/p2p) + SEED="" + while [ -z "$SEED" ] + do + SEED=$(curl --retry 10 --retry-delay 5 --retry-connrefused -s zetaclient0:8123/p2p) + done rm ~/.tss/* zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 0 zetaclientd start > $HOME/zetaclient.log 2>&1 & diff --git a/contrib/localnet/scripts/start-zetaclientd-genesis.sh b/contrib/localnet/scripts/start-zetaclientd-genesis.sh index 1109acaf37..7c23cd0673 100755 --- a/contrib/localnet/scripts/start-zetaclientd-genesis.sh +++ b/contrib/localnet/scripts/start-zetaclientd-genesis.sh @@ -13,8 +13,6 @@ fi cp /root/preparams/PreParams_$HOSTNAME.json /root/preParams.json num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" -#mv /root/zetacored/zetacored_$node /root/.zetacored -#mv /root/tss/$HOSTNAME /root/.tss echo "Wait for zetacore to exchange genesis file" sleep 40 @@ -26,7 +24,7 @@ if [ $HOSTNAME == "zetaclient0" ] then rm ~/.tss/* MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) - zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --keyring-backend "$BACKEND" + zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --keyring-backend "$BACKEND" zetaclientd start else num=$(echo $HOSTNAME | tr -dc '0-9') diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 6d8b1c4e18..cb87e0dfc4 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -26696,6 +26696,25 @@ paths: type: string tags: - Query + /zeta-chain/crosschain/get_tss_address: + get: + summary: |- + GetTssAddress queries the tss address of the module. + Deprecated: Moved to observer + TODO: remove after v12 once upgrade testing is no longer needed with v11 + https://github.com/zeta-chain/node/issues/1547 + operationId: Query_GetTssAddress + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/zetacorecrosschainQueryGetTssAddressResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + tags: + - Query /zeta-chain/crosschain/in_tx_hash_to_cctx_data/{inTxHash}: get: summary: Queries a InTxHashToCctx data by index. @@ -27806,7 +27825,7 @@ paths: "200": description: A successful response. schema: - $ref: '#/definitions/observerQueryGetTssAddressResponse' + $ref: '#/definitions/zetacoreobserverQueryGetTssAddressResponse' default: description: An unexpected error response. schema: @@ -51622,13 +51641,6 @@ definitions: type: string btc: type: string - observerQueryGetTssAddressResponse: - type: object - properties: - eth: - type: string - btc: - type: string observerQueryHasVotedResponse: type: object properties: @@ -51788,6 +51800,17 @@ definitions: enabled: type: boolean description: Params defines the parameters for the module. + zetacorecrosschainQueryGetTssAddressResponse: + type: object + properties: + eth: + type: string + btc: + type: string + title: |- + Deprecated: Moved to observer + TODO: remove after v12 once upgrade testing is no longer needed with v11 + https://github.com/zeta-chain/node/issues/1547 zetacorecrosschainQueryParamsResponse: type: object properties: @@ -51862,6 +51885,13 @@ definitions: type: string format: int64 description: Params defines the parameters for the module. + zetacoreobserverQueryGetTssAddressResponse: + type: object + properties: + eth: + type: string + btc: + type: string zetacoreobserverQueryParamsResponse: type: object properties: diff --git a/proto/crosschain/query.proto b/proto/crosschain/query.proto index c9eee26378..0df9d8a0b7 100644 --- a/proto/crosschain/query.proto +++ b/proto/crosschain/query.proto @@ -16,6 +16,14 @@ option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; // Query defines the gRPC querier service. service Query { + // GetTssAddress queries the tss address of the module. + // Deprecated: Moved to observer + // TODO: remove after v12 once upgrade testing is no longer needed with v11 + // https://github.com/zeta-chain/node/issues/1547 + rpc GetTssAddress(QueryGetTssAddressRequest) returns (QueryGetTssAddressResponse) { + option (google.api.http).get = "/zeta-chain/crosschain/get_tss_address"; + } + // Parameters queries the parameters of the module. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/zeta-chain/crosschain/params"; @@ -114,6 +122,19 @@ service Query { } } +// Deprecated: Moved to observer +// TODO: remove after v12 once upgrade testing is no longer needed with v11 +// https://github.com/zeta-chain/node/issues/1547 +message QueryGetTssAddressRequest {} + +// Deprecated: Moved to observer +// TODO: remove after v12 once upgrade testing is no longer needed with v11 +// https://github.com/zeta-chain/node/issues/1547 +message QueryGetTssAddressResponse { + string eth = 1; + string btc = 2; +} + message QueryZetaAccountingRequest {} message QueryZetaAccountingResponse { diff --git a/typescript/crosschain/query_pb.d.ts b/typescript/crosschain/query_pb.d.ts index 17bb54ef27..52d504e4e4 100644 --- a/typescript/crosschain/query_pb.d.ts +++ b/typescript/crosschain/query_pb.d.ts @@ -14,6 +14,62 @@ import type { CrossChainTx } from "./cross_chain_tx_pb.js"; import type { GasPrice } from "./gas_price_pb.js"; import type { LastBlockHeight } from "./last_block_height_pb.js"; +/** + * Deprecated: Moved to observer + * TODO: remove after v12 once upgrade testing is no longer needed with v11 + * https://github.com/zeta-chain/node/issues/1547 + * + * @generated from message zetachain.zetacore.crosschain.QueryGetTssAddressRequest + */ +export declare class QueryGetTssAddressRequest extends Message { + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.QueryGetTssAddressRequest"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetTssAddressRequest; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetTssAddressRequest; + + static fromJsonString(jsonString: string, options?: Partial): QueryGetTssAddressRequest; + + static equals(a: QueryGetTssAddressRequest | PlainMessage | undefined, b: QueryGetTssAddressRequest | PlainMessage | undefined): boolean; +} + +/** + * Deprecated: Moved to observer + * TODO: remove after v12 once upgrade testing is no longer needed with v11 + * https://github.com/zeta-chain/node/issues/1547 + * + * @generated from message zetachain.zetacore.crosschain.QueryGetTssAddressResponse + */ +export declare class QueryGetTssAddressResponse extends Message { + /** + * @generated from field: string eth = 1; + */ + eth: string; + + /** + * @generated from field: string btc = 2; + */ + btc: string; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.QueryGetTssAddressResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryGetTssAddressResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryGetTssAddressResponse; + + static fromJsonString(jsonString: string, options?: Partial): QueryGetTssAddressResponse; + + static equals(a: QueryGetTssAddressResponse | PlainMessage | undefined, b: QueryGetTssAddressResponse | PlainMessage | undefined): boolean; +} + /** * @generated from message zetachain.zetacore.crosschain.QueryZetaAccountingRequest */ diff --git a/x/crosschain/keeper/grpc_query.go b/x/crosschain/keeper/grpc_query.go index 720f65c8f7..3b2d06620e 100644 --- a/x/crosschain/keeper/grpc_query.go +++ b/x/crosschain/keeper/grpc_query.go @@ -1,7 +1,19 @@ package keeper import ( + "context" + "github.com/zeta-chain/zetacore/x/crosschain/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var _ types.QueryServer = Keeper{} + +// GetTssAddress returns the tss address +// Deprecated: GetTssAddress returns the tss address +// TODO: remove after v12 once upgrade testing is no longer needed with v11 +// https://github.com/zeta-chain/node/issues/1547 +func (k Keeper) GetTssAddress(_ context.Context, _ *types.QueryGetTssAddressRequest) (*types.QueryGetTssAddressResponse, error) { + return nil, status.Error(codes.Unimplemented, "Deprecated") +} diff --git a/x/crosschain/types/query.pb.go b/x/crosschain/types/query.pb.go index 7273180766..e2dc8505bf 100644 --- a/x/crosschain/types/query.pb.go +++ b/x/crosschain/types/query.pb.go @@ -31,6 +31,100 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// Deprecated: Moved to observer +// TODO: remove after v12 once upgrade testing is no longer needed with v11 +// https://github.com/zeta-chain/node/issues/1547 +type QueryGetTssAddressRequest struct { +} + +func (m *QueryGetTssAddressRequest) Reset() { *m = QueryGetTssAddressRequest{} } +func (m *QueryGetTssAddressRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetTssAddressRequest) ProtoMessage() {} +func (*QueryGetTssAddressRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{0} +} +func (m *QueryGetTssAddressRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetTssAddressRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetTssAddressRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetTssAddressRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetTssAddressRequest.Merge(m, src) +} +func (m *QueryGetTssAddressRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetTssAddressRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetTssAddressRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetTssAddressRequest proto.InternalMessageInfo + +// Deprecated: Moved to observer +// TODO: remove after v12 once upgrade testing is no longer needed with v11 +// https://github.com/zeta-chain/node/issues/1547 +type QueryGetTssAddressResponse struct { + Eth string `protobuf:"bytes,1,opt,name=eth,proto3" json:"eth,omitempty"` + Btc string `protobuf:"bytes,2,opt,name=btc,proto3" json:"btc,omitempty"` +} + +func (m *QueryGetTssAddressResponse) Reset() { *m = QueryGetTssAddressResponse{} } +func (m *QueryGetTssAddressResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetTssAddressResponse) ProtoMessage() {} +func (*QueryGetTssAddressResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_65a992045e92a606, []int{1} +} +func (m *QueryGetTssAddressResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetTssAddressResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetTssAddressResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryGetTssAddressResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetTssAddressResponse.Merge(m, src) +} +func (m *QueryGetTssAddressResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetTssAddressResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetTssAddressResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetTssAddressResponse proto.InternalMessageInfo + +func (m *QueryGetTssAddressResponse) GetEth() string { + if m != nil { + return m.Eth + } + return "" +} + +func (m *QueryGetTssAddressResponse) GetBtc() string { + if m != nil { + return m.Btc + } + return "" +} + type QueryZetaAccountingRequest struct { } @@ -38,7 +132,7 @@ func (m *QueryZetaAccountingRequest) Reset() { *m = QueryZetaAccountingR func (m *QueryZetaAccountingRequest) String() string { return proto.CompactTextString(m) } func (*QueryZetaAccountingRequest) ProtoMessage() {} func (*QueryZetaAccountingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{0} + return fileDescriptor_65a992045e92a606, []int{2} } func (m *QueryZetaAccountingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +169,7 @@ func (m *QueryZetaAccountingResponse) Reset() { *m = QueryZetaAccounting func (m *QueryZetaAccountingResponse) String() string { return proto.CompactTextString(m) } func (*QueryZetaAccountingResponse) ProtoMessage() {} func (*QueryZetaAccountingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{1} + return fileDescriptor_65a992045e92a606, []int{3} } func (m *QueryZetaAccountingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -119,7 +213,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{2} + return fileDescriptor_65a992045e92a606, []int{4} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -158,7 +252,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{3} + return fileDescriptor_65a992045e92a606, []int{5} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -203,7 +297,7 @@ func (m *QueryGetOutTxTrackerRequest) Reset() { *m = QueryGetOutTxTracke func (m *QueryGetOutTxTrackerRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetOutTxTrackerRequest) ProtoMessage() {} func (*QueryGetOutTxTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{4} + return fileDescriptor_65a992045e92a606, []int{6} } func (m *QueryGetOutTxTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -254,7 +348,7 @@ func (m *QueryGetOutTxTrackerResponse) Reset() { *m = QueryGetOutTxTrack func (m *QueryGetOutTxTrackerResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetOutTxTrackerResponse) ProtoMessage() {} func (*QueryGetOutTxTrackerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{5} + return fileDescriptor_65a992045e92a606, []int{7} } func (m *QueryGetOutTxTrackerResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -298,7 +392,7 @@ func (m *QueryAllOutTxTrackerRequest) Reset() { *m = QueryAllOutTxTracke func (m *QueryAllOutTxTrackerRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerRequest) ProtoMessage() {} func (*QueryAllOutTxTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{6} + return fileDescriptor_65a992045e92a606, []int{8} } func (m *QueryAllOutTxTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -343,7 +437,7 @@ func (m *QueryAllOutTxTrackerResponse) Reset() { *m = QueryAllOutTxTrack func (m *QueryAllOutTxTrackerResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerResponse) ProtoMessage() {} func (*QueryAllOutTxTrackerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{7} + return fileDescriptor_65a992045e92a606, []int{9} } func (m *QueryAllOutTxTrackerResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -395,7 +489,7 @@ func (m *QueryAllOutTxTrackerByChainRequest) Reset() { *m = QueryAllOutT func (m *QueryAllOutTxTrackerByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerByChainRequest) ProtoMessage() {} func (*QueryAllOutTxTrackerByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{8} + return fileDescriptor_65a992045e92a606, []int{10} } func (m *QueryAllOutTxTrackerByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -447,7 +541,7 @@ func (m *QueryAllOutTxTrackerByChainResponse) Reset() { *m = QueryAllOut func (m *QueryAllOutTxTrackerByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerByChainResponse) ProtoMessage() {} func (*QueryAllOutTxTrackerByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{9} + return fileDescriptor_65a992045e92a606, []int{11} } func (m *QueryAllOutTxTrackerByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -499,7 +593,7 @@ func (m *QueryAllInTxTrackerByChainRequest) Reset() { *m = QueryAllInTxT func (m *QueryAllInTxTrackerByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackerByChainRequest) ProtoMessage() {} func (*QueryAllInTxTrackerByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{10} + return fileDescriptor_65a992045e92a606, []int{12} } func (m *QueryAllInTxTrackerByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -551,7 +645,7 @@ func (m *QueryAllInTxTrackerByChainResponse) Reset() { *m = QueryAllInTx func (m *QueryAllInTxTrackerByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackerByChainResponse) ProtoMessage() {} func (*QueryAllInTxTrackerByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{11} + return fileDescriptor_65a992045e92a606, []int{13} } func (m *QueryAllInTxTrackerByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -602,7 +696,7 @@ func (m *QueryAllInTxTrackersRequest) Reset() { *m = QueryAllInTxTracker func (m *QueryAllInTxTrackersRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackersRequest) ProtoMessage() {} func (*QueryAllInTxTrackersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{12} + return fileDescriptor_65a992045e92a606, []int{14} } func (m *QueryAllInTxTrackersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -647,7 +741,7 @@ func (m *QueryAllInTxTrackersResponse) Reset() { *m = QueryAllInTxTracke func (m *QueryAllInTxTrackersResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackersResponse) ProtoMessage() {} func (*QueryAllInTxTrackersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{13} + return fileDescriptor_65a992045e92a606, []int{15} } func (m *QueryAllInTxTrackersResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -698,7 +792,7 @@ func (m *QueryGetInTxHashToCctxRequest) Reset() { *m = QueryGetInTxHashT func (m *QueryGetInTxHashToCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetInTxHashToCctxRequest) ProtoMessage() {} func (*QueryGetInTxHashToCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{14} + return fileDescriptor_65a992045e92a606, []int{16} } func (m *QueryGetInTxHashToCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -742,7 +836,7 @@ func (m *QueryGetInTxHashToCctxResponse) Reset() { *m = QueryGetInTxHash func (m *QueryGetInTxHashToCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetInTxHashToCctxResponse) ProtoMessage() {} func (*QueryGetInTxHashToCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{15} + return fileDescriptor_65a992045e92a606, []int{17} } func (m *QueryGetInTxHashToCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -786,7 +880,7 @@ func (m *QueryInTxHashToCctxDataRequest) Reset() { *m = QueryInTxHashToC func (m *QueryInTxHashToCctxDataRequest) String() string { return proto.CompactTextString(m) } func (*QueryInTxHashToCctxDataRequest) ProtoMessage() {} func (*QueryInTxHashToCctxDataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{16} + return fileDescriptor_65a992045e92a606, []int{18} } func (m *QueryInTxHashToCctxDataRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -830,7 +924,7 @@ func (m *QueryInTxHashToCctxDataResponse) Reset() { *m = QueryInTxHashTo func (m *QueryInTxHashToCctxDataResponse) String() string { return proto.CompactTextString(m) } func (*QueryInTxHashToCctxDataResponse) ProtoMessage() {} func (*QueryInTxHashToCctxDataResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{17} + return fileDescriptor_65a992045e92a606, []int{19} } func (m *QueryInTxHashToCctxDataResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -874,7 +968,7 @@ func (m *QueryAllInTxHashToCctxRequest) Reset() { *m = QueryAllInTxHashT func (m *QueryAllInTxHashToCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxHashToCctxRequest) ProtoMessage() {} func (*QueryAllInTxHashToCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{18} + return fileDescriptor_65a992045e92a606, []int{20} } func (m *QueryAllInTxHashToCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -919,7 +1013,7 @@ func (m *QueryAllInTxHashToCctxResponse) Reset() { *m = QueryAllInTxHash func (m *QueryAllInTxHashToCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxHashToCctxResponse) ProtoMessage() {} func (*QueryAllInTxHashToCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{19} + return fileDescriptor_65a992045e92a606, []int{21} } func (m *QueryAllInTxHashToCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -970,7 +1064,7 @@ func (m *QueryGetGasPriceRequest) Reset() { *m = QueryGetGasPriceRequest func (m *QueryGetGasPriceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetGasPriceRequest) ProtoMessage() {} func (*QueryGetGasPriceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{20} + return fileDescriptor_65a992045e92a606, []int{22} } func (m *QueryGetGasPriceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1014,7 +1108,7 @@ func (m *QueryGetGasPriceResponse) Reset() { *m = QueryGetGasPriceRespon func (m *QueryGetGasPriceResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetGasPriceResponse) ProtoMessage() {} func (*QueryGetGasPriceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{21} + return fileDescriptor_65a992045e92a606, []int{23} } func (m *QueryGetGasPriceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1058,7 +1152,7 @@ func (m *QueryAllGasPriceRequest) Reset() { *m = QueryAllGasPriceRequest func (m *QueryAllGasPriceRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllGasPriceRequest) ProtoMessage() {} func (*QueryAllGasPriceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{22} + return fileDescriptor_65a992045e92a606, []int{24} } func (m *QueryAllGasPriceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1103,7 +1197,7 @@ func (m *QueryAllGasPriceResponse) Reset() { *m = QueryAllGasPriceRespon func (m *QueryAllGasPriceResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllGasPriceResponse) ProtoMessage() {} func (*QueryAllGasPriceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{23} + return fileDescriptor_65a992045e92a606, []int{25} } func (m *QueryAllGasPriceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1154,7 +1248,7 @@ func (m *QueryGetLastBlockHeightRequest) Reset() { *m = QueryGetLastBloc func (m *QueryGetLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightRequest) ProtoMessage() {} func (*QueryGetLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{24} + return fileDescriptor_65a992045e92a606, []int{26} } func (m *QueryGetLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1198,7 +1292,7 @@ func (m *QueryGetLastBlockHeightResponse) Reset() { *m = QueryGetLastBlo func (m *QueryGetLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightResponse) ProtoMessage() {} func (*QueryGetLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{25} + return fileDescriptor_65a992045e92a606, []int{27} } func (m *QueryGetLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1242,7 +1336,7 @@ func (m *QueryAllLastBlockHeightRequest) Reset() { *m = QueryAllLastBloc func (m *QueryAllLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightRequest) ProtoMessage() {} func (*QueryAllLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{26} + return fileDescriptor_65a992045e92a606, []int{28} } func (m *QueryAllLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1287,7 +1381,7 @@ func (m *QueryAllLastBlockHeightResponse) Reset() { *m = QueryAllLastBlo func (m *QueryAllLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightResponse) ProtoMessage() {} func (*QueryAllLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{27} + return fileDescriptor_65a992045e92a606, []int{29} } func (m *QueryAllLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1338,7 +1432,7 @@ func (m *QueryGetCctxRequest) Reset() { *m = QueryGetCctxRequest{} } func (m *QueryGetCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxRequest) ProtoMessage() {} func (*QueryGetCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{28} + return fileDescriptor_65a992045e92a606, []int{30} } func (m *QueryGetCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1383,7 +1477,7 @@ func (m *QueryGetCctxByNonceRequest) Reset() { *m = QueryGetCctxByNonceR func (m *QueryGetCctxByNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxByNonceRequest) ProtoMessage() {} func (*QueryGetCctxByNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{29} + return fileDescriptor_65a992045e92a606, []int{31} } func (m *QueryGetCctxByNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1434,7 +1528,7 @@ func (m *QueryGetCctxResponse) Reset() { *m = QueryGetCctxResponse{} } func (m *QueryGetCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxResponse) ProtoMessage() {} func (*QueryGetCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{30} + return fileDescriptor_65a992045e92a606, []int{32} } func (m *QueryGetCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1478,7 +1572,7 @@ func (m *QueryAllCctxRequest) Reset() { *m = QueryAllCctxRequest{} } func (m *QueryAllCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxRequest) ProtoMessage() {} func (*QueryAllCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{31} + return fileDescriptor_65a992045e92a606, []int{33} } func (m *QueryAllCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1523,7 +1617,7 @@ func (m *QueryAllCctxResponse) Reset() { *m = QueryAllCctxResponse{} } func (m *QueryAllCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxResponse) ProtoMessage() {} func (*QueryAllCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{32} + return fileDescriptor_65a992045e92a606, []int{34} } func (m *QueryAllCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1575,7 +1669,7 @@ func (m *QueryListCctxPendingRequest) Reset() { *m = QueryListCctxPendin func (m *QueryListCctxPendingRequest) String() string { return proto.CompactTextString(m) } func (*QueryListCctxPendingRequest) ProtoMessage() {} func (*QueryListCctxPendingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{33} + return fileDescriptor_65a992045e92a606, []int{35} } func (m *QueryListCctxPendingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1627,7 +1721,7 @@ func (m *QueryListCctxPendingResponse) Reset() { *m = QueryListCctxPendi func (m *QueryListCctxPendingResponse) String() string { return proto.CompactTextString(m) } func (*QueryListCctxPendingResponse) ProtoMessage() {} func (*QueryListCctxPendingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{34} + return fileDescriptor_65a992045e92a606, []int{36} } func (m *QueryListCctxPendingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1677,7 +1771,7 @@ func (m *QueryLastZetaHeightRequest) Reset() { *m = QueryLastZetaHeightR func (m *QueryLastZetaHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightRequest) ProtoMessage() {} func (*QueryLastZetaHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{35} + return fileDescriptor_65a992045e92a606, []int{37} } func (m *QueryLastZetaHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1714,7 +1808,7 @@ func (m *QueryLastZetaHeightResponse) Reset() { *m = QueryLastZetaHeight func (m *QueryLastZetaHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightResponse) ProtoMessage() {} func (*QueryLastZetaHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{36} + return fileDescriptor_65a992045e92a606, []int{38} } func (m *QueryLastZetaHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1759,7 +1853,7 @@ func (m *QueryConvertGasToZetaRequest) Reset() { *m = QueryConvertGasToZ func (m *QueryConvertGasToZetaRequest) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaRequest) ProtoMessage() {} func (*QueryConvertGasToZetaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{37} + return fileDescriptor_65a992045e92a606, []int{39} } func (m *QueryConvertGasToZetaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1812,7 +1906,7 @@ func (m *QueryConvertGasToZetaResponse) Reset() { *m = QueryConvertGasTo func (m *QueryConvertGasToZetaResponse) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaResponse) ProtoMessage() {} func (*QueryConvertGasToZetaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{38} + return fileDescriptor_65a992045e92a606, []int{40} } func (m *QueryConvertGasToZetaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1869,7 +1963,7 @@ func (m *QueryMessagePassingProtocolFeeRequest) Reset() { *m = QueryMess func (m *QueryMessagePassingProtocolFeeRequest) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeRequest) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{39} + return fileDescriptor_65a992045e92a606, []int{41} } func (m *QueryMessagePassingProtocolFeeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1908,7 +2002,7 @@ func (m *QueryMessagePassingProtocolFeeResponse) Reset() { func (m *QueryMessagePassingProtocolFeeResponse) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeResponse) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{40} + return fileDescriptor_65a992045e92a606, []int{42} } func (m *QueryMessagePassingProtocolFeeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1945,6 +2039,8 @@ func (m *QueryMessagePassingProtocolFeeResponse) GetFeeInZeta() string { } func init() { + proto.RegisterType((*QueryGetTssAddressRequest)(nil), "zetachain.zetacore.crosschain.QueryGetTssAddressRequest") + proto.RegisterType((*QueryGetTssAddressResponse)(nil), "zetachain.zetacore.crosschain.QueryGetTssAddressResponse") proto.RegisterType((*QueryZetaAccountingRequest)(nil), "zetachain.zetacore.crosschain.QueryZetaAccountingRequest") proto.RegisterType((*QueryZetaAccountingResponse)(nil), "zetachain.zetacore.crosschain.QueryZetaAccountingResponse") proto.RegisterType((*QueryParamsRequest)(nil), "zetachain.zetacore.crosschain.QueryParamsRequest") @@ -1991,119 +2087,124 @@ func init() { func init() { proto.RegisterFile("crosschain/query.proto", fileDescriptor_65a992045e92a606) } var fileDescriptor_65a992045e92a606 = []byte{ - // 1782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xdf, 0x6f, 0x14, 0x55, - 0x14, 0xee, 0xed, 0xd2, 0x52, 0x6e, 0x0b, 0x95, 0x4b, 0x85, 0x3a, 0xb4, 0x5b, 0x98, 0x5a, 0x5a, - 0xc1, 0xee, 0xd0, 0x02, 0x45, 0xa0, 0x18, 0xb7, 0x45, 0x0a, 0xb1, 0x40, 0xdd, 0xd4, 0x68, 0x30, - 0x66, 0x73, 0x3b, 0x3b, 0xce, 0x4e, 0x98, 0xce, 0x94, 0x9d, 0x59, 0xd2, 0xd2, 0xf4, 0x85, 0x07, - 0x5f, 0x7c, 0x31, 0x21, 0xd1, 0x17, 0x5f, 0x8d, 0x3e, 0xf8, 0xe0, 0x83, 0xd1, 0x07, 0x13, 0x8c, - 0x51, 0x91, 0x47, 0x12, 0x13, 0x63, 0x34, 0x31, 0x06, 0xfc, 0x43, 0xcc, 0xdc, 0x39, 0xb3, 0x7b, - 0xe7, 0xd7, 0xee, 0xed, 0x76, 0x79, 0xe0, 0xa9, 0x3b, 0x73, 0xef, 0x39, 0xe7, 0xfb, 0xbe, 0xfb, - 0x63, 0xce, 0x39, 0xc5, 0x07, 0xd5, 0x8a, 0xed, 0x38, 0x6a, 0x99, 0x1a, 0x96, 0x72, 0xbb, 0xaa, - 0x55, 0x36, 0x72, 0x6b, 0x15, 0xdb, 0xb5, 0xc9, 0xf0, 0x5d, 0xcd, 0xa5, 0xec, 0x75, 0x8e, 0xfd, - 0xb2, 0x2b, 0x5a, 0xae, 0x3e, 0x55, 0x3a, 0xae, 0xda, 0xce, 0xaa, 0xed, 0x28, 0x2b, 0xd4, 0xd1, - 0x7c, 0x3b, 0xe5, 0xce, 0xd4, 0x8a, 0xe6, 0xd2, 0x29, 0x65, 0x8d, 0xea, 0x86, 0x45, 0x5d, 0xc3, - 0xb6, 0x7c, 0x57, 0xd2, 0x08, 0x17, 0x82, 0xfd, 0x2c, 0xb2, 0xdf, 0x45, 0x77, 0x1d, 0x26, 0x48, - 0xdc, 0x04, 0x9d, 0x3a, 0xc5, 0xb5, 0x8a, 0xa1, 0x6a, 0x30, 0x36, 0xca, 0x8d, 0x31, 0x9b, 0x62, - 0x99, 0x3a, 0xe5, 0xa2, 0x6b, 0x17, 0x55, 0xb5, 0xe6, 0x20, 0x1b, 0x9b, 0xe4, 0x56, 0xa8, 0x7a, - 0x4b, 0xab, 0xc0, 0xb8, 0xcc, 0x8d, 0x9b, 0xd4, 0x71, 0x8b, 0x2b, 0xa6, 0xad, 0xde, 0x2a, 0x96, - 0x35, 0x43, 0x2f, 0xbb, 0x09, 0x28, 0xed, 0xaa, 0x1b, 0x77, 0x72, 0x88, 0x9b, 0xb0, 0x46, 0x2b, - 0x74, 0xd5, 0x81, 0x81, 0x01, 0xdd, 0xd6, 0x6d, 0xf6, 0x53, 0xf1, 0x7e, 0xc1, 0xdb, 0x21, 0xdd, - 0xb6, 0x75, 0x53, 0x53, 0xe8, 0x9a, 0xa1, 0x50, 0xcb, 0xb2, 0x5d, 0x26, 0x09, 0xd8, 0xc8, 0x43, - 0x58, 0x7a, 0xdb, 0x53, 0xed, 0xa6, 0xe6, 0xd2, 0xbc, 0xaa, 0xda, 0x55, 0xcb, 0x35, 0x2c, 0xbd, - 0xa0, 0xdd, 0xae, 0x6a, 0x8e, 0x2b, 0x5f, 0xc3, 0x87, 0x13, 0x47, 0x9d, 0x35, 0xdb, 0x72, 0x34, - 0x92, 0xc3, 0x07, 0xe8, 0x8a, 0x5d, 0x71, 0xb5, 0x52, 0xd1, 0x5b, 0x9b, 0x22, 0x5d, 0xf5, 0x66, - 0x0c, 0xa2, 0x23, 0x68, 0x62, 0x4f, 0x61, 0x3f, 0x0c, 0x31, 0x5b, 0x36, 0x20, 0x0f, 0x60, 0xc2, - 0xdc, 0x2d, 0x31, 0xd4, 0x41, 0x90, 0x9b, 0xf8, 0x40, 0xe8, 0x2d, 0x38, 0x9f, 0xc7, 0xdd, 0x3e, - 0x3b, 0xe6, 0xaf, 0x77, 0x7a, 0x2c, 0xd7, 0x70, 0x27, 0xe4, 0x7c, 0xf3, 0xb9, 0x5d, 0x8f, 0xfe, - 0x19, 0xe9, 0x28, 0x80, 0x69, 0x8d, 0xc0, 0x82, 0xe6, 0xde, 0xa8, 0xba, 0xcb, 0xeb, 0xcb, 0xbe, - 0x92, 0x10, 0x9a, 0x0c, 0xe2, 0xdd, 0xcc, 0xf8, 0xea, 0x25, 0x16, 0x24, 0x53, 0x08, 0x1e, 0xc9, - 0x00, 0xee, 0xb2, 0x6c, 0x4b, 0xd5, 0x06, 0x3b, 0x8f, 0xa0, 0x89, 0x5d, 0x05, 0xff, 0x41, 0xae, - 0xe2, 0xa1, 0x64, 0x77, 0x80, 0xf9, 0x1d, 0xdc, 0x67, 0x73, 0xef, 0x01, 0xf9, 0x89, 0x26, 0xc8, - 0x79, 0x57, 0x80, 0x3f, 0xe4, 0x46, 0xd6, 0x80, 0x45, 0xde, 0x34, 0x93, 0x58, 0x5c, 0xc6, 0xb8, - 0xbe, 0xd7, 0x21, 0xe6, 0xb1, 0x9c, 0x7f, 0x30, 0x72, 0xde, 0xc1, 0xc8, 0xf9, 0x07, 0x0a, 0x0e, - 0x46, 0x6e, 0x89, 0xea, 0x1a, 0xd8, 0x16, 0x38, 0x4b, 0xf9, 0x01, 0x02, 0x7a, 0xb1, 0x38, 0xa9, - 0xf4, 0x32, 0x6d, 0xa0, 0x47, 0x16, 0x42, 0xf8, 0x3b, 0x19, 0xfe, 0xf1, 0xa6, 0xf8, 0x7d, 0x4c, - 0x21, 0x02, 0xf7, 0x10, 0x96, 0x93, 0x08, 0xcc, 0x6d, 0xcc, 0x7b, 0x48, 0x02, 0xbd, 0x06, 0x70, - 0x17, 0x43, 0x06, 0x6b, 0xee, 0x3f, 0x44, 0x54, 0xec, 0x6c, 0x59, 0xc5, 0x5f, 0x11, 0x1e, 0x6d, - 0x08, 0xe2, 0x39, 0x11, 0xf3, 0x23, 0x84, 0x8f, 0x06, 0x3c, 0xae, 0x5a, 0x69, 0x5a, 0xbe, 0x84, - 0x7b, 0xfc, 0x4b, 0xd4, 0x28, 0x85, 0x8f, 0x50, 0xa9, 0x6d, 0x82, 0xfe, 0xc4, 0xad, 0x6a, 0x12, - 0x10, 0xd0, 0xb3, 0x80, 0x7b, 0x0d, 0x2b, 0x2a, 0xe7, 0xf1, 0x26, 0x72, 0xf2, 0xfe, 0x7c, 0x35, - 0x79, 0x27, 0xed, 0x13, 0x93, 0x3b, 0xc1, 0x5c, 0x48, 0xa7, 0xdd, 0x27, 0xf8, 0x07, 0xee, 0x04, - 0x87, 0xe3, 0x3c, 0x0f, 0x22, 0x5d, 0xc0, 0xc3, 0xc1, 0xed, 0xea, 0x85, 0xbc, 0x42, 0x9d, 0xf2, - 0xb2, 0x3d, 0xaf, 0xba, 0xeb, 0x81, 0x4c, 0x12, 0xee, 0x31, 0x60, 0x00, 0x3e, 0x32, 0xb5, 0x67, - 0x79, 0x0b, 0x67, 0xd3, 0x8c, 0x81, 0xfb, 0xfb, 0x78, 0x9f, 0x11, 0x1a, 0x01, 0xa1, 0x27, 0x05, - 0xe8, 0xd7, 0x8d, 0x40, 0x81, 0x88, 0x2b, 0x79, 0x16, 0xc2, 0x87, 0x27, 0x5f, 0xa2, 0x2e, 0x15, - 0x01, 0x7f, 0x17, 0x8f, 0xa4, 0x5a, 0x03, 0xfa, 0x77, 0xf1, 0xde, 0x79, 0x0f, 0x13, 0xdb, 0xf4, - 0xcb, 0xeb, 0x8e, 0xe0, 0x7d, 0xc1, 0xdb, 0x00, 0xf4, 0xb0, 0x1f, 0x59, 0x07, 0xd5, 0x61, 0xcb, - 0xc4, 0x55, 0x6f, 0xd7, 0xe6, 0x7c, 0x88, 0x40, 0xa3, 0x84, 0x48, 0x0d, 0x96, 0x28, 0xd3, 0xa6, - 0x25, 0x6a, 0xdf, 0x3e, 0x55, 0xf0, 0xa1, 0x60, 0xab, 0x2d, 0x50, 0x67, 0xc9, 0x4b, 0x12, 0xb9, - 0x4f, 0x8b, 0x61, 0x95, 0xb4, 0x75, 0x58, 0x61, 0xff, 0x41, 0x2e, 0xe2, 0xc1, 0xb8, 0x41, 0x2d, - 0xcd, 0xe9, 0x09, 0xde, 0x81, 0xb6, 0xe3, 0x4d, 0xc8, 0xd6, 0x5c, 0xd4, 0x0c, 0x65, 0x0a, 0x88, - 0xf2, 0xa6, 0x19, 0x45, 0xd4, 0xae, 0xd5, 0xfb, 0x0a, 0x01, 0x89, 0x50, 0x8c, 0x44, 0x12, 0x99, - 0x96, 0x48, 0xb4, 0x6f, 0x7d, 0x66, 0xea, 0x57, 0xc1, 0x22, 0x75, 0xdc, 0x39, 0x2f, 0xc7, 0xbe, - 0xc2, 0x52, 0xec, 0xc6, 0xcb, 0xb4, 0x09, 0xa7, 0x30, 0xc9, 0x0e, 0x88, 0xbe, 0x87, 0xfb, 0x23, - 0x43, 0x20, 0x69, 0xae, 0x09, 0xdf, 0xa8, 0xc3, 0xa8, 0x1b, 0xb9, 0x5c, 0x3f, 0x1c, 0x29, 0xa0, - 0xdb, 0xb5, 0x92, 0xbf, 0x20, 0xe0, 0x99, 0x14, 0xaa, 0x11, 0xcf, 0x4c, 0x1b, 0x78, 0xb6, 0x6f, - 0x95, 0x4f, 0x40, 0xd9, 0xb0, 0xa0, 0xb9, 0xfc, 0x6d, 0x95, 0xbc, 0xb4, 0x8b, 0x50, 0xe6, 0xc0, - 0xe4, 0xb9, 0x8d, 0xeb, 0x5e, 0x3e, 0xdf, 0x6a, 0x19, 0xa0, 0xe3, 0x81, 0x70, 0x68, 0x50, 0xed, - 0x06, 0xee, 0xe3, 0xef, 0x56, 0xc1, 0xf4, 0x9f, 0x37, 0x29, 0x84, 0x1c, 0xc8, 0x1f, 0x00, 0xc7, - 0xbc, 0x69, 0x3e, 0x8b, 0x1b, 0xf9, 0x1b, 0x04, 0x44, 0x6a, 0xfe, 0x53, 0x89, 0x64, 0x76, 0x44, - 0xa4, 0x7d, 0xab, 0x7e, 0x1d, 0x12, 0xa9, 0x45, 0xc3, 0x61, 0xda, 0x2f, 0x69, 0x56, 0xa9, 0x5e, - 0xb0, 0x36, 0x4a, 0x47, 0x07, 0x70, 0x97, 0x69, 0xac, 0x1a, 0x2e, 0x8b, 0xbe, 0xb7, 0xe0, 0x3f, - 0xc8, 0xf7, 0x83, 0x8c, 0x29, 0xe6, 0xf0, 0x59, 0x49, 0x21, 0xe3, 0x3e, 0xd7, 0x76, 0xa9, 0x09, - 0x81, 0x60, 0x67, 0x85, 0xde, 0xd5, 0xaa, 0x72, 0xef, 0xf0, 0x78, 0xf5, 0x73, 0xe8, 0x22, 0x90, - 0xcf, 0x04, 0x1a, 0x44, 0x46, 0x01, 0xf1, 0x41, 0xdc, 0xcd, 0x5d, 0x4d, 0x99, 0x02, 0x3c, 0xc9, - 0xcb, 0xc0, 0x74, 0xde, 0xb6, 0xee, 0x68, 0x15, 0xef, 0x4b, 0xb4, 0x6c, 0x7b, 0xe6, 0xb1, 0x53, - 0x10, 0x93, 0x4e, 0xc2, 0x3d, 0x3a, 0x75, 0x16, 0x6b, 0xea, 0xed, 0x29, 0xd4, 0x9e, 0xe5, 0x2f, - 0x10, 0xe4, 0x0f, 0x71, 0xb7, 0x80, 0xe7, 0x55, 0xbc, 0xdf, 0xae, 0xba, 0x2b, 0x76, 0xd5, 0x2a, - 0x2d, 0x50, 0xe7, 0xaa, 0xe5, 0x0d, 0x06, 0x3d, 0x82, 0xd8, 0x80, 0x37, 0x9b, 0x75, 0x26, 0x54, - 0xdb, 0xbc, 0xac, 0x69, 0x30, 0xdb, 0x0f, 0x1a, 0x1f, 0x20, 0x13, 0xb8, 0xdf, 0xfb, 0xcb, 0xdf, - 0x53, 0x19, 0xa6, 0x67, 0xf4, 0xb5, 0x3c, 0x8e, 0xc7, 0x18, 0xcc, 0x6b, 0x9a, 0xe3, 0x50, 0x5d, - 0x5b, 0xa2, 0x8e, 0x63, 0x58, 0xfa, 0x52, 0xdd, 0x63, 0xa0, 0xee, 0x65, 0x7c, 0xac, 0xd9, 0x44, - 0x20, 0x36, 0x84, 0xf7, 0x7c, 0x58, 0x83, 0xe8, 0x13, 0xaa, 0xbf, 0x98, 0xfe, 0x78, 0x04, 0x77, - 0x31, 0x47, 0xe4, 0x53, 0x84, 0xbb, 0xfd, 0xee, 0x04, 0x99, 0x6a, 0xb2, 0x6f, 0xe2, 0xed, 0x11, - 0x69, 0x7a, 0x3b, 0x26, 0x3e, 0x32, 0x79, 0xec, 0xde, 0xef, 0xff, 0xdd, 0xef, 0x1c, 0x21, 0xc3, - 0x8a, 0x67, 0x31, 0xc9, 0xb5, 0xbc, 0xf8, 0xb6, 0x11, 0x79, 0x88, 0x70, 0x1f, 0x5f, 0x50, 0x92, - 0xf3, 0x22, 0xb1, 0x92, 0x7b, 0x29, 0xd2, 0x85, 0x96, 0x6c, 0x01, 0xf0, 0x45, 0x06, 0xf8, 0x2c, - 0x39, 0x93, 0x02, 0x98, 0x2f, 0x71, 0x95, 0x4d, 0xb8, 0x9d, 0xb7, 0x94, 0x4d, 0x76, 0x1f, 0x6f, - 0x91, 0xef, 0x11, 0xee, 0xe7, 0xfd, 0xe6, 0x4d, 0x53, 0x8c, 0x4b, 0x72, 0x47, 0x45, 0x8c, 0x4b, - 0x4a, 0x97, 0x44, 0x3e, 0xc1, 0xb8, 0x8c, 0x91, 0x51, 0x01, 0x2e, 0xe4, 0x6f, 0x84, 0x0f, 0x46, - 0x90, 0x43, 0x61, 0x4b, 0xf2, 0x2d, 0x80, 0x08, 0x57, 0xe7, 0xd2, 0xdc, 0x4e, 0x5c, 0x00, 0x9d, - 0xf3, 0x8c, 0xce, 0x69, 0x32, 0x2d, 0x40, 0x07, 0x6c, 0x61, 0x85, 0xb6, 0xc8, 0x5f, 0x08, 0xbf, - 0xc8, 0x55, 0x8f, 0x1c, 0xb9, 0x37, 0x04, 0x91, 0xa5, 0x76, 0x1e, 0xa4, 0xfc, 0x0e, 0x3c, 0x00, - 0xb5, 0x59, 0x46, 0x6d, 0x86, 0x9c, 0x4e, 0xa1, 0x66, 0x58, 0x29, 0xcc, 0x8a, 0x46, 0x69, 0x8b, - 0x7c, 0x87, 0xf0, 0xbe, 0x30, 0x39, 0xe1, 0x3d, 0x97, 0xd0, 0x03, 0x10, 0xde, 0x73, 0x49, 0x75, - 0x7d, 0xd3, 0x3d, 0xc7, 0x31, 0x71, 0xc8, 0x6f, 0x00, 0x9c, 0xab, 0x8d, 0x66, 0x05, 0x0f, 0x6f, - 0x62, 0x85, 0x28, 0x5d, 0x6c, 0xd1, 0x1a, 0xc0, 0xbf, 0xc6, 0xc0, 0x4f, 0x93, 0x93, 0x0d, 0xc0, - 0xd7, 0xcd, 0x94, 0xcd, 0xe0, 0x79, 0x8b, 0xfc, 0x81, 0x30, 0x89, 0xd7, 0xcc, 0x44, 0x08, 0x4f, - 0x6a, 0xa5, 0x2e, 0xbd, 0xde, 0xaa, 0x39, 0xf0, 0xc9, 0x33, 0x3e, 0x17, 0xc8, 0xb9, 0x54, 0x3e, - 0xd1, 0x7f, 0x1f, 0x14, 0x4b, 0xd4, 0xa5, 0x3c, 0xb1, 0x1f, 0x11, 0xde, 0x1f, 0x8e, 0xe0, 0x6d, - 0xaf, 0xd9, 0x6d, 0x6c, 0x91, 0x16, 0x57, 0x29, 0xb5, 0x36, 0x97, 0x27, 0x19, 0xab, 0x71, 0x32, - 0x26, 0xb4, 0x4a, 0xe4, 0x6b, 0x54, 0xaf, 0x09, 0xc9, 0x8c, 0xe0, 0x06, 0x89, 0x14, 0xaf, 0xd2, - 0xd9, 0x6d, 0xdb, 0x01, 0x58, 0x85, 0x81, 0x7d, 0x85, 0x8c, 0xa7, 0x80, 0xd5, 0xc1, 0xc0, 0xd3, - 0xbc, 0xa4, 0xad, 0x6f, 0x91, 0x2f, 0x11, 0xee, 0x0d, 0xbc, 0x78, 0x52, 0xcf, 0x08, 0x8a, 0xd5, - 0x12, 0xe2, 0x84, 0x12, 0x5a, 0x1e, 0x67, 0x88, 0x8f, 0x92, 0x91, 0x26, 0x88, 0xc9, 0x03, 0x84, - 0x5f, 0x88, 0xe6, 0x5a, 0x44, 0xe8, 0xf2, 0x48, 0x49, 0xfc, 0xa4, 0xd9, 0xd6, 0x8c, 0x05, 0xa5, - 0x56, 0xa3, 0x58, 0x1f, 0x22, 0xdc, 0xcb, 0xa5, 0x53, 0xe4, 0x92, 0x48, 0xf8, 0x66, 0x69, 0x9b, - 0xf4, 0xe6, 0x0e, 0xbd, 0x00, 0x9b, 0xe3, 0x8c, 0xcd, 0xcb, 0x44, 0x4e, 0xcb, 0x9c, 0x38, 0xe0, - 0x8f, 0x50, 0xac, 0x4a, 0x26, 0xa2, 0x57, 0x61, 0x72, 0x8d, 0x2f, 0x76, 0xf5, 0xa4, 0xf7, 0x27, - 0xe4, 0x19, 0x06, 0xff, 0x24, 0xc9, 0xa5, 0xc0, 0x37, 0xc3, 0x76, 0xb5, 0xed, 0xff, 0x33, 0xc2, - 0x24, 0xe2, 0xd3, 0x3b, 0x05, 0xa2, 0x57, 0xc6, 0x4e, 0xd8, 0xa4, 0x77, 0x21, 0xe4, 0x1c, 0x63, - 0x33, 0x41, 0x8e, 0x89, 0xb1, 0x21, 0x9f, 0x23, 0xbc, 0x8b, 0x5d, 0x3e, 0xd3, 0x82, 0x32, 0xf2, - 0xd7, 0xe3, 0xa9, 0x6d, 0xd9, 0x08, 0x7e, 0x77, 0x55, 0xf8, 0x60, 0x31, 0x91, 0xbf, 0x45, 0xb8, - 0x97, 0xeb, 0x3e, 0x90, 0x73, 0xdb, 0x88, 0x18, 0xee, 0x58, 0xb4, 0x06, 0xf6, 0x0c, 0x03, 0xab, - 0x90, 0xc9, 0x86, 0x60, 0x63, 0xc9, 0xf5, 0x67, 0x08, 0xef, 0x0e, 0xbe, 0x40, 0xd3, 0x82, 0x2b, - 0xba, 0x6d, 0x61, 0x23, 0x1d, 0x08, 0x79, 0x94, 0x61, 0x1d, 0x26, 0x87, 0x1b, 0x60, 0xf5, 0x32, - 0xb0, 0x7e, 0xcf, 0xca, 0xab, 0xdd, 0xa1, 0x74, 0x16, 0x4b, 0xc1, 0x92, 0xbb, 0x07, 0x62, 0x29, - 0x58, 0x4a, 0xa3, 0xa0, 0xe9, 0xcd, 0xa1, 0xd6, 0x6d, 0x58, 0xea, 0x18, 0xfe, 0x9f, 0xba, 0xd8, - 0x66, 0x48, 0xfc, 0x2f, 0xbd, 0x74, 0xbe, 0x15, 0x53, 0xc1, 0xaf, 0xfa, 0xdd, 0x30, 0x4a, 0x0f, - 0x78, 0xb8, 0xed, 0x20, 0x06, 0x3c, 0xb1, 0x91, 0x21, 0x06, 0x3c, 0xb9, 0xcb, 0xd1, 0x14, 0xb8, - 0x19, 0x32, 0x9b, 0x7b, 0xeb, 0xd1, 0x93, 0x2c, 0x7a, 0xfc, 0x24, 0x8b, 0xfe, 0x7d, 0x92, 0x45, - 0x9f, 0x3c, 0xcd, 0x76, 0x3c, 0x7e, 0x9a, 0xed, 0xf8, 0xf3, 0x69, 0xb6, 0xe3, 0xe6, 0x94, 0x6e, - 0xb8, 0xe5, 0xea, 0x4a, 0x4e, 0xb5, 0x57, 0x79, 0x57, 0x01, 0x1e, 0x65, 0x9d, 0xf7, 0xea, 0x6e, - 0xac, 0x69, 0xce, 0x4a, 0x37, 0xfb, 0x0a, 0x9c, 0xfa, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x77, - 0x46, 0x98, 0xb4, 0x22, 0x00, 0x00, + // 1860 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x6f, 0x14, 0xc9, + 0x15, 0x77, 0x79, 0xb0, 0xd7, 0x94, 0xcd, 0x7a, 0xa9, 0x75, 0x58, 0x6f, 0x63, 0x8f, 0x77, 0xdb, + 0x31, 0x26, 0x10, 0xcf, 0xac, 0xbd, 0x60, 0xbe, 0x4c, 0xc4, 0xd8, 0x04, 0x83, 0x62, 0xc0, 0x19, + 0x39, 0x4a, 0x44, 0x14, 0x8d, 0x6a, 0x7a, 0x2a, 0x33, 0x2d, 0xda, 0xdd, 0x66, 0xaa, 0x06, 0xd9, + 0x58, 0xbe, 0x70, 0xc8, 0x39, 0x12, 0x52, 0x72, 0xc9, 0x35, 0x4a, 0x0e, 0x39, 0xe4, 0x80, 0x92, + 0x43, 0x24, 0xa2, 0x7c, 0x11, 0x8e, 0x48, 0x91, 0xa2, 0x28, 0x91, 0xa2, 0x08, 0xf2, 0x87, 0xac, + 0xba, 0xfa, 0xf5, 0x4c, 0x75, 0x4f, 0xf7, 0x4c, 0x79, 0x3c, 0x1c, 0x38, 0x31, 0x5d, 0x55, 0xef, + 0xbd, 0xdf, 0xef, 0x57, 0x5f, 0xaf, 0x1e, 0xc6, 0xa7, 0xac, 0xba, 0xc7, 0xb9, 0x55, 0xa3, 0xb6, + 0x9b, 0x7f, 0xd4, 0x60, 0xf5, 0xbd, 0xdc, 0x4e, 0xdd, 0x13, 0x1e, 0x99, 0x7e, 0xc2, 0x04, 0x95, + 0xcd, 0x39, 0xf9, 0xcb, 0xab, 0xb3, 0x5c, 0x6b, 0xa8, 0x71, 0xce, 0xf2, 0xf8, 0xb6, 0xc7, 0xf3, + 0x65, 0xca, 0x59, 0x60, 0x97, 0x7f, 0xbc, 0x58, 0x66, 0x82, 0x2e, 0xe6, 0x77, 0x68, 0xd5, 0x76, + 0xa9, 0xb0, 0x3d, 0x37, 0x70, 0x65, 0xcc, 0x28, 0x21, 0xe4, 0xcf, 0x92, 0xfc, 0x5d, 0x12, 0xbb, + 0x30, 0xc0, 0x50, 0x06, 0x54, 0x29, 0x2f, 0xed, 0xd4, 0x6d, 0x8b, 0x41, 0xdf, 0xac, 0xd2, 0x27, + 0x6d, 0x4a, 0x35, 0xca, 0x6b, 0x25, 0xe1, 0x95, 0x2c, 0xab, 0xe9, 0x20, 0xdb, 0x36, 0x48, 0xd4, + 0xa9, 0xf5, 0x90, 0xd5, 0xa1, 0xdf, 0x54, 0xfa, 0x1d, 0xca, 0x45, 0xa9, 0xec, 0x78, 0xd6, 0xc3, + 0x52, 0x8d, 0xd9, 0xd5, 0x9a, 0x48, 0x40, 0xe9, 0x35, 0x44, 0xbb, 0x93, 0x4f, 0x94, 0x01, 0x3b, + 0xb4, 0x4e, 0xb7, 0x39, 0x74, 0x4c, 0x54, 0xbd, 0xaa, 0x27, 0x7f, 0xe6, 0xfd, 0x5f, 0xd0, 0x3a, + 0x55, 0xf5, 0xbc, 0xaa, 0xc3, 0xf2, 0x74, 0xc7, 0xce, 0x53, 0xd7, 0xf5, 0x84, 0x94, 0x04, 0x6c, + 0xcc, 0xd3, 0xf8, 0xd3, 0xef, 0xfa, 0xaa, 0xad, 0x33, 0xb1, 0xc5, 0x79, 0xa1, 0x52, 0xa9, 0x33, + 0xce, 0x8b, 0xec, 0x51, 0x83, 0x71, 0x61, 0xde, 0xc0, 0x46, 0x52, 0x27, 0xdf, 0xf1, 0x5c, 0xce, + 0xc8, 0x47, 0x38, 0xc3, 0x44, 0x6d, 0x12, 0x7d, 0x86, 0xce, 0x1e, 0x2f, 0xfa, 0x3f, 0xfd, 0x96, + 0xb2, 0xb0, 0x26, 0x07, 0x83, 0x96, 0xb2, 0xb0, 0xcc, 0x29, 0xf0, 0xf0, 0x80, 0x09, 0x5a, 0xb0, + 0x2c, 0xaf, 0xe1, 0x0a, 0xdb, 0xad, 0x86, 0xfe, 0xef, 0xe2, 0xd3, 0x89, 0xbd, 0x10, 0x20, 0x87, + 0x3f, 0xa6, 0x65, 0xaf, 0x2e, 0x58, 0xa5, 0xe4, 0x4f, 0x7d, 0x89, 0x6e, 0xfb, 0x23, 0x20, 0xe0, + 0x49, 0xe8, 0x92, 0xb6, 0xb2, 0xc3, 0x9c, 0xc0, 0x44, 0xba, 0xdb, 0x94, 0xa2, 0x84, 0x41, 0x1e, + 0xe0, 0x8f, 0x23, 0xad, 0xe0, 0x7c, 0x0d, 0x0f, 0x07, 0xe2, 0x49, 0x7f, 0xa3, 0x4b, 0x73, 0xb9, + 0x8e, 0x0b, 0x2d, 0x17, 0x98, 0xaf, 0x1e, 0x7b, 0xf5, 0xdf, 0x99, 0x81, 0x22, 0x98, 0x36, 0x09, + 0xac, 0x33, 0x71, 0xbf, 0x21, 0xb6, 0x76, 0xb7, 0x82, 0x89, 0x82, 0xd0, 0x64, 0x12, 0x7f, 0x20, + 0x8d, 0xef, 0xdc, 0x94, 0x41, 0x32, 0xc5, 0xf0, 0x93, 0x4c, 0xe0, 0x21, 0xd7, 0x73, 0x2d, 0x26, + 0xb5, 0x3a, 0x56, 0x0c, 0x3e, 0xcc, 0x06, 0x9e, 0x4a, 0x76, 0x07, 0x98, 0xbf, 0x87, 0xc7, 0x3c, + 0xa5, 0x1d, 0x90, 0x9f, 0xef, 0x82, 0x5c, 0x75, 0x05, 0xf8, 0x23, 0x6e, 0x4c, 0x06, 0x2c, 0x0a, + 0x8e, 0x93, 0xc4, 0xe2, 0x16, 0xc6, 0xad, 0xad, 0x04, 0x31, 0xcf, 0xe4, 0x82, 0x7d, 0x97, 0xf3, + 0xf7, 0x5d, 0x2e, 0xd8, 0xaf, 0xb0, 0xef, 0x72, 0x9b, 0xb4, 0xca, 0xc0, 0xb6, 0xa8, 0x58, 0x9a, + 0x2f, 0x10, 0xd0, 0x6b, 0x8b, 0x93, 0x4a, 0x2f, 0xd3, 0x07, 0x7a, 0x64, 0x3d, 0x82, 0x7f, 0x50, + 0xe2, 0x9f, 0xef, 0x8a, 0x3f, 0xc0, 0x14, 0x21, 0xf0, 0x14, 0x61, 0x33, 0x89, 0xc0, 0xea, 0xde, + 0x9a, 0x8f, 0x24, 0xd4, 0x6b, 0x02, 0x0f, 0x49, 0x64, 0x30, 0xe7, 0xc1, 0x47, 0x4c, 0xc5, 0xc1, + 0x9e, 0x55, 0xfc, 0x1b, 0xc2, 0xb3, 0x1d, 0x41, 0xbc, 0x27, 0x62, 0xfe, 0x04, 0xe1, 0xcf, 0x43, + 0x1e, 0x77, 0xdc, 0x34, 0x2d, 0x3f, 0xc5, 0x23, 0xc1, 0x19, 0x6d, 0x57, 0xa2, 0x5b, 0xa8, 0xd2, + 0x37, 0x41, 0xff, 0xa4, 0xcc, 0x6a, 0x12, 0x10, 0xd0, 0xb3, 0x88, 0x47, 0x6d, 0x37, 0x2e, 0xe7, + 0xb9, 0x2e, 0x72, 0xaa, 0xfe, 0x02, 0x35, 0x55, 0x27, 0xfd, 0x13, 0x53, 0xd9, 0xc1, 0x4a, 0x48, + 0xde, 0xef, 0x1d, 0xfc, 0x07, 0x65, 0x07, 0x47, 0xe3, 0xbc, 0x0f, 0x22, 0x5d, 0xc3, 0xd3, 0xe1, + 0xe9, 0xea, 0x87, 0xbc, 0x4d, 0x79, 0x6d, 0xcb, 0x5b, 0xb3, 0xc4, 0x6e, 0x28, 0x93, 0x81, 0x47, + 0x6c, 0xe8, 0x80, 0x4b, 0xa6, 0xf9, 0x6d, 0x1e, 0xe0, 0x6c, 0x9a, 0x31, 0x70, 0xff, 0x21, 0xfe, + 0xd0, 0x8e, 0xf4, 0x80, 0xd0, 0x0b, 0x1a, 0xf4, 0x5b, 0x46, 0xa0, 0x40, 0xcc, 0x95, 0xb9, 0x02, + 0xe1, 0xa3, 0x83, 0x6f, 0x52, 0x41, 0x75, 0xc0, 0x3f, 0xc1, 0x33, 0xa9, 0xd6, 0x80, 0xfe, 0xfb, + 0xf8, 0xc4, 0x9a, 0x8f, 0x49, 0x2e, 0xfa, 0xad, 0x5d, 0xae, 0x79, 0x5e, 0xa8, 0x36, 0x00, 0x3d, + 0xea, 0xc7, 0xac, 0x82, 0xea, 0xb0, 0x64, 0xda, 0x55, 0xef, 0xd7, 0xe2, 0x7c, 0x89, 0x40, 0xa3, + 0x84, 0x48, 0x1d, 0xa6, 0x28, 0xd3, 0xa7, 0x29, 0xea, 0xdf, 0x3a, 0xcd, 0xe3, 0x4f, 0xc2, 0xa5, + 0xb6, 0x4e, 0xf9, 0xa6, 0x9f, 0x83, 0x2a, 0x57, 0x8b, 0xed, 0x56, 0xd8, 0x2e, 0xcc, 0x70, 0xf0, + 0x61, 0x96, 0xf0, 0x64, 0xbb, 0x41, 0x33, 0xcd, 0x19, 0x09, 0xdb, 0x40, 0xdb, 0xf9, 0x2e, 0x64, + 0x9b, 0x2e, 0x9a, 0x86, 0x26, 0x05, 0x44, 0x05, 0xc7, 0x89, 0x23, 0xea, 0xd7, 0xec, 0xfd, 0x1a, + 0x01, 0x89, 0x48, 0x8c, 0x44, 0x12, 0x99, 0x9e, 0x48, 0xf4, 0x6f, 0x7e, 0x96, 0x5b, 0x47, 0xc1, + 0x06, 0xe5, 0x62, 0xd5, 0x4f, 0xe1, 0x6f, 0xcb, 0x0c, 0xbe, 0xf3, 0x34, 0xed, 0xc3, 0x2e, 0x4c, + 0xb2, 0x03, 0xa2, 0x3f, 0xc0, 0xe3, 0xb1, 0x2e, 0x90, 0x34, 0xd7, 0x85, 0x6f, 0xdc, 0x61, 0xdc, + 0x8d, 0x59, 0x6b, 0x6d, 0x8e, 0x14, 0xd0, 0xfd, 0x9a, 0xc9, 0xbf, 0x22, 0xe0, 0x99, 0x14, 0xaa, + 0x13, 0xcf, 0x4c, 0x1f, 0x78, 0xf6, 0x6f, 0x96, 0xcf, 0xc3, 0xb3, 0x61, 0x9d, 0x09, 0xf5, 0xb4, + 0x4a, 0x9e, 0xda, 0x8d, 0xd6, 0x43, 0x49, 0x9e, 0x10, 0x7b, 0xf7, 0xfc, 0x7c, 0xbe, 0xd7, 0x67, + 0x40, 0x15, 0x4f, 0x44, 0x43, 0x83, 0x6a, 0xf7, 0xf1, 0x98, 0x7a, 0xb6, 0x6a, 0xa6, 0xff, 0xaa, + 0x49, 0x31, 0xe2, 0xc0, 0xfc, 0x11, 0x70, 0x2c, 0x38, 0xce, 0xbb, 0x38, 0x91, 0x7f, 0x8b, 0x80, + 0x48, 0xd3, 0x7f, 0x2a, 0x91, 0xcc, 0x91, 0x88, 0xf4, 0x6f, 0xd6, 0xef, 0x41, 0x22, 0xb5, 0x61, + 0x73, 0xa9, 0xfd, 0x26, 0x73, 0x2b, 0xad, 0x07, 0x6b, 0xa7, 0x74, 0x74, 0x02, 0x0f, 0x39, 0xf6, + 0xb6, 0x2d, 0x64, 0xf4, 0x13, 0xc5, 0xe0, 0xc3, 0x7c, 0x16, 0x66, 0x4c, 0x6d, 0x0e, 0xdf, 0x95, + 0x14, 0x26, 0x1e, 0x13, 0x9e, 0xa0, 0x0e, 0x04, 0x82, 0x95, 0x15, 0x69, 0x6b, 0xbe, 0xca, 0xfd, + 0xcd, 0xe3, 0xbf, 0x9f, 0x23, 0x07, 0x81, 0x79, 0x31, 0xd4, 0x20, 0xd6, 0x0b, 0x88, 0x4f, 0xe1, + 0x61, 0xe5, 0x68, 0xca, 0x14, 0xe1, 0xcb, 0xdc, 0x02, 0xa6, 0x6b, 0x9e, 0xfb, 0x98, 0xd5, 0xfd, + 0x9b, 0x68, 0xcb, 0xf3, 0xcd, 0xdb, 0x76, 0x41, 0x9b, 0x74, 0x06, 0x1e, 0xa9, 0x52, 0xbe, 0xd1, + 0x54, 0xef, 0x78, 0xb1, 0xf9, 0x6d, 0xfe, 0x12, 0x41, 0xfe, 0xd0, 0xee, 0x16, 0xf0, 0x7c, 0x13, + 0x9f, 0xf4, 0x1a, 0xa2, 0xec, 0x35, 0xdc, 0xca, 0x3a, 0xe5, 0x77, 0x5c, 0xbf, 0x33, 0xac, 0x11, + 0xb4, 0x75, 0xf8, 0xa3, 0x65, 0xe1, 0xc3, 0xf2, 0x9c, 0x5b, 0x8c, 0xc1, 0xe8, 0x20, 0x68, 0x7b, + 0x07, 0x39, 0x8b, 0xc7, 0xfd, 0x7f, 0xd5, 0x73, 0x2a, 0x23, 0xf5, 0x8c, 0x37, 0x9b, 0xf3, 0x78, + 0x4e, 0xc2, 0xbc, 0xcb, 0x38, 0xa7, 0x55, 0xb6, 0x49, 0x39, 0xb7, 0xdd, 0xea, 0x66, 0xcb, 0x63, + 0xa8, 0xee, 0x2d, 0x7c, 0xa6, 0xdb, 0x40, 0x20, 0x36, 0x85, 0x8f, 0xff, 0xb8, 0x09, 0x31, 0x20, + 0xd4, 0x6a, 0x58, 0xfa, 0xf3, 0x67, 0x78, 0x48, 0x3a, 0x22, 0xcf, 0x11, 0x3e, 0x11, 0xa9, 0xd0, + 0x90, 0xcb, 0x5d, 0x96, 0x4f, 0x6a, 0xc5, 0xc7, 0xb8, 0xd2, 0x83, 0x65, 0x00, 0xd7, 0xcc, 0x3d, + 0xfd, 0xc7, 0xff, 0x9f, 0x0d, 0x9e, 0x25, 0x67, 0xf2, 0xbe, 0xe1, 0x82, 0x52, 0x66, 0x83, 0x82, + 0x1a, 0x13, 0x25, 0xc1, 0x79, 0x89, 0x02, 0xc8, 0x9f, 0x21, 0x3c, 0x1c, 0x14, 0x55, 0xc8, 0xa2, + 0x4e, 0xd4, 0x48, 0x55, 0xc7, 0x58, 0x3a, 0x8c, 0x09, 0x20, 0x9c, 0x93, 0x08, 0x67, 0xc8, 0x74, + 0x0a, 0xc2, 0xa0, 0xa8, 0x43, 0x5e, 0x22, 0x3c, 0xa6, 0xbe, 0x83, 0xc9, 0x55, 0x4d, 0x51, 0x12, + 0x8a, 0x27, 0xc6, 0xb5, 0x9e, 0x6c, 0x01, 0xf0, 0x75, 0x09, 0xf8, 0x12, 0xb9, 0x98, 0x02, 0x58, + 0x7d, 0x99, 0xe7, 0xf7, 0xe1, 0x52, 0x39, 0xc8, 0xef, 0xcb, 0x6b, 0xe4, 0x80, 0xfc, 0x1e, 0xe1, + 0x71, 0xd5, 0x6f, 0xc1, 0x71, 0xf4, 0xb8, 0x24, 0x17, 0x82, 0xf4, 0xb8, 0xa4, 0x14, 0x77, 0xcc, + 0xf3, 0x92, 0xcb, 0x1c, 0x99, 0xd5, 0xe0, 0x42, 0xfe, 0x83, 0xf0, 0xa9, 0x18, 0x72, 0x78, 0x8f, + 0x93, 0x42, 0x0f, 0x20, 0xa2, 0x45, 0x05, 0x63, 0xf5, 0x28, 0x2e, 0x80, 0xce, 0x55, 0x49, 0xe7, + 0x02, 0x59, 0xd2, 0xa0, 0x03, 0xb6, 0x30, 0x43, 0x07, 0xe4, 0xdf, 0x08, 0x7f, 0x4d, 0x79, 0xf4, + 0x2a, 0xe4, 0x6e, 0x68, 0x22, 0x4b, 0x2d, 0x98, 0x18, 0x85, 0x23, 0x78, 0x00, 0x6a, 0x2b, 0x92, + 0xda, 0x32, 0xb9, 0x90, 0x42, 0xcd, 0x76, 0x53, 0x98, 0x95, 0xec, 0xca, 0x01, 0xf9, 0x1d, 0xc2, + 0x1f, 0x46, 0xc9, 0x69, 0xaf, 0xb9, 0x84, 0xd2, 0x85, 0xf6, 0x9a, 0x4b, 0x2a, 0x47, 0x74, 0x5d, + 0x73, 0x0a, 0x13, 0x4e, 0xfe, 0x0e, 0xc0, 0x95, 0x27, 0xdd, 0x8a, 0xe6, 0xe6, 0x4d, 0x7c, 0xd8, + 0x1a, 0xd7, 0x7b, 0xb4, 0x06, 0xf0, 0x97, 0x25, 0xf8, 0x25, 0xf2, 0x45, 0x07, 0xf0, 0x2d, 0xb3, + 0xfc, 0x7e, 0xf8, 0x7d, 0x40, 0xfe, 0x89, 0x30, 0x69, 0x7f, 0xea, 0x13, 0x2d, 0x3c, 0xa9, 0x05, + 0x06, 0xe3, 0x5b, 0xbd, 0x9a, 0x03, 0x9f, 0x82, 0xe4, 0x73, 0x8d, 0x5c, 0x49, 0xe5, 0x13, 0xff, + 0x4f, 0x95, 0x52, 0x85, 0x0a, 0xaa, 0x12, 0xfb, 0x23, 0xc2, 0x27, 0xa3, 0x11, 0xfc, 0xe5, 0xb5, + 0x72, 0x88, 0x25, 0xd2, 0xe3, 0x2c, 0xa5, 0x96, 0x14, 0xcc, 0x05, 0xc9, 0x6a, 0x9e, 0xcc, 0x69, + 0xcd, 0x12, 0xf9, 0x0d, 0x6a, 0x3d, 0x65, 0xc9, 0xb2, 0xe6, 0x02, 0x89, 0xbd, 0xb9, 0x8d, 0x4b, + 0x87, 0xb6, 0x03, 0xb0, 0x79, 0x09, 0xf6, 0x1b, 0x64, 0x3e, 0xed, 0x8a, 0x06, 0x03, 0x5f, 0xf3, + 0x0a, 0xdb, 0x3d, 0x20, 0xbf, 0x42, 0x78, 0x34, 0xf4, 0xe2, 0x4b, 0xbd, 0xac, 0x29, 0x56, 0x4f, + 0x88, 0x13, 0x5e, 0xfe, 0xe6, 0xbc, 0x44, 0xfc, 0x39, 0x99, 0xe9, 0x82, 0x98, 0xbc, 0x40, 0xf8, + 0xa3, 0x78, 0x8a, 0x48, 0xb4, 0x0e, 0x8f, 0x94, 0x7c, 0xd5, 0x58, 0xe9, 0xcd, 0x58, 0x53, 0x6a, + 0x2b, 0x8e, 0xf5, 0x25, 0xc2, 0xa3, 0x4a, 0x16, 0x48, 0x6e, 0xea, 0x84, 0xef, 0x96, 0x6d, 0x1a, + 0xdf, 0x3e, 0xa2, 0x17, 0x60, 0x73, 0x4e, 0xb2, 0xf9, 0x3a, 0x31, 0xd3, 0x32, 0x27, 0x05, 0xf8, + 0x2b, 0xd4, 0xf6, 0xb8, 0x27, 0xba, 0x47, 0x61, 0x72, 0x69, 0x42, 0xef, 0xe8, 0x49, 0x2f, 0xab, + 0x98, 0xcb, 0x12, 0xfe, 0x17, 0x24, 0x97, 0x02, 0xdf, 0x89, 0xda, 0x35, 0x97, 0xff, 0x5f, 0x10, + 0x26, 0x31, 0x9f, 0xfe, 0x2e, 0xd0, 0x3d, 0x32, 0x8e, 0xc2, 0x26, 0xbd, 0x78, 0xd2, 0x35, 0xd1, + 0x8e, 0xb1, 0x21, 0xbf, 0x40, 0xf8, 0x98, 0x3c, 0x7c, 0x96, 0x34, 0x65, 0x54, 0x8f, 0xc7, 0x2f, + 0x0f, 0x65, 0xa3, 0x79, 0xef, 0x5a, 0x70, 0x61, 0x49, 0x91, 0x9f, 0x23, 0x3c, 0xaa, 0x14, 0x4d, + 0xc8, 0x95, 0x43, 0x44, 0x8c, 0x16, 0x5a, 0x7a, 0x03, 0x7b, 0x51, 0x82, 0xcd, 0x93, 0x85, 0x8e, + 0x60, 0xdb, 0x92, 0xeb, 0x9f, 0x23, 0xfc, 0x41, 0x78, 0x03, 0x2d, 0x69, 0xce, 0xe8, 0xa1, 0x85, + 0x8d, 0x15, 0x4e, 0xcc, 0x59, 0x89, 0x75, 0x9a, 0x9c, 0xee, 0x80, 0xd5, 0xcf, 0xc0, 0xc6, 0x7d, + 0xab, 0x0d, 0x9b, 0x0b, 0x78, 0xf1, 0xeb, 0xa5, 0x60, 0xc9, 0x45, 0x0f, 0xbd, 0x14, 0x2c, 0xa5, + 0xbe, 0xd1, 0xf5, 0xe4, 0xb0, 0x5a, 0x36, 0x32, 0x75, 0x8c, 0xfe, 0x29, 0x80, 0xde, 0x62, 0x48, + 0xfc, 0xe3, 0x02, 0xe3, 0x6a, 0x2f, 0xa6, 0x9a, 0xb7, 0xfa, 0x93, 0x28, 0x4a, 0x1f, 0x78, 0xb4, + 0x5a, 0xa2, 0x07, 0x3c, 0xb1, 0xfe, 0xa2, 0x07, 0x3c, 0xb9, 0x38, 0xd3, 0x15, 0xb8, 0x13, 0x31, + 0x5b, 0xfd, 0xce, 0xab, 0x37, 0x59, 0xf4, 0xfa, 0x4d, 0x16, 0xfd, 0xef, 0x4d, 0x16, 0xfd, 0xf4, + 0x6d, 0x76, 0xe0, 0xf5, 0xdb, 0xec, 0xc0, 0xbf, 0xde, 0x66, 0x07, 0x1e, 0x2c, 0x56, 0x6d, 0x51, + 0x6b, 0x94, 0x73, 0x96, 0xb7, 0xad, 0xba, 0x0a, 0xf1, 0xe4, 0x77, 0x55, 0xaf, 0x62, 0x6f, 0x87, + 0xf1, 0xf2, 0xb0, 0xbc, 0x05, 0xbe, 0xfc, 0x2a, 0x00, 0x00, 0xff, 0xff, 0xd6, 0xad, 0xe9, 0xc2, + 0xca, 0x23, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2118,6 +2219,11 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { + // GetTssAddress queries the tss address of the module. + // Deprecated: Moved to observer + // TODO: remove after v12 once upgrade testing is no longer needed with v11 + // https://github.com/zeta-chain/node/issues/1547 + GetTssAddress(ctx context.Context, in *QueryGetTssAddressRequest, opts ...grpc.CallOption) (*QueryGetTssAddressResponse, error) // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // Queries a OutTxTracker by index. @@ -2164,6 +2270,15 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } +func (c *queryClient) GetTssAddress(ctx context.Context, in *QueryGetTssAddressRequest, opts ...grpc.CallOption) (*QueryGetTssAddressResponse, error) { + out := new(QueryGetTssAddressResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/GetTssAddress", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/Params", in, out, opts...) @@ -2355,6 +2470,11 @@ func (c *queryClient) LastZetaHeight(ctx context.Context, in *QueryLastZetaHeigh // QueryServer is the server API for Query service. type QueryServer interface { + // GetTssAddress queries the tss address of the module. + // Deprecated: Moved to observer + // TODO: remove after v12 once upgrade testing is no longer needed with v11 + // https://github.com/zeta-chain/node/issues/1547 + GetTssAddress(context.Context, *QueryGetTssAddressRequest) (*QueryGetTssAddressResponse, error) // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) // Queries a OutTxTracker by index. @@ -2397,6 +2517,9 @@ type QueryServer interface { type UnimplementedQueryServer struct { } +func (*UnimplementedQueryServer) GetTssAddress(ctx context.Context, req *QueryGetTssAddressRequest) (*QueryGetTssAddressResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTssAddress not implemented") +} func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } @@ -2465,6 +2588,24 @@ func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } +func _Query_GetTssAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetTssAddressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetTssAddress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.crosschain.Query/GetTssAddress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetTssAddress(ctx, req.(*QueryGetTssAddressRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryParamsRequest) if err := dec(in); err != nil { @@ -2847,6 +2988,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.crosschain.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "GetTssAddress", + Handler: _Query_GetTssAddress_Handler, + }, { MethodName: "Params", Handler: _Query_Params_Handler, @@ -2936,6 +3081,66 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "crosschain/query.proto", } +func (m *QueryGetTssAddressRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGetTssAddressRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetTssAddressRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryGetTssAddressResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGetTssAddressResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetTssAddressResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Btc) > 0 { + i -= len(m.Btc) + copy(dAtA[i:], m.Btc) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Btc))) + i-- + dAtA[i] = 0x12 + } + if len(m.Eth) > 0 { + i -= len(m.Eth) + copy(dAtA[i:], m.Eth) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Eth))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *QueryZetaAccountingRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4418,6 +4623,32 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QueryGetTssAddressRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryGetTssAddressResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Eth) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Btc) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryZetaAccountingRequest) Size() (n int) { if m == nil { return 0 @@ -5011,6 +5242,170 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *QueryGetTssAddressRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGetTssAddressRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetTssAddressRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetTssAddressResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGetTssAddressResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetTssAddressResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Eth", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Eth = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Btc", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Btc = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryZetaAccountingRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/crosschain/types/query.pb.gw.go b/x/crosschain/types/query.pb.gw.go index 3e7f8b97c6..d7c90c4180 100644 --- a/x/crosschain/types/query.pb.gw.go +++ b/x/crosschain/types/query.pb.gw.go @@ -33,6 +33,24 @@ var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage var _ = metadata.Join +func request_Query_GetTssAddress_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetTssAddressRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetTssAddress(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetTssAddress_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetTssAddressRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetTssAddress(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest var metadata runtime.ServerMetadata @@ -965,6 +983,29 @@ func local_request_Query_LastZetaHeight_0(ctx context.Context, marshaler runtime // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + mux.Handle("GET", pattern_Query_GetTssAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetTssAddress_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetTssAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1489,6 +1530,26 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + mux.Handle("GET", pattern_Query_GetTssAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetTssAddress_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetTssAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1913,6 +1974,8 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( + pattern_Query_GetTssAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "get_tss_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_OutTxTracker_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"zeta-chain", "crosschain", "outTxTracker", "chainID", "nonce"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1957,6 +2020,8 @@ var ( ) var ( + forward_Query_GetTssAddress_0 = runtime.ForwardResponseMessage + forward_Query_Params_0 = runtime.ForwardResponseMessage forward_Query_OutTxTracker_0 = runtime.ForwardResponseMessage From 431eff59dac4af8cd8311714389a70480646902a Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:49:43 -0600 Subject: [PATCH 15/67] fix: sanity check events of ZetaSent/ZetaReceived/ZetaReverted/Withdrawn/Deposited (#1539) * sanity check events of ZetaSent/ZetaReceived/ZetaRevertedWithdrawn/Deposited * added unit tests, comments --------- Co-authored-by: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> --- changelog.md | 1 + zetaclient/evm_client.go | 73 +++++++++++++++--------- zetaclient/inbound_tracker.go | 44 +++++++++++++-- zetaclient/utils.go | 26 +++++++++ zetaclient/utils_test.go | 102 ++++++++++++++++++++++++++++++++++ 5 files changed, 215 insertions(+), 31 deletions(-) create mode 100644 zetaclient/utils_test.go diff --git a/changelog.md b/changelog.md index 0498a869e1..9ae132349c 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ ### Fixes +* [1537](https://github.com/zeta-chain/node/issues/1537) - Sanity check events of ZetaSent/ZetaReceived/ZetaRevertedWithdrawn/Deposited * [1530](https://github.com/zeta-chain/node/pull/1530) - Outbound tx confirmation/inclusion enhancement * [1496](https://github.com/zeta-chain/node/issues/1496) - post block header for enabled EVM chains only * [1518](https://github.com/zeta-chain/node/pull/1518) - Avoid duplicate keysign if an outTx is already pending diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index badce4eca6..86d4444f60 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -57,7 +57,12 @@ type EVMLog struct { } const ( - DonationMessage = "I am rich!" + DonationMessage = "I am rich!" + TopicsZetaSent = 3 // [signature, zetaTxSenderAddress, destinationChainId] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L34 + TopicsZetaReceived = 4 // [signature, sourceChainId, destinationAddress] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L45 + TopicsZetaReverted = 3 // [signature, destinationChainId, internalSendHash] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L54 + TopicsWithdrawn = 3 // [signature, recipient, asset] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L43 + TopicsDeposited = 2 // [signature, asset] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L42 ) // EVMChainClient represents the chain configuration for an EVM chain @@ -233,24 +238,28 @@ func (ob *EVMChainClient) GetChainParams() observertypes.ChainParams { return ob.params } -func (ob *EVMChainClient) GetConnectorContract() (*zetaconnector.ZetaConnectorNonEth, error) { +func (ob *EVMChainClient) GetConnectorContract() (ethcommon.Address, *zetaconnector.ZetaConnectorNonEth, error) { addr := ethcommon.HexToAddress(ob.GetChainParams().ConnectorContractAddress) - return FetchConnectorContract(addr, ob.evmClient) + contract, err := FetchConnectorContract(addr, ob.evmClient) + return addr, contract, err } -func (ob *EVMChainClient) GetConnectorContractEth() (*zetaconnectoreth.ZetaConnectorEth, error) { +func (ob *EVMChainClient) GetConnectorContractEth() (ethcommon.Address, *zetaconnectoreth.ZetaConnectorEth, error) { addr := ethcommon.HexToAddress(ob.GetChainParams().ConnectorContractAddress) - return FetchConnectorContractEth(addr, ob.evmClient) + contract, err := FetchConnectorContractEth(addr, ob.evmClient) + return addr, contract, err } -func (ob *EVMChainClient) GetZetaTokenNonEthContract() (*zeta.ZetaNonEth, error) { +func (ob *EVMChainClient) GetZetaTokenNonEthContract() (ethcommon.Address, *zeta.ZetaNonEth, error) { addr := ethcommon.HexToAddress(ob.GetChainParams().ZetaTokenContractAddress) - return FetchZetaZetaNonEthTokenContract(addr, ob.evmClient) + contract, err := FetchZetaZetaNonEthTokenContract(addr, ob.evmClient) + return addr, contract, err } -func (ob *EVMChainClient) GetERC20CustodyContract() (*erc20custody.ERC20Custody, error) { +func (ob *EVMChainClient) GetERC20CustodyContract() (ethcommon.Address, *erc20custody.ERC20Custody, error) { addr := ethcommon.HexToAddress(ob.GetChainParams().Erc20CustodyContractAddress) - return FetchERC20CustodyContract(addr, ob.evmClient) + contract, err := FetchERC20CustodyContract(addr, ob.evmClient) + return addr, contract, err } func FetchConnectorContract(addr ethcommon.Address, client EVMRPCClient) (*zetaconnector.ZetaConnectorNonEth, error) { @@ -378,7 +387,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co for _, vLog := range logs { confHeight := vLog.BlockNumber + params.ConfirmationCount // TODO rewrite this to return early if not confirmed - connector, err := ob.GetConnectorContract() + connectorAddr, connector, err := ob.GetConnectorContract() if err != nil { return false, false, fmt.Errorf("error getting connector contract: %w", err) } @@ -387,9 +396,11 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co 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 zetacore...") - if len(vLog.Topics) != 4 { - logger.Error().Msgf("wrong number of topics in log %d", len(vLog.Topics)) - return false, false, fmt.Errorf("wrong number of topics in log %d", len(vLog.Topics)) + // sanity check tx event + err = ob.CheckEvmTxLog(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() @@ -423,9 +434,11 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co 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 zetacore...") - if len(vLog.Topics) != 3 { - logger.Error().Msgf("wrong number of topics in log %d", len(vLog.Topics)) - return false, false, fmt.Errorf("wrong number of topics in log %d", len(vLog.Topics)) + // sanity check tx event + err = ob.CheckEvmTxLog(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 @@ -480,7 +493,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } else if cointype == common.CoinType_ERC20 { if receipt.Status == 1 { logs := receipt.Logs - ERC20Custody, err := ob.GetERC20CustodyContract() + addrCustody, ERC20Custody, err := ob.GetERC20CustodyContract() if err != nil { logger.Warn().Msgf("NewERC20Custody err: %s", err) } @@ -489,6 +502,12 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co 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 = ob.CheckEvmTxLog(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 zetacore...") zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( @@ -893,7 +912,7 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { // returns the last block successfully scanned func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { // filter ZetaSent logs - connector, err := ob.GetConnectorContract() + addrConnector, connector, err := ob.GetConnectorContract() if err != nil { ob.logger.ChainLogger.Warn().Err(err).Msgf("observeZetaSent: GetConnectorContract error:") return startBlock - 1 // lastScanned @@ -912,12 +931,14 @@ func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { // collect and sort events by block number, then tx index, then log index (ascending) events := make([]*zetaconnector.ZetaConnectorNonEthZetaSent, 0) for iter.Next() { - if !iter.Event.Raw.Removed && iter.Event.Raw.BlockNumber > 0 { // skip if chain reorg removed this event + // sanity check tx event + err := ob.CheckEvmTxLog(&iter.Event.Raw, addrConnector, "", TopicsZetaSent) + if err == nil { events = append(events, iter.Event) continue } - ob.logger.ExternalChainWatcher.Warn().Msgf("observeZetaSent: invalid event in tx %s at height %d for chain %d", - iter.Event.Raw.TxHash.Hex(), iter.Event.Raw.BlockNumber, ob.chain.ChainId) + ob.logger.ExternalChainWatcher.Warn().Err(err).Msgf("observeZetaSent: invalid ZetaSent event in tx %s on chain %d at height %d", + iter.Event.Raw.TxHash.Hex(), ob.chain.ChainId, iter.Event.Raw.BlockNumber) } sort.SliceStable(events, func(i, j int) bool { if events[i].Raw.BlockNumber == events[j].Raw.BlockNumber { @@ -970,7 +991,7 @@ func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { // returns the last block successfully scanned func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint64 { // filter ERC20CustodyDeposited logs - erc20custodyContract, err := ob.GetERC20CustodyContract() + addrCustody, erc20custodyContract, err := ob.GetERC20CustodyContract() if err != nil { ob.logger.ExternalChainWatcher.Warn().Err(err).Msgf("observeERC20Deposited: GetERC20CustodyContract error:") return startBlock - 1 // lastScanned @@ -989,12 +1010,14 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint // collect and sort events by block number, then tx index, then log index (ascending) events := make([]*erc20custody.ERC20CustodyDeposited, 0) for iter.Next() { - if !iter.Event.Raw.Removed && iter.Event.Raw.BlockNumber > 0 { // skip if chain reorg removed this event + // sanity check tx event + err := ob.CheckEvmTxLog(&iter.Event.Raw, addrCustody, "", TopicsDeposited) + if err == nil { events = append(events, iter.Event) continue } - ob.logger.ExternalChainWatcher.Warn().Msgf("observeERC20Deposited: invalid event in tx %s at height %d for chain %d", - iter.Event.Raw.TxHash.Hex(), iter.Event.Raw.BlockNumber, ob.chain.ChainId) + ob.logger.ExternalChainWatcher.Warn().Err(err).Msgf("observeERC20Deposited: invalid Deposited event in tx %s on chain %d at height %d", + iter.Event.Raw.TxHash.Hex(), ob.chain.ChainId, iter.Event.Raw.BlockNumber) } sort.SliceStable(events, func(i, j int) bool { if events[i].Raw.BlockNumber == events[j].Raw.BlockNumber { diff --git a/zetaclient/inbound_tracker.go b/zetaclient/inbound_tracker.go index e5c370b54f..8a7ebd1147 100644 --- a/zetaclient/inbound_tracker.go +++ b/zetaclient/inbound_tracker.go @@ -156,7 +156,7 @@ func (ob *EVMChainClient) ObserveTrackerSuggestions() error { } func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) (string, error) { - connector, err := ob.GetConnectorContract() + addrConnector, connector, err := ob.GetConnectorContract() if err != nil { return "", err } @@ -166,13 +166,25 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) return "", err } + // check if the tx is confirmed + lastHeight := ob.GetLastBlockHeight() + if !ob.HasEnoughConfirmations(receipt, lastHeight) { + return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) + } + var msg types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { event, err := connector.ParseZetaSent(*log) if err == nil && event != nil { - msg, err = ob.GetInboundVoteMsgForZetaSentEvent(event) + // sanity check tx event + err = ob.CheckEvmTxLog(&event.Raw, addrConnector, txHash, TopicsZetaSent) if err == nil { - break + msg, err = ob.GetInboundVoteMsgForZetaSentEvent(event) + if err == nil { + break + } + } else { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on ZetaSent event") } } } @@ -192,7 +204,7 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) } func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) (string, error) { - custody, err := ob.GetERC20CustodyContract() + addrCustory, custody, err := ob.GetERC20CustodyContract() if err != nil { return "", err } @@ -201,13 +213,26 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) if err != nil { return "", err } + + // check if the tx is confirmed + lastHeight := ob.GetLastBlockHeight() + if !ob.HasEnoughConfirmations(receipt, lastHeight) { + return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) + } + var msg types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { zetaDeposited, err := custody.ParseDeposited(*log) if err == nil && zetaDeposited != nil { - msg, err = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited) + // sanity check tx event + err = ob.CheckEvmTxLog(&zetaDeposited.Raw, addrCustory, txHash, TopicsDeposited) if err == nil { - break + msg, err = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited) + if err == nil { + break + } + } else { + ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on Deposited event") } } } @@ -245,6 +270,13 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) ( ob.logger.ExternalChainWatcher.Info().Msgf("tx %s failed; don't act", tx.Hash().Hex()) return "", errors.New("tx not successful yet") } + + // check if the tx is confirmed + lastHeight := ob.GetLastBlockHeight() + if !ob.HasEnoughConfirmations(receipt, lastHeight) { + return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) + } + block, err := ob.evmClient.BlockByNumber(context.Background(), receipt.BlockNumber) if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msg("BlockByNumber error") diff --git a/zetaclient/utils.go b/zetaclient/utils.go index d3702a62e9..0dfa5cb973 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -170,6 +170,32 @@ func (t *DynamicTicker) Stop() { t.impl.Stop() } +// CheckEvmTxLog checks the basics of an EVM tx log +func (ob *EVMChainClient) CheckEvmTxLog(vLog *ethtypes.Log, wantAddress ethcommon.Address, wantHash string, wantTopics int) error { + if vLog.Removed { + return fmt.Errorf("log is removed, chain reorg?") + } + if vLog.Address != wantAddress { + return fmt.Errorf("log emitter address mismatch: want %s got %s", wantAddress.Hex(), vLog.Address.Hex()) + } + if vLog.TxHash.Hex() == "" { + return fmt.Errorf("log tx hash is empty: %d %s", vLog.BlockNumber, vLog.TxHash.Hex()) + } + if wantHash != "" && vLog.TxHash.Hex() != wantHash { + return fmt.Errorf("log tx hash mismatch: want %s got %s", wantHash, vLog.TxHash.Hex()) + } + if len(vLog.Topics) != wantTopics { + return fmt.Errorf("number of topics mismatch: want %d got %d", wantTopics, len(vLog.Topics)) + } + return nil +} + +// HasEnoughConfirmations checks if the given receipt has enough confirmations +func (ob *EVMChainClient) HasEnoughConfirmations(receipt *ethtypes.Receipt, lastHeight uint64) bool { + confHeight := receipt.BlockNumber.Uint64() + ob.GetChainParams().ConfirmationCount + return lastHeight >= confHeight +} + func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody.ERC20CustodyDeposited) (types.MsgVoteOnObservedInboundTx, error) { ob.logger.ExternalChainWatcher.Info().Msgf("TxBlockNumber %d Transaction Hash: %s Message : %s", event.Raw.BlockNumber, event.Raw.TxHash, event.Message) if bytes.Equal(event.Message, []byte(DonationMessage)) { diff --git a/zetaclient/utils_test.go b/zetaclient/utils_test.go new file mode 100644 index 0000000000..98355e82ac --- /dev/null +++ b/zetaclient/utils_test.go @@ -0,0 +1,102 @@ +package zetaclient + +import ( + "fmt" + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" +) + +func TestCheckEvmTxLog(t *testing.T) { + // test data + connectorAddr := ethcommon.HexToAddress("0x00005e3125aba53c5652f9f0ce1a4cf91d8b15ea") + txHash := "0xb252c9e77feafdeeae25cc1f037a16c4b50fa03c494754b99a7339d816c79626" + topics := []ethcommon.Hash{ + // https://goerli.etherscan.io/tx/0xb252c9e77feafdeeae25cc1f037a16c4b50fa03c494754b99a7339d816c79626#eventlog + ethcommon.HexToHash("0x7ec1c94701e09b1652f3e1d307e60c4b9ebf99aff8c2079fd1d8c585e031c4e4"), + ethcommon.HexToHash("0x00000000000000000000000023856df5d563bd893fc7df864102d8bbfe7fc487"), + ethcommon.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000061"), + } + + tests := []struct { + name string + vLog *ethtypes.Log + fail bool + }{ + { + name: "chain reorganization", + vLog: ðtypes.Log{ + Removed: true, + Address: connectorAddr, + TxHash: ethcommon.HexToHash(txHash), + Topics: topics, + }, + fail: true, + }, + { + name: "emitter address mismatch", + vLog: ðtypes.Log{ + Removed: false, + Address: ethcommon.HexToAddress("0x184ba627DB853244c9f17f3Cb4378cB8B39bf147"), + TxHash: ethcommon.HexToHash(txHash), + Topics: topics, + }, + fail: true, + }, + { + name: "tx hash mismatch", + vLog: ðtypes.Log{ + Removed: false, + Address: connectorAddr, + TxHash: ethcommon.HexToHash("0x781c018d604af4dad0fe5e3cea4ad9fb949a996d8cd0cd04a92cadd7f08c05f2"), + Topics: topics, + }, + fail: true, + }, + { + name: "topics mismatch", + vLog: ðtypes.Log{ + Removed: false, + Address: connectorAddr, + TxHash: ethcommon.HexToHash(txHash), + Topics: []ethcommon.Hash{ + // https://goerli.etherscan.io/tx/0xb252c9e77feafdeeae25cc1f037a16c4b50fa03c494754b99a7339d816c79626#eventlog + ethcommon.HexToHash("0x7ec1c94701e09b1652f3e1d307e60c4b9ebf99aff8c2079fd1d8c585e031c4e4"), + ethcommon.HexToHash("0x00000000000000000000000023856df5d563bd893fc7df864102d8bbfe7fc487"), + }, + }, + fail: true, + }, + { + name: "should pass", + vLog: ðtypes.Log{ + Removed: false, + Address: connectorAddr, + TxHash: ethcommon.HexToHash(txHash), + Topics: topics, + }, + fail: false, + }, + } + + evmClient := EVMChainClient{} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fmt.Printf("check test: %s\n", tt.name) + err := evmClient.CheckEvmTxLog( + tt.vLog, + connectorAddr, + "0xb252c9e77feafdeeae25cc1f037a16c4b50fa03c494754b99a7339d816c79626", + TopicsZetaSent, + ) + if tt.fail { + require.Error(t, err) + return + } else { + require.NoError(t, err) + } + }) + } +} From bd88cf0f21f127cc49ff375480ceda0990d41e7e Mon Sep 17 00:00:00 2001 From: Christopher Fuka <97121270+CryptoFewka@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:11:11 -0600 Subject: [PATCH 16/67] docs: Update the --ledger --hd-path hint for clarity (#1553) * Update the --ledger --hd-path hint for clarity - replace the second line of the hint with `Please set a blank path with --hd-path="" to use Cosmos HD path instead.` * Update changelog.md * Update cmd/zetacored/main.go Co-authored-by: Lucas Bertrand --------- Co-authored-by: Charlie <31941002+CharlieMc0@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- changelog.md | 1 + cmd/zetacored/main.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 9ae132349c..a09cc2d5bb 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,7 @@ * Remove chain id from the index for observer mapper and rename it to observer set. * Add logger to smoke tests * [1521](https://github.com/zeta-chain/node/pull/1521) - replace go-tss lib version with one that reverts back to thorchain tss-lib +* Update --ledger flag hint ### Chores * [1446](https://github.com/zeta-chain/node/pull/1446) - renamed file `zetaclientd/aux.go` to `zetaclientd/utils.go` to avoid complaints from go package resolver. diff --git a/cmd/zetacored/main.go b/cmd/zetacored/main.go index 5da5d57913..4b12f153c7 100644 --- a/cmd/zetacored/main.go +++ b/cmd/zetacored/main.go @@ -34,7 +34,7 @@ func processError(err error) { if strings.Contains(err.Error(), "cannot set custom bip32 path with ledger") { printNotice([]string{ "note: --ledger flag can't be used with Ethereum HD path (used by default)", - "use --hd-path=\"\" in the command to use Cosmos HD path", + "Please set a blank path with --hd-path=\"\" to use Cosmos HD path instead.", }) os.Exit(1) } From 361fcafceadf6d65df913f833467ec5ac5818d8e Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:39:41 -0600 Subject: [PATCH 17/67] fix: unprivileged outtx tracker removal (#1533) * unprivileged outtx tracker removal * updated changelog * added extra comment * differentiate API call failure from ErrCannotFindCctx --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + .../keeper/msg_server_add_to_outtx_tracker.go | 30 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/changelog.md b/changelog.md index a09cc2d5bb..a80e9cdd5a 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ ### Fixes +* [1516](https://github.com/zeta-chain/node/issues/1516) - Unprivileged outtx tracker removal * [1537](https://github.com/zeta-chain/node/issues/1537) - Sanity check events of ZetaSent/ZetaReceived/ZetaRevertedWithdrawn/Deposited * [1530](https://github.com/zeta-chain/node/pull/1530) - Outbound tx confirmation/inclusion enhancement * [1496](https://github.com/zeta-chain/node/issues/1496) - post block header for enabled EVM chains only diff --git a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go index 0af5fc9a2b..64f1396859 100644 --- a/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_outtx_tracker.go @@ -29,6 +29,24 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO return nil, observertypes.ErrSupportedChains } + // the cctx must exist + cctx, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: msg.ChainId, + Nonce: msg.Nonce, + }) + if err != nil { + return nil, cosmoserrors.Wrap(err, "CcxtByNonce failed") + } + if cctx == nil || cctx.CrossChainTx == nil { + return nil, cosmoserrors.Wrapf(types.ErrCannotFindCctx, "no corresponding cctx found for chain %d, nonce %d", msg.ChainId, msg.Nonce) + } + // tracker submission is only allowed when the cctx is pending + if !IsPending(*cctx.CrossChainTx) { + // garbage tracker (for any reason) is harmful to outTx observation and should be removed + k.RemoveOutTxTracker(ctx, msg.ChainId, msg.Nonce) + return &types.MsgAddToOutTxTrackerResponse{IsRemoved: true}, nil + } + if msg.Proof == nil { // without proof, only certain accounts can send this message adminPolicyAccount := k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_group1) isAdmin := msg.Creator == adminPolicyAccount @@ -53,18 +71,6 @@ func (k msgServer) AddToOutTxTracker(goCtx context.Context, msg *types.MsgAddToO isProven = true } - cctx, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ - ChainID: msg.ChainId, - Nonce: msg.Nonce, - }) - if err != nil || cctx == nil || cctx.CrossChainTx == nil { - return nil, cosmoserrors.Wrap(types.ErrCannotFindCctx, "cannot add out tx: no corresponding cctx found") - } - if !IsPending(*cctx.CrossChainTx) { - k.RemoveOutTxTracker(ctx, msg.ChainId, msg.Nonce) - return &types.MsgAddToOutTxTrackerResponse{IsRemoved: true}, nil - } - tracker, found := k.GetOutTxTracker(ctx, msg.ChainId, msg.Nonce) hash := types.TxHashList{ TxHash: msg.TxHash, From a9c613ba25df7245dc5f8938f0a837333e600753 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 11 Jan 2024 12:59:20 -0800 Subject: [PATCH 18/67] fix(`rpc`): reduce websocket message limit to 10MB (#1555) * fix(): reduce websocket message limit to 10MB * changelogs --- changelog.md | 1 + rpc/websockets.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index a80e9cdd5a..1479bc50dd 100644 --- a/changelog.md +++ b/changelog.md @@ -36,6 +36,7 @@ * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses +* [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB ### Refactoring diff --git a/rpc/websockets.go b/rpc/websockets.go index c3b928dc36..3c64bfdb8a 100644 --- a/rpc/websockets.go +++ b/rpc/websockets.go @@ -47,7 +47,7 @@ import ( ) const ( - messageSizeLimit = 32 * 1024 * 1024 // 32MB + messageSizeLimit = 10 * 1024 * 1024 // 10MB ) From 7c33e546930dd7f33629656575d793e006cc9a48 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 11 Jan 2024 13:19:38 -0800 Subject: [PATCH 19/67] refactor(`crosschain`): change log level for gas stability pool iteration error (#1558) * change log level for gas stability pool iteration error * changelog --- changelog.md | 1 + x/crosschain/module.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 1479bc50dd..cee0204501 100644 --- a/changelog.md +++ b/changelog.md @@ -53,6 +53,7 @@ * Remove chain id from the index for observer mapper and rename it to observer set. * Add logger to smoke tests * [1521](https://github.com/zeta-chain/node/pull/1521) - replace go-tss lib version with one that reverts back to thorchain tss-lib +* [1558](https://github.com/zeta-chain/node/pull/1558) - change log level for gas stability pool iteration error * Update --ledger flag hint ### Chores diff --git a/x/crosschain/module.go b/x/crosschain/module.go index a0177cd11e..9e2e4ec81b 100644 --- a/x/crosschain/module.go +++ b/x/crosschain/module.go @@ -190,7 +190,7 @@ func (AppModule) ConsensusVersion() uint64 { return 4 } func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { err := am.keeper.IterateAndUpdateCctxGasPrice(ctx) if err != nil { - ctx.Logger().Error("Error iterating and updating pending cctx gas price", "err", err.Error()) + ctx.Logger().Info("Error iterating and updating pending cctx gas price", "err", err.Error()) } } From 81f8c6375dbb1aafa60ab5a8cac4ac3a1b1ece21 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:38:05 -0600 Subject: [PATCH 20/67] fix: cherry picked hot fixes from v11.0.x (#1561) * cherry picked hot fixes from v11.0.x * update changelog --- changelog.md | 1 + zetaclient/bitcoin_client.go | 8 ++-- zetaclient/evm_client.go | 8 ++-- zetaclient/evm_signer.go | 76 ++++++++++++++++++++++++++++++------ 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index cee0204501..b09a9512ef 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ ### Fixes +* [1560](https://github.com/zeta-chain/node/issues/1560) - Zetaclient post evm-chain outtx hashes only when receipt is available * [1516](https://github.com/zeta-chain/node/issues/1516) - Unprivileged outtx tracker removal * [1537](https://github.com/zeta-chain/node/issues/1537) - Sanity check events of ZetaSent/ZetaReceived/ZetaRevertedWithdrawn/Deposited * [1530](https://github.com/zeta-chain/node/pull/1530) - Outbound tx confirmation/inclusion enhancement diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 2b9f242b56..43a0cc422e 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -365,9 +365,11 @@ func (ob *BitcoinChainClient) observeInTx() error { } // add block header to zetacore - err = ob.postBlockHeader(bn) - if err != nil { - ob.logger.WatchInTx.Warn().Err(err).Msgf("observeInTxBTC: error posting block header %d", bn) + if flags.BlockHeaderVerificationFlags != nil && flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled { + err = ob.postBlockHeader(bn) + if err != nil { + ob.logger.WatchInTx.Warn().Err(err).Msgf("observeInTxBTC: error posting block header %d", bn) + } } tssAddress := ob.Tss.BTCAddress() diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 86d4444f60..8a68ac121e 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -885,7 +885,7 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { lastScannedDeposited := ob.observeERC20Deposited(startBlock, toBlock) // task 3: query the incoming tx to TSS address (read at most 100 blocks in one go) - lastScannedTssRecvd := ob.observeTssRecvd(startBlock, toBlock) + lastScannedTssRecvd := ob.observeTssRecvd(startBlock, toBlock, flags) // note: using lowest height for all 3 events is not perfect, but it's simple and good enough lastScannedLowest := lastScannedZetaSent @@ -1068,7 +1068,7 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint // observeTssRecvd queries the incoming gas asset to TSS address and posts to zetacore // returns the last block successfully scanned -func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64) uint64 { +func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags observertypes.CrosschainFlags) uint64 { // check TSS address (after keygen, ob.Tss.pubkey will be updated) tssAddress := ob.Tss.EVMAddress() if tssAddress == (ethcommon.Address{}) { @@ -1080,7 +1080,9 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64) uint64 { for bn := startBlock; bn <= toBlock; bn++ { // post new block header (if any) to zetacore and ignore error // TODO: consider having a independent ticker(from TSS scaning) for posting block headers - if common.IsHeaderSupportedEvmChain(ob.chain.ChainId) { // post block header for supported chains + if flags.BlockHeaderVerificationFlags != nil && + flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled && + common.IsHeaderSupportedEvmChain(ob.chain.ChainId) { // post block header for supported chains err := ob.postBlockHeader(toBlock) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting block header") diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index 7882104cd5..c961a627e0 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -9,6 +9,7 @@ import ( "math/rand" "strconv" "strings" + "sync" "time" "github.com/ethereum/go-ethereum/accounts/abi" @@ -24,6 +25,10 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) +const ( + OutTxTrackerReportTimeout = 10 * time.Minute +) + type EVMSigner struct { client EVMRPCClient chain *common.Chain @@ -36,6 +41,10 @@ type EVMSigner struct { erc20CustodyContractAddress ethcommon.Address logger zerolog.Logger ts *TelemetryServer + + // for outTx tracker report only + mu *sync.Mutex + outTxHashBeingReported map[string]bool } var _ ChainSigner = &EVMSigner{} @@ -83,7 +92,9 @@ func NewEVMSigner( logger: logger.With(). Str("chain", chain.ChainName.String()). Str("module", "EVMSigner").Logger(), - ts: ts, + ts: ts, + mu: &sync.Mutex{}, + outTxHashBeingReported: make(map[string]bool), }, nil } @@ -566,11 +577,7 @@ func (signer *EVMSigner) TryProcessOutTx( log.Warn().Err(err).Msgf("OutTx Broadcast error") retry, report := HandleBroadcastError(err, strconv.FormatUint(send.GetCurrentOutTxParam().OutboundTxTssNonce, 10), toChain.String(), outTxHash) if report { - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash, nil, "", -1) - if err != nil { - logger.Err(err).Msgf("Unable to add to tracker on ZetaCore: nonce %d chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) - } - logger.Info().Msgf("Broadcast to core successful %s", zetaHash) + signer.reportToOutTxTracker(zetaBridge, toChain.ChainId, tx.Nonce(), outTxHash, logger) } if !retry { break @@ -579,15 +586,62 @@ func (signer *EVMSigner) TryProcessOutTx( continue } logger.Info().Msgf("Broadcast success: nonce %d to chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(toChain.ChainId, tx.Nonce(), outTxHash, nil, "", -1) - if err != nil { - logger.Err(err).Msgf("Unable to add to tracker on ZetaCore: nonce %d chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) - } - logger.Info().Msgf("Broadcast to core successful %s", zetaHash) + signer.reportToOutTxTracker(zetaBridge, toChain.ChainId, tx.Nonce(), outTxHash, logger) break // successful broadcast; no need to retry } + } +} +// reportToOutTxTracker reports outTxHash to tracker only when tx receipt is available +func (signer *EVMSigner) reportToOutTxTracker(zetaBridge ZetaCoreBridger, chainID int64, nonce uint64, outTxHash string, logger zerolog.Logger) { + // skip if already being reported + signer.mu.Lock() + defer signer.mu.Unlock() + if _, found := signer.outTxHashBeingReported[outTxHash]; found { + logger.Info().Msgf("reportToOutTxTracker: outTxHash %s for chain %d nonce %d is being reported", outTxHash, chainID, nonce) + return } + signer.outTxHashBeingReported[outTxHash] = true // mark as being reported + + // report to outTx tracker with goroutine + go func() { + defer func() { + signer.mu.Lock() + delete(signer.outTxHashBeingReported, outTxHash) + signer.mu.Unlock() + }() + + // try fetching tx receipt for 10 minutes + tStart := time.Now() + for { + if time.Since(tStart) > OutTxTrackerReportTimeout { // give up after 10 minutes + logger.Info().Msgf("reportToOutTxTracker: outTxHash report timeout for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + return + } + receipt, err := signer.client.TransactionReceipt(context.TODO(), ethcommon.HexToHash(outTxHash)) + if err != nil { + logger.Info().Err(err).Msgf("reportToOutTxTracker: receipt not available for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + time.Sleep(10 * time.Second) + continue + } + if receipt != nil { + _, isPending, err := signer.client.TransactionByHash(context.TODO(), ethcommon.HexToHash(outTxHash)) + if err != nil || isPending { + logger.Info().Err(err).Msgf("reportToOutTxTracker: error getting tx or tx is pending for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + time.Sleep(10 * time.Second) + continue + } + break + } + } + + // report to outTxTracker + zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(chainID, nonce, outTxHash, nil, "", -1) + if err != nil { + logger.Err(err).Msgf("reportToOutTxTracker: unable to add to tracker on ZetaCore for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + } + logger.Info().Msgf("reportToOutTxTracker: reported outTxHash to core successful %s, chain %d nonce %d outTxHash %s", zetaHash, chainID, nonce, outTxHash) + }() } // SignERC20WithdrawTx From c388606eae3866a970ad3b7e178a838f87122907 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:13:50 -0600 Subject: [PATCH 21/67] screen out unconfirmed utxos that are not created by TSS itself (#1554) --- changelog.md | 1 + zetaclient/bitcoin_client.go | 41 +++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/changelog.md b/changelog.md index b09a9512ef..e8f7f36cb7 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ ### Fixes +* [1554](https://github.com/zeta-chain/node/pull/1554) - Screen out unconfirmed UTXOs that are not created by TSS itself * [1560](https://github.com/zeta-chain/node/issues/1560) - Zetaclient post evm-chain outtx hashes only when receipt is available * [1516](https://github.com/zeta-chain/node/issues/1516) - Unprivileged outtx tracker removal * [1537](https://github.com/zeta-chain/node/issues/1537) - Sanity check events of ZetaSent/ZetaReceived/ZetaRevertedWithdrawn/Deposited diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 43a0cc422e..39649a0307 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -57,7 +57,7 @@ type BitcoinChainClient struct { Mu *sync.Mutex // lock for all the maps, utxos and core params pendingNonce uint64 - includedTxHashes map[string]uint64 // key: tx hash + 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 @@ -147,7 +147,7 @@ func NewBitcoinClient( ob.zetaClient = bridge ob.Tss = tss - ob.includedTxHashes = make(map[string]uint64) + ob.includedTxHashes = make(map[string]bool) ob.includedTxResults = make(map[string]*btcjson.GetTransactionResult) ob.broadcastedTx = make(map[string]string) ob.params = btcCfg.ChainParams @@ -757,16 +757,13 @@ func (ob *BitcoinChainClient) FetchUTXOS() error { } maxConfirmations := int(bh) - // List unspent. + // List all unspent UTXOs (160ms) tssAddr := ob.Tss.BTCAddress() address, err := common.DecodeBtcAddress(tssAddr, ob.chain.ChainId) if err != nil { return fmt.Errorf("btc: error decoding wallet address (%s) : %s", tssAddr, err.Error()) } - addresses := []btcutil.Address{address} - - // fetching all TSS utxos takes 160ms - utxos, err := ob.rpcClient.ListUnspentMinMaxAddresses(0, maxConfirmations, addresses) + utxos, err := ob.rpcClient.ListUnspentMinMaxAddresses(0, maxConfirmations, []btcutil.Address{address}) if err != nil { return err } @@ -782,12 +779,20 @@ func (ob *BitcoinChainClient) FetchUTXOS() error { return utxos[i].Amount < utxos[j].Amount }) - // filter UTXOs big enough to cover the cost of spending themselves + // filter UTXOs good to spend for next TSS transaction utxosFiltered := make([]btcjson.ListUnspentResult, 0) for _, utxo := range utxos { - if utxo.Amount >= BtcDepositorFeeMin { - utxosFiltered = append(utxosFiltered, utxo) + // UTXOs big enough to cover the cost of spending themselves + if utxo.Amount < BtcDepositorFeeMin { + continue + } + // we don't want to spend other people's unconfirmed UTXOs as they may not be safe to spend + if utxo.Confirmations == 0 { + if !ob.isTssTransaction(utxo.TxID) { + continue + } } + utxosFiltered = append(utxosFiltered, utxo) } ob.Mu.Lock() @@ -797,6 +802,13 @@ func (ob *BitcoinChainClient) 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 *BitcoinChainClient) 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. @@ -1083,6 +1095,7 @@ func (ob *BitcoinChainClient) setIncludedTx(nonce uint64, getTxResult *btcjson.G 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 @@ -1107,11 +1120,15 @@ func (ob *BitcoinChainClient) getIncludedTx(nonce uint64) *btcjson.GetTransactio return ob.includedTxResults[ob.GetTxID(nonce)] } -// removeIncludedTx removes included tx's result from memory +// removeIncludedTx removes included tx from memory func (ob *BitcoinChainClient) removeIncludedTx(nonce uint64) { ob.Mu.Lock() defer ob.Mu.Unlock() - delete(ob.includedTxResults, ob.GetTxID(nonce)) + txResult, found := ob.includedTxResults[ob.GetTxID(nonce)] + if found { + delete(ob.includedTxHashes, txResult.TxID) + delete(ob.includedTxResults, ob.GetTxID(nonce)) + } } // Basic TSS outTX checks: From b2fbd84736275c0c15bf96a6dc333fceba8bda44 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 11 Jan 2024 14:36:43 -0800 Subject: [PATCH 22/67] refactor(`MsgUpdateCrosschainFlags`): requires group2 policy type to enable header verification (#1552) * required group function * require function tests * update message logic * add changelog --- changelog.md | 1 + .../msg_server_update_crosschain_flags.go | 7 +- ...msg_server_update_crosschain_flags_test.go | 33 ++++- x/observer/types/message_crosschain_flags.go | 18 +++ .../types/message_crosschain_flags_test.go | 115 ++++++++++++++++++ 5 files changed, 166 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index e8f7f36cb7..27f2123f35 100644 --- a/changelog.md +++ b/changelog.md @@ -42,6 +42,7 @@ ### Refactoring +* [1552](https://github.com/zeta-chain/node/pull/1552) - requires group2 to enable header verification * [1211](https://github.com/zeta-chain/node/issues/1211) - use `grpc` and `msg` for query and message files * refactor cctx scheduler - decouple evm cctx scheduler from btc cctx scheduler * move tss state from crosschain to observer diff --git a/x/observer/keeper/msg_server_update_crosschain_flags.go b/x/observer/keeper/msg_server_update_crosschain_flags.go index 41904c75be..30325bef64 100644 --- a/x/observer/keeper/msg_server_update_crosschain_flags.go +++ b/x/observer/keeper/msg_server_update_crosschain_flags.go @@ -14,13 +14,8 @@ import ( func (k msgServer) UpdateCrosschainFlags(goCtx context.Context, msg *types.MsgUpdateCrosschainFlags) (*types.MsgUpdateCrosschainFlagsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - requiredGroup := types.Policy_Type_group1 - if msg.IsInboundEnabled || msg.IsOutboundEnabled || msg.GasPriceIncreaseFlags != nil { - requiredGroup = types.Policy_Type_group2 - } - // check permission - if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(requiredGroup) { + if msg.Creator != k.GetParams(ctx).GetAdminPolicyAccount(msg.GetRequiredGroup()) { return &types.MsgUpdateCrosschainFlagsResponse{}, types.ErrNotAuthorizedPolicy } diff --git a/x/observer/keeper/msg_server_update_crosschain_flags_test.go b/x/observer/keeper/msg_server_update_crosschain_flags_test.go index 6481b44ee0..555988694c 100644 --- a/x/observer/keeper/msg_server_update_crosschain_flags_test.go +++ b/x/observer/keeper/msg_server_update_crosschain_flags_test.go @@ -57,6 +57,7 @@ func TestMsgServer_UpdateCrosschainFlags(t *testing.T) { require.Equal(t, uint32(42), flags.GasPriceIncreaseFlags.GasPriceIncreasePercent) require.True(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) require.False(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group2) // can update flags again @@ -71,7 +72,7 @@ func TestMsgServer_UpdateCrosschainFlags(t *testing.T) { }, BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ IsEthTypeChainEnabled: false, - IsBtcTypeChainEnabled: false, + IsBtcTypeChainEnabled: true, }, }) require.NoError(t, err) @@ -84,7 +85,8 @@ func TestMsgServer_UpdateCrosschainFlags(t *testing.T) { require.Equal(t, time.Minute*43, flags.GasPriceIncreaseFlags.RetryInterval) require.Equal(t, uint32(43), flags.GasPriceIncreaseFlags.GasPriceIncreasePercent) require.False(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) - require.False(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) + require.True(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) + // group 1 should be able to disable inbound and outbound setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) @@ -103,6 +105,33 @@ func TestMsgServer_UpdateCrosschainFlags(t *testing.T) { require.Equal(t, int64(43), flags.GasPriceIncreaseFlags.EpochLength) require.Equal(t, time.Minute*43, flags.GasPriceIncreaseFlags.RetryInterval) require.Equal(t, uint32(43), flags.GasPriceIncreaseFlags.GasPriceIncreasePercent) + require.False(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) + require.True(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) + + // group 1 should be able to disable header verification + setAdminCrossChainFlags(ctx, k, admin, types.Policy_Type_group1) + + // if gas price increase flags is nil, it should not be updated + _, err = srv.UpdateCrosschainFlags(sdk.WrapSDKContext(ctx), &types.MsgUpdateCrosschainFlags{ + Creator: admin, + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: false, + }, + }) + require.NoError(t, err) + + flags, found = k.GetCrosschainFlags(ctx) + require.True(t, found) + require.False(t, flags.IsInboundEnabled) + require.False(t, flags.IsOutboundEnabled) + require.Equal(t, int64(43), flags.GasPriceIncreaseFlags.EpochLength) + require.Equal(t, time.Minute*43, flags.GasPriceIncreaseFlags.RetryInterval) + require.Equal(t, uint32(43), flags.GasPriceIncreaseFlags.GasPriceIncreasePercent) + require.False(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) + require.False(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) // if flags are not defined, default should be used k.RemoveCrosschainFlags(ctx) diff --git a/x/observer/types/message_crosschain_flags.go b/x/observer/types/message_crosschain_flags.go index cdca148a94..58d49cd3d3 100644 --- a/x/observer/types/message_crosschain_flags.go +++ b/x/observer/types/message_crosschain_flags.go @@ -67,3 +67,21 @@ func (gpf GasPriceIncreaseFlags) Validate() error { } return nil } + +// GetRequiredGroup returns the required group policy for the message to execute the message +// Group 1 should only be able to stop or disable functiunalities in case of emergency +// this concerns disabling inbound and outbound txs or block header verification +// every other action requires group 2 +func (msg *MsgUpdateCrosschainFlags) GetRequiredGroup() Policy_Type { + if msg.IsInboundEnabled || msg.IsOutboundEnabled { + return Policy_Type_group2 + } + if msg.GasPriceIncreaseFlags != nil { + return Policy_Type_group2 + } + if msg.BlockHeaderVerificationFlags != nil && (msg.BlockHeaderVerificationFlags.IsEthTypeChainEnabled || msg.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) { + return Policy_Type_group2 + + } + return Policy_Type_group1 +} diff --git a/x/observer/types/message_crosschain_flags_test.go b/x/observer/types/message_crosschain_flags_test.go index f01c33e6ef..199b80c13a 100644 --- a/x/observer/types/message_crosschain_flags_test.go +++ b/x/observer/types/message_crosschain_flags_test.go @@ -116,3 +116,118 @@ func TestGasPriceIncreaseFlags_Validate(t *testing.T) { }) } } + +func TestMsgUpdateCrosschainFlags_GetRequiredGroup(t *testing.T) { + tests := []struct { + name string + msg types.MsgUpdateCrosschainFlags + want types.Policy_Type + }{ + { + name: "disabling outbound and inbound allows group 1", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: nil, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group1, + }, + { + name: "disabling outbound and inbound and block header verification allows group 1", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: false, + }, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group1, + }, + { + name: "updating gas price increase flags requires group 2", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: false, + }, + GasPriceIncreaseFlags: &types.GasPriceIncreaseFlags{ + EpochLength: 1, + RetryInterval: 1, + GasPriceIncreasePercent: 1, + MaxPendingCctxs: 100, + }, + }, + want: types.Policy_Type_group2, + }, + { + name: "enabling inbound requires group 2", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: true, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: false, + }, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group2, + }, + { + name: "enabling outbound requires group 2", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: true, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: false, + }, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group2, + }, + { + name: "enabling eth header verification requires group 2", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: true, + IsBtcTypeChainEnabled: false, + }, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group2, + }, + { + name: "enabling btc header verification requires group 2", + msg: types.MsgUpdateCrosschainFlags{ + Creator: sample.AccAddress(), + IsInboundEnabled: false, + IsOutboundEnabled: false, + BlockHeaderVerificationFlags: &types.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + IsBtcTypeChainEnabled: true, + }, + GasPriceIncreaseFlags: nil, + }, + want: types.Policy_Type_group2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, tt.msg.GetRequiredGroup()) + }) + } +} From fde9cabb64770c221fe80fe820af2918a33c0501 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 11 Jan 2024 15:10:43 -0800 Subject: [PATCH 23/67] fix(`crosschain`): add emptiness check for topic array in event parsing (#1556) * add check for topic len * changelogs --- changelog.md | 1 + x/crosschain/keeper/evm_hooks.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/changelog.md b/changelog.md index 27f2123f35..ad0deb58d3 100644 --- a/changelog.md +++ b/changelog.md @@ -38,6 +38,7 @@ * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses +* [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB ### Refactoring diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index e4c3ed5d4b..f2b9f6bc8d 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -275,6 +275,9 @@ func (k Keeper) ParseZRC20WithdrawalEvent(ctx sdk.Context, log ethtypes.Log) (*z if err != nil { return nil, err } + if len(log.Topics) == 0 { + return nil, fmt.Errorf("ParseZRC20WithdrawalEvent: invalid log - no topics") + } event, err := zrc20ZEVM.ParseWithdrawal(log) if err != nil { return nil, err @@ -306,6 +309,9 @@ func ParseZetaSentEvent(log ethtypes.Log, connectorZEVM ethcommon.Address) (*con if err != nil { return nil, err } + if len(log.Topics) == 0 { + return nil, fmt.Errorf("ParseZetaSentEvent: invalid log - no topics") + } event, err := zetaConnectorZEVM.ParseZetaSent(log) if err != nil { return nil, err From 736d6164894a31e27aff9b46d4cc6f4a53fe53f0 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jan 2024 18:43:18 -0500 Subject: [PATCH 24/67] fix: adds an index to keep track of finalized inbounds and prevent duplicate (#1536) * add finalized inbound * fix lint * fix unit test * changelog entry * add function to generate key for finalized inbound * add proto files * add simple test for evm deposit * add todo for improving unit tests * generate files * add nosec * add genesis inmport export form Finalzied inbounds * add log lines * avoid creation of ballots during double spend * add changelog entry * remove changelog entry --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + docs/openapi/openapi.swagger.yaml | 15 ++ proto/crosschain/cross_chain_tx.proto | 8 + proto/crosschain/genesis.proto | 1 + standalone-network/change-observer-params.sh | 2 +- standalone-network/proposal_feemarket.json | 15 ++ testutil/sample/common.go | 5 + testutil/sample/crosschain.go | 19 ++ testutil/sample/observer.go | 12 +- testutil/sample/sample.go | 12 +- typescript/crosschain/cross_chain_tx_pb.d.ts | 36 +++ typescript/crosschain/genesis_pb.d.ts | 5 + .../client/integrationtests/cli_helpers.go | 9 +- .../integrationtests/inbound_voter_test.go | 10 +- .../integrationtests/outbound_voter_test.go | 8 +- x/crosschain/genesis.go | 5 +- x/crosschain/keeper/finalized_inbounds.go | 34 +++ .../keeper/finalized_inbounds_test.go | 82 ++++++ .../keeper/msg_server_vote_inbound_tx.go | 12 +- .../keeper/msg_server_vote_inbound_tx_test.go | 195 +++++++++++---- .../keeper/msg_server_vote_outbound_tx.go | 2 + x/crosschain/types/cross_chain_tx.pb.go | 235 +++++++++++++----- x/crosschain/types/errors.go | 17 +- x/crosschain/types/genesis.pb.go | 121 ++++++--- x/crosschain/types/keys.go | 9 +- x/observer/keeper/chain_nonces.go | 2 - 26 files changed, 684 insertions(+), 188 deletions(-) create mode 100644 standalone-network/proposal_feemarket.json create mode 100644 x/crosschain/keeper/finalized_inbounds.go create mode 100644 x/crosschain/keeper/finalized_inbounds_test.go diff --git a/changelog.md b/changelog.md index ad0deb58d3..c80a744c33 100644 --- a/changelog.md +++ b/changelog.md @@ -38,6 +38,7 @@ * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses +* [1536](https://github.com/zeta-chain/node/pull/1536) - add index to check previously finalized inbounds * [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index cb87e0dfc4..6c170fc142 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -50813,6 +50813,8 @@ definitions: inbound_tx_finalized_zeta_height: type: string format: uint64 + tx_finalization_status: + $ref: '#/definitions/crosschainTxFinalizationStatus' crosschainLastBlockHeight: type: object properties: @@ -50914,6 +50916,8 @@ definitions: format: uint64 tss_pubkey: type: string + tx_finalization_status: + $ref: '#/definitions/crosschainTxFinalizationStatus' crosschainQueryAllCctxResponse: type: object properties: @@ -51064,6 +51068,17 @@ definitions: properties: aborted_zeta_amount: type: string + crosschainTxFinalizationStatus: + type: string + enum: + - NotFinalized + - Finalized + - Executed + default: NotFinalized + title: |- + - NotFinalized: the corresponding tx is not finalized + - Finalized: the corresponding tx is finalized but not executed yet + - Executed: the corresponding tx is executed crosschainTxHashList: type: object properties: diff --git a/proto/crosschain/cross_chain_tx.proto b/proto/crosschain/cross_chain_tx.proto index ed38a74597..28f9d92452 100644 --- a/proto/crosschain/cross_chain_tx.proto +++ b/proto/crosschain/cross_chain_tx.proto @@ -16,6 +16,12 @@ enum CctxStatus { Aborted = 6; // inbound tx error or invalid paramters and cannot revert; just abort } +enum TxFinalizationStatus { + option (gogoproto.goproto_enum_stringer) = true; + NotFinalized = 0; // the corresponding tx is not finalized + Finalized = 1; // the corresponding tx is finalized but not executed yet + Executed = 2; // the corresponding tx is executed +} message InboundTxParams { string sender = 1; // this address is the immediate contract/EOA that calls the Connector.send() int64 sender_chain_id = 2; @@ -30,6 +36,7 @@ message InboundTxParams { uint64 inbound_tx_observed_external_height = 8; string inbound_tx_ballot_index = 9; uint64 inbound_tx_finalized_zeta_height = 10; + TxFinalizationStatus tx_finalization_status = 11; } message ZetaAccounting { @@ -63,6 +70,7 @@ message OutboundTxParams { ]; uint64 outbound_tx_effective_gas_limit = 22; string tss_pubkey = 11; + TxFinalizationStatus tx_finalization_status = 12; } message Status { diff --git a/proto/crosschain/genesis.proto b/proto/crosschain/genesis.proto index 46d1b18066..016fc38aee 100644 --- a/proto/crosschain/genesis.proto +++ b/proto/crosschain/genesis.proto @@ -22,4 +22,5 @@ message GenesisState { repeated InTxHashToCctx inTxHashToCctxList = 9 [(gogoproto.nullable) = false]; repeated InTxTracker in_tx_tracker_list = 11 [(gogoproto.nullable) = false]; ZetaAccounting zeta_accounting = 12 [(gogoproto.nullable) = false]; + repeated string FinalizedInbounds = 16; } diff --git a/standalone-network/change-observer-params.sh b/standalone-network/change-observer-params.sh index 209c33706e..4df238642f 100644 --- a/standalone-network/change-observer-params.sh +++ b/standalone-network/change-observer-params.sh @@ -1,2 +1,2 @@ -zetacored tx gov submit-proposal param-change proposal.json --from zeta --keyring-backend=test -b block --chain-id=localnet_101-1 --gas=auto --gas-prices=0.1azeta --gas-adjustment=1.5 --yes +zetacored tx gov submit-proposal proposal_feemarket.json --from zeta --keyring-backend=test -b block --chain-id=localnet_101-1 --gas=auto --gas-prices=0.1azeta --gas-adjustment=1.5 --yes zetacored tx gov vote 1 yes --from zeta --keyring-backend test --chain-id localnet_101-1 --yes --gas=auto --gas-prices=0.1azeta --gas-adjustment=1.5 \ No newline at end of file diff --git a/standalone-network/proposal_feemarket.json b/standalone-network/proposal_feemarket.json new file mode 100644 index 0000000000..1ec114d19a --- /dev/null +++ b/standalone-network/proposal_feemarket.json @@ -0,0 +1,15 @@ +{ + "messages": [ + { + "@type": "/ethermint.feemarket.v1.MsgUpdateParams", + "authority": "zeta10d07y265gmmuvt4z0w9aw880jnsr700jvxasvr", + "params": { + "base_fee": "7", + "min_gas_price" : "100000000000000", + "base_fee_change_denominator": "8" + } + } + ], + "metadata" : "some metadata", + "deposit": "10000000azeta" +} \ No newline at end of file diff --git a/testutil/sample/common.go b/testutil/sample/common.go index 0d41ea6862..d32ca30274 100644 --- a/testutil/sample/common.go +++ b/testutil/sample/common.go @@ -86,3 +86,8 @@ func Proof() (txIndex int64, block *ethtypes.Block, header ethtypes.Header, head tx = block.Transactions()[txIndex] return } + +func EventIndex() uint64 { + r := newRandFromSeed(1) + return r.Uint64() +} diff --git a/testutil/sample/crosschain.go b/testutil/sample/crosschain.go index a2e1e18846..35082be7d1 100644 --- a/testutil/sample/crosschain.go +++ b/testutil/sample/crosschain.go @@ -116,3 +116,22 @@ func ZetaAccounting(t *testing.T, index string) types.ZetaAccounting { AbortedZetaAmount: math.NewUint(uint64(r.Int63())), } } + +func InboundVote(coinType common.CoinType, from, to int64) types.MsgVoteOnObservedInboundTx { + return types.MsgVoteOnObservedInboundTx{ + Creator: "", + Sender: EthAddress().String(), + SenderChainId: Chain(from).GetChainId(), + Receiver: EthAddress().String(), + ReceiverChain: Chain(to).GetChainId(), + Amount: UintInRange(10000000, 1000000000), + Message: String(), + InBlockHeight: Uint64InRange(1, 10000), + GasLimit: 1000000000, + InTxHash: Hash().String(), + CoinType: coinType, + TxOrigin: EthAddress().String(), + Asset: "", + EventIndex: EventIndex(), + } +} diff --git a/testutil/sample/observer.go b/testutil/sample/observer.go index 19b186e845..b5d533c4e6 100644 --- a/testutil/sample/observer.go +++ b/testutil/sample/observer.go @@ -88,15 +88,15 @@ func ChainParams(chainID int64) *types.ChainParams { ChainId: chainID, ConfirmationCount: r.Uint64(), - GasPriceTicker: Uint64InRange(r, 1, 300), - InTxTicker: Uint64InRange(r, 1, 300), - OutTxTicker: Uint64InRange(r, 1, 300), - WatchUtxoTicker: Uint64InRange(r, 1, 300), + GasPriceTicker: Uint64InRange(1, 300), + InTxTicker: Uint64InRange(1, 300), + OutTxTicker: Uint64InRange(1, 300), + WatchUtxoTicker: Uint64InRange(1, 300), ZetaTokenContractAddress: EthAddress().String(), ConnectorContractAddress: EthAddress().String(), Erc20CustodyContractAddress: EthAddress().String(), - OutboundTxScheduleInterval: Int64InRange(r, 1, 100), - OutboundTxScheduleLookahead: Int64InRange(r, 1, 500), + OutboundTxScheduleInterval: Int64InRange(1, 100), + OutboundTxScheduleLookahead: Int64InRange(1, 500), BallotThreshold: fiftyPercent, MinObserverDelegation: sdk.NewDec(r.Int63()), IsSupported: false, diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 37bb1883e4..4fcc9ac9e8 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -7,6 +7,7 @@ import ( "strconv" "testing" + sdkmath "cosmossdk.io/math" "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -131,11 +132,18 @@ func Coins() sdk.Coins { } // Uint64InRange returns a sample uint64 in the given ranges -func Uint64InRange(r *rand.Rand, low, high uint64) uint64 { +func Uint64InRange(low, high uint64) uint64 { + r := newRandFromSeed(int64(low)) return r.Uint64()%(high-low) + low } // Int64InRange returns a sample int64 in the given ranges -func Int64InRange(r *rand.Rand, low, high int64) int64 { +func Int64InRange(low, high int64) int64 { + r := newRandFromSeed(low) return r.Int63()%(high-low) + low } + +func UintInRange(low, high uint64) sdkmath.Uint { + u := Uint64InRange(low, high) + return sdkmath.NewUint(u) +} diff --git a/typescript/crosschain/cross_chain_tx_pb.d.ts b/typescript/crosschain/cross_chain_tx_pb.d.ts index 4a00361f6f..d8216afcff 100644 --- a/typescript/crosschain/cross_chain_tx_pb.d.ts +++ b/typescript/crosschain/cross_chain_tx_pb.d.ts @@ -54,6 +54,32 @@ export declare enum CctxStatus { Aborted = 6, } +/** + * @generated from enum zetachain.zetacore.crosschain.TxFinalizationStatus + */ +export declare enum TxFinalizationStatus { + /** + * the corresponding tx is not finalized + * + * @generated from enum value: NotFinalized = 0; + */ + NotFinalized = 0, + + /** + * the corresponding tx is finalized but not executed yet + * + * @generated from enum value: Finalized = 1; + */ + Finalized = 1, + + /** + * the corresponding tx is executed + * + * @generated from enum value: Executed = 2; + */ + Executed = 2, +} + /** * @generated from message zetachain.zetacore.crosschain.InboundTxParams */ @@ -114,6 +140,11 @@ export declare class InboundTxParams extends Message { */ inboundTxFinalizedZetaHeight: bigint; + /** + * @generated from field: zetachain.zetacore.crosschain.TxFinalizationStatus tx_finalization_status = 11; + */ + txFinalizationStatus: TxFinalizationStatus; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; @@ -232,6 +263,11 @@ export declare class OutboundTxParams extends Message { */ tssPubkey: string; + /** + * @generated from field: zetachain.zetacore.crosschain.TxFinalizationStatus tx_finalization_status = 12; + */ + txFinalizationStatus: TxFinalizationStatus; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/typescript/crosschain/genesis_pb.d.ts b/typescript/crosschain/genesis_pb.d.ts index 7d4741170a..e8c8d5dcf0 100644 --- a/typescript/crosschain/genesis_pb.d.ts +++ b/typescript/crosschain/genesis_pb.d.ts @@ -59,6 +59,11 @@ export declare class GenesisState extends Message { */ zetaAccounting?: ZetaAccounting; + /** + * @generated from field: repeated string FinalizedInbounds = 16; + */ + FinalizedInbounds: string[]; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 7daaf2ed7e..03f565fc97 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -242,7 +242,7 @@ func BuildSignedOutboundVote( return WriteToNewTempFile(t, res.String()) } -func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, account authtypes.AccountI, message string) *os.File { +func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, account authtypes.AccountI, message string, eventIndex int) *os.File { cmd := cli.CmdCCTXInboundVoter() inboundVoterArgs := []string{ "0x96B05C238b99768F349135de0653b687f9c13fEE", @@ -256,7 +256,7 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, "100", "Zeta", "", - "0", + strconv.Itoa(eventIndex), } txArgs := []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), @@ -274,7 +274,7 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, return WriteToNewTempFile(t, res.String()) } -func GetBallotIdentifier(message string) string { +func GetBallotIdentifier(message string, eventIndex int) string { msg := types.NewMsgVoteOnObservedInboundTx( "", "0x96B05C238b99768F349135de0653b687f9c13fEE", @@ -289,7 +289,8 @@ func GetBallotIdentifier(message string) string { 250_000, common.CoinType_Zeta, "", - 0, + // #nosec G701 always positive + uint(eventIndex), ) return msg.Digest() } diff --git a/x/crosschain/client/integrationtests/inbound_voter_test.go b/x/crosschain/client/integrationtests/inbound_voter_test.go index cd01d95381..ce0a0043e8 100644 --- a/x/crosschain/client/integrationtests/inbound_voter_test.go +++ b/x/crosschain/client/integrationtests/inbound_voter_test.go @@ -203,7 +203,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { }, ballotResult: observerTypes.BallotStatus_BallotInProgress, cctxStatus: crosschaintypes.CctxStatus_PendingOutbound, - falseBallotIdentifier: GetBallotIdentifier("majority wrong votes incorrect ballot finalized / correct ballot still in progress" + "falseVote"), + falseBallotIdentifier: "majority wrong votes incorrect ballot finalized / correct ballot still in progress" + "falseVote", }, { name: "7 votes only just crossed threshold", @@ -223,7 +223,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { cctxStatus: crosschaintypes.CctxStatus_PendingOutbound, }, } - for _, test := range tt { + for i, test := range tt { test := test s.Run(test.name, func() { // Vote the gas price @@ -266,14 +266,14 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { if vote == observerTypes.VoteType_FailureObservation { message = message + "falseVote" } - signedTx := BuildSignedInboundVote(s.T(), val, s.cfg.BondDenom, account, message) + signedTx := BuildSignedInboundVote(s.T(), val, s.cfg.BondDenom, account, message, i) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) // Get the ballot - ballotIdentifier := GetBallotIdentifier(test.name) + ballotIdentifier := GetBallotIdentifier(test.name, i) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdBallotByIdentifier(), []string{ballotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} @@ -293,7 +293,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { // Get the cctx and check its status cctxIdentifier := ballotIdentifier if test.falseBallotIdentifier != "" { - cctxIdentifier = test.falseBallotIdentifier + cctxIdentifier = GetBallotIdentifier(test.falseBallotIdentifier, i) } out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschaincli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} diff --git a/x/crosschain/client/integrationtests/outbound_voter_test.go b/x/crosschain/client/integrationtests/outbound_voter_test.go index cb36954838..d388adc003 100644 --- a/x/crosschain/client/integrationtests/outbound_voter_test.go +++ b/x/crosschain/client/integrationtests/outbound_voter_test.go @@ -115,7 +115,9 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { valueReceived: "7991636132140714751", }, } - for _, test := range tt { + for i, test := range tt { + // Buffer event index so that it does not clash with the inbound voter test + eventIndex := i + 100 test := test s.Run(test.name, func() { broadcaster := s.network.Validators[0] @@ -148,14 +150,14 @@ func (s *IntegrationTestSuite) TestCCTXOutBoundVoter() { var account authtypes.AccountI s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) message := test.name - signedTx := BuildSignedInboundVote(s.T(), val, s.cfg.BondDenom, account, message) + signedTx := BuildSignedInboundVote(s.T(), val, s.cfg.BondDenom, account, message, eventIndex) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } s.Require().NoError(s.network.WaitForNBlocks(2)) // Get the ballot - cctxIdentifier := GetBallotIdentifier(test.name) + cctxIdentifier := GetBallotIdentifier(test.name, eventIndex) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschaincli.CmdShowSend(), []string{cctxIdentifier, "--output", "json"}) cctx := crosschaintypes.QueryGetCctxResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &cctx)) diff --git a/x/crosschain/genesis.go b/x/crosschain/genesis.go index 06ec239962..d152c32bb3 100644 --- a/x/crosschain/genesis.go +++ b/x/crosschain/genesis.go @@ -50,7 +50,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetCctxAndNonceToCctxAndInTxHashToCctx(ctx, *elem) } } - + for _, elem := range genState.FinalizedInbounds { + k.SetFinalizedInbound(ctx, elem) + } } // ExportGenesis returns the crosschain module's exported genesis. @@ -87,6 +89,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { if found { genesis.ZetaAccounting = amount } + genesis.FinalizedInbounds = k.GetAllFinalizedInbound(ctx) return &genesis } diff --git a/x/crosschain/keeper/finalized_inbounds.go b/x/crosschain/keeper/finalized_inbounds.go new file mode 100644 index 0000000000..8bb95ac820 --- /dev/null +++ b/x/crosschain/keeper/finalized_inbounds.go @@ -0,0 +1,34 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func (k Keeper) SetFinalizedInbound(ctx sdk.Context, finalizedInboundIndex string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.FinalizedInboundsKey)) + store.Set(types.KeyPrefix(finalizedInboundIndex), []byte{1}) +} + +func (k Keeper) AddFinalizedInbound(ctx sdk.Context, intxHash string, chainID int64, eventIndex uint64) { + finalizedInboundIndex := types.FinalizedInboundKey(intxHash, chainID, eventIndex) + k.SetFinalizedInbound(ctx, finalizedInboundIndex) +} +func (k Keeper) IsFinalizedInbound(ctx sdk.Context, intxHash string, chainID int64, eventIndex uint64) bool { + finalizedInboundIndex := types.FinalizedInboundKey(intxHash, chainID, eventIndex) + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.FinalizedInboundsKey)) + return store.Has(types.KeyPrefix(finalizedInboundIndex)) +} + +func (k Keeper) GetAllFinalizedInbound(ctx sdk.Context) (list []string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.FinalizedInboundsKey)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + iterator.Value() + list = append(list, string(iterator.Key())) + } + return +} diff --git a/x/crosschain/keeper/finalized_inbounds_test.go b/x/crosschain/keeper/finalized_inbounds_test.go new file mode 100644 index 0000000000..9946024aa8 --- /dev/null +++ b/x/crosschain/keeper/finalized_inbounds_test.go @@ -0,0 +1,82 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_IsFinalizedInbound(t *testing.T) { + t.Run("check true for finalized inbound", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + intxHash := sample.Hash().String() + chainID := sample.Chain(5).ChainId + eventIndex := sample.EventIndex() + k.AddFinalizedInbound(ctx, intxHash, chainID, eventIndex) + require.True(t, k.IsFinalizedInbound(ctx, intxHash, chainID, eventIndex)) + }) + t.Run("check false for non-finalized inbound", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + intxHash := sample.Hash().String() + chainID := sample.Chain(5).ChainId + eventIndex := sample.EventIndex() + require.False(t, k.IsFinalizedInbound(ctx, intxHash, chainID, eventIndex)) + }) + t.Run("check true for finalized inbound list", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + listSize := 1000 + txHashList := make([]string, listSize) + chainIdList := make([]int64, listSize) + eventIndexList := make([]uint64, listSize) + for i := 0; i < listSize; i++ { + txHashList[i] = sample.Hash().String() + chainIdList[i] = sample.Chain(5).ChainId + eventIndexList[i] = sample.EventIndex() + k.AddFinalizedInbound(ctx, txHashList[i], chainIdList[i], eventIndexList[i]) + } + for i := 0; i < listSize; i++ { + require.True(t, k.IsFinalizedInbound(ctx, txHashList[i], chainIdList[i], eventIndexList[i])) + } + }) +} + +func TestKeeper_AddFinalizedInbound(t *testing.T) { + t.Run("check add finalized inbound", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + intxHash := sample.Hash().String() + chainID := sample.Chain(5).ChainId + eventIndex := sample.EventIndex() + k.AddFinalizedInbound(ctx, intxHash, chainID, eventIndex) + require.True(t, k.IsFinalizedInbound(ctx, intxHash, chainID, eventIndex)) + }) +} + +func TestKeeper_GetAllFinalizedInbound(t *testing.T) { + t.Run("check empty list", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + list := k.GetAllFinalizedInbound(ctx) + require.Empty(t, list) + }) + t.Run("check list", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + listSize := 1000 + txHashList := make([]string, listSize) + chainIdList := make([]int64, listSize) + eventIndexList := make([]uint64, listSize) + for i := 0; i < listSize; i++ { + txHashList[i] = sample.Hash().String() + chainIdList[i] = sample.Chain(5).ChainId + eventIndexList[i] = sample.EventIndex() + k.AddFinalizedInbound(ctx, txHashList[i], chainIdList[i], eventIndexList[i]) + } + list := k.GetAllFinalizedInbound(ctx) + require.Equal(t, listSize, len(list)) + for i := 0; i < listSize; i++ { + require.Contains(t, list, types.FinalizedInboundKey(txHashList[i], chainIdList[i], eventIndexList[i])) + } + require.NotContains(t, list, types.FinalizedInboundKey(sample.Hash().String(), sample.Chain(5).ChainId, sample.EventIndex())) + }) +} diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx.go b/x/crosschain/keeper/msg_server_vote_inbound_tx.go index 50954d1a15..57c3e54041 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -90,6 +91,10 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg return nil, err } if isNew { + // Check if the inbound has already been processed. + if k.IsFinalizedInbound(ctx, msg.InTxHash, msg.SenderChainId, msg.EventIndex) { + return nil, errorsmod.Wrap(types.ErrObservedTxAlreadyFinalized, fmt.Sprintf("InTxHash:%s, SenderChainID:%d, EventIndex:%d", msg.InTxHash, msg.SenderChainId, msg.EventIndex)) + } observerKeeper.EmitEventBallotCreated(ctx, ballot, msg.InTxHash, observationChain.String()) } // AddVoteToBallot adds a vote and sets the ballot @@ -98,8 +103,8 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg return nil, err } - _, isFinalized := k.zetaObserverKeeper.CheckIfFinalizingVote(ctx, ballot) - if !isFinalized { + _, isFinalizedInThisBlock := k.zetaObserverKeeper.CheckIfFinalizingVote(ctx, ballot) + if !isFinalizedInThisBlock { // Return nil here to add vote to ballot and commit state return &types.MsgVoteOnObservedInboundTxResponse{}, nil } @@ -123,8 +128,10 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg cctx := k.CreateNewCCTX(ctx, msg, index, tssPub, types.CctxStatus_PendingInbound, observationChain, receiverChain) defer func() { EmitEventInboundFinalized(ctx, &cctx) + k.AddFinalizedInbound(ctx, msg.InTxHash, msg.SenderChainId, msg.EventIndex) // #nosec G701 always positive cctx.InboundTxParams.InboundTxFinalizedZetaHeight = uint64(ctx.BlockHeight()) + cctx.InboundTxParams.TxFinalizationStatus = types.TxFinalizationStatus_Executed k.RemoveInTxTrackerIfExists(ctx, cctx.InboundTxParams.SenderChainId, cctx.InboundTxParams.InboundTxObservedHash) k.SetCctxAndNonceToCctxAndInTxHashToCctx(ctx, cctx) }() @@ -203,7 +210,6 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg commit() cctx.CctxStatus.ChangeStatus(types.CctxStatus_PendingRevert, revertMessage) return &types.MsgVoteOnObservedInboundTxResponse{}, nil - } // successful HandleEVMDeposit; commit() diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go index ef6c8fe3d1..32a0578ed8 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go @@ -1,66 +1,154 @@ -package keeper +package keeper_test import ( + "encoding/hex" "testing" + //"github.com/zeta-chain/zetacore/common" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" + "github.com/zeta-chain/zetacore/common" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" + observerTypes "github.com/zeta-chain/zetacore/x/observer/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -// FIMXE: make it work -//func Test_CalculateGasFee(t *testing.T) { -// -// tt := []struct { -// name string -// gasPrice sdk.Uint // Sample gasPrice posted by zeta-client based on observed value and posted to core using PostGasPriceVoter -// gasLimit sdk.Uint // Sample gasLimit used in smartContract call -// rate sdk.Uint // Sample Rate obtained from UniSwapV2 / V3 and posted to core using PostGasPriceVoter -// expectedFee sdk.Uint // ExpectedFee in Zeta Tokens -// }{ -// { -// name: "Test Price1", -// gasPrice: sdk.NewUintFromString("20000000000"), -// gasLimit: sdk.NewUintFromString("90000"), -// rate: sdk.NewUintFromString("1000000000000000000"), -// expectedFee: sdk.NewUintFromString("1001800000000000000"), -// }, -// } -// for _, test := range tt { -// test := test -// t.Run(test.name, func(t *testing.T) { -// assert.Equal(t, test.expectedFee, CalculateFee(test.gasPrice, test.gasLimit, test.rate)) -// }) -// } -//} +func setObservers(t *testing.T, k *keeper.Keeper, ctx sdk.Context, zk keepertest.ZetaKeepers) []string { + validators := k.StakingKeeper.GetAllValidators(ctx) -// FIXME: make it work -//func Test_UpdateGasFees(t *testing.T) { -// keeper, ctx := setupKeeper(t) -// cctx := createNCctx(keeper, ctx, 1) -// cctx[0].Amount = sdk.NewUintFromString("8000000000000000000") -// keeper.SetGasPrice(ctx, types.GasPrice{ -// Creator: cctx[0].Creator, -// Index: cctx[0].OutboundTxParams.ReceiverChain, -// Chain: cctx[0].OutboundTxParams.ReceiverChain, -// Signers: []string{cctx[0].Creator}, -// BlockNums: nil, -// Prices: []uint64{20000000000, 20000000000, 20000000000, 20000000000}, -// MedianIndex: 0, -// }) -// //keeper.SetZetaConversionRate(ctx, types.ZetaConversionRate{ -// // Index: cctx[0].OutboundTxParams.ReceiverChain, -// // Chain: cctx[0].OutboundTxParams.ReceiverChain, -// // Signers: []string{cctx[0].Creator}, -// // BlockNums: nil, -// // ZetaConversionRates: []string{"1000000000000000000", "1000000000000000000", "1000000000000000000", "1000000000000000000"}, -// // NativeTokenSymbol: "", -// // MedianIndex: 0, -// //}) -// err := keeper.PayGasInZetaAndUpdateCctx(ctx, cctx[0].OutboundTxParams.ReceiverChain, &cctx[0]) -// assert.NoError(t, err) -// fmt.Println(cctx[0].String()) -//} + validatorAddressListFormatted := make([]string, len(validators)) + for i, validator := range validators { + valAddr, err := sdk.ValAddressFromBech32(validator.OperatorAddress) + assert.NoError(t, err) + addressTmp, err := sdk.AccAddressFromHexUnsafe(hex.EncodeToString(valAddr.Bytes())) + assert.NoError(t, err) + validatorAddressListFormatted[i] = addressTmp.String() + } + + // Add validator to the observer list for voting + zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ + ObserverList: validatorAddressListFormatted, + }) + return validatorAddressListFormatted +} +func TestKeeper_VoteOnObservedInboundTx(t *testing.T) { + t.Run("successfully vote on evm deposit", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + validatorList := setObservers(t, k, ctx, zk) + to, from := int64(1337), int64(101) + chains := zk.ObserverKeeper.GetSupportedChains(ctx) + for _, chain := range chains { + if common.IsEVMChain(chain.ChainId) { + from = chain.ChainId + } + if common.IsZetaChain(chain.ChainId) { + to = chain.ChainId + } + } + msg := sample.InboundVote(0, from, to) + for _, validatorAddr := range validatorList { + msg.Creator = validatorAddr + _, err := msgServer.VoteOnObservedInboundTx( + ctx, + &msg, + ) + assert.NoError(t, err) + } + ballot, _, _ := zk.ObserverKeeper.FindBallot(ctx, msg.Digest(), zk.ObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId), observerTypes.ObservationType_InBoundTx) + assert.Equal(t, ballot.BallotStatus, observerTypes.BallotStatus_BallotFinalized_SuccessObservation) + cctx, found := k.GetCrossChainTx(ctx, msg.Digest()) + assert.True(t, found) + assert.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_OutboundMined) + assert.Equal(t, cctx.InboundTxParams.TxFinalizationStatus, types.TxFinalizationStatus_Executed) + }) + // TODO : https://github.com/zeta-chain/node/issues/1542 +} + +/* +Potential Double Event Submission +*/ +func TestNoDoubleEventProtections(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + + // MsgServer for the crosschain keeper + msgServer := keeper.NewMsgServerImpl(*k) + // Set the chain ids we want to use to be valid + params := observertypes.DefaultParams() + zk.ObserverKeeper.SetParams( + ctx, params, + ) + + // Convert the validator address into a user address. + validators := k.StakingKeeper.GetAllValidators(ctx) + validatorAddress := validators[0].OperatorAddress + valAddr, _ := sdk.ValAddressFromBech32(validatorAddress) + addresstmp, _ := sdk.AccAddressFromHexUnsafe(hex.EncodeToString(valAddr.Bytes())) + validatorAddr := addresstmp.String() + + // Add validator to the observer list for voting + zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ + ObserverList: []string{validatorAddr}, + }) + + // Vote on the FIRST message. + msg := &types.MsgVoteOnObservedInboundTx{ + Creator: validatorAddr, + Sender: "0x954598965C2aCdA2885B037561526260764095B8", + SenderChainId: 1337, // ETH + Receiver: "0x954598965C2aCdA2885B037561526260764095B8", + ReceiverChain: 101, // zetachain + Amount: sdkmath.NewUintFromString("10000000"), + Message: "", + InBlockHeight: 1, + GasLimit: 1000000000, + InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", + CoinType: 0, // zeta + TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", + Asset: "", + EventIndex: 1, + } + _, err := msgServer.VoteOnObservedInboundTx( + ctx, + msg, + ) + assert.NoError(t, err) + + // Check that the vote passed + ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) + assert.True(t, found) + assert.Equal(t, ballot.BallotStatus, observerTypes.BallotStatus_BallotFinalized_SuccessObservation) + //Perform the SAME event. Except, this time, we resubmit the event. + msg2 := &types.MsgVoteOnObservedInboundTx{ + Creator: validatorAddr, + Sender: "0x954598965C2aCdA2885B037561526260764095B8", + SenderChainId: 1337, + Receiver: "0x954598965C2aCdA2885B037561526260764095B8", + ReceiverChain: 101, + Amount: sdkmath.NewUintFromString("10000000"), + Message: "", + InBlockHeight: 1, + GasLimit: 1000000001, // <---- Change here + InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b", + CoinType: 0, + TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8", + Asset: "", + EventIndex: 1, + } + + _, err = msgServer.VoteOnObservedInboundTx( + ctx, + msg2, + ) + assert.ErrorIs(t, err, types.ErrObservedTxAlreadyFinalized) + _, found = zk.ObserverKeeper.GetBallot(ctx, msg2.Digest()) + assert.False(t, found) +} func TestStatus_StatusTransition(t *testing.T) { tt := []struct { Name string @@ -95,7 +183,6 @@ func TestStatus_StatusTransition(t *testing.T) { IsErr: false, }, } - _, _ = setupKeeper(t) for _, test := range tt { test := test t.Run(test.Name, func(t *testing.T) { diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 274bbdc695..17319d1f8a 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -211,6 +211,7 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms if err != nil { // do not commit tmpCtx cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()) + cctx.GetCurrentOutTxParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed ctx.Logger().Error(err.Error()) // #nosec G701 always in range k.GetObserverKeeper().RemoveFromPendingNonces(ctx, tss.TssPubkey, msg.OutTxChain, int64(msg.OutTxTssNonce)) @@ -221,6 +222,7 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms commit() // Set the ballot index to the finalized ballot cctx.GetCurrentOutTxParam().OutboundTxBallotIndex = ballotIndex + cctx.GetCurrentOutTxParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed // #nosec G701 always in range k.GetObserverKeeper().RemoveFromPendingNonces(ctx, tss.TssPubkey, msg.OutTxChain, int64(msg.OutTxTssNonce)) k.RemoveOutTxTracker(ctx, msg.OutTxChain, msg.OutTxTssNonce) diff --git a/x/crosschain/types/cross_chain_tx.pb.go b/x/crosschain/types/cross_chain_tx.pb.go index fbcfff0e36..f74b500a81 100644 --- a/x/crosschain/types/cross_chain_tx.pb.go +++ b/x/crosschain/types/cross_chain_tx.pb.go @@ -63,6 +63,34 @@ func (CctxStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor_af3a0ad055343c21, []int{0} } +type TxFinalizationStatus int32 + +const ( + TxFinalizationStatus_NotFinalized TxFinalizationStatus = 0 + TxFinalizationStatus_Finalized TxFinalizationStatus = 1 + TxFinalizationStatus_Executed TxFinalizationStatus = 2 +) + +var TxFinalizationStatus_name = map[int32]string{ + 0: "NotFinalized", + 1: "Finalized", + 2: "Executed", +} + +var TxFinalizationStatus_value = map[string]int32{ + "NotFinalized": 0, + "Finalized": 1, + "Executed": 2, +} + +func (x TxFinalizationStatus) String() string { + return proto.EnumName(TxFinalizationStatus_name, int32(x)) +} + +func (TxFinalizationStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_af3a0ad055343c21, []int{1} +} + type InboundTxParams struct { Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` SenderChainId int64 `protobuf:"varint,2,opt,name=sender_chain_id,json=senderChainId,proto3" json:"sender_chain_id,omitempty"` @@ -74,6 +102,7 @@ type InboundTxParams struct { InboundTxObservedExternalHeight uint64 `protobuf:"varint,8,opt,name=inbound_tx_observed_external_height,json=inboundTxObservedExternalHeight,proto3" json:"inbound_tx_observed_external_height,omitempty"` InboundTxBallotIndex string `protobuf:"bytes,9,opt,name=inbound_tx_ballot_index,json=inboundTxBallotIndex,proto3" json:"inbound_tx_ballot_index,omitempty"` InboundTxFinalizedZetaHeight uint64 `protobuf:"varint,10,opt,name=inbound_tx_finalized_zeta_height,json=inboundTxFinalizedZetaHeight,proto3" json:"inbound_tx_finalized_zeta_height,omitempty"` + TxFinalizationStatus TxFinalizationStatus `protobuf:"varint,11,opt,name=tx_finalization_status,json=txFinalizationStatus,proto3,enum=zetachain.zetacore.crosschain.TxFinalizationStatus" json:"tx_finalization_status,omitempty"` } func (m *InboundTxParams) Reset() { *m = InboundTxParams{} } @@ -172,6 +201,13 @@ func (m *InboundTxParams) GetInboundTxFinalizedZetaHeight() uint64 { return 0 } +func (m *InboundTxParams) GetTxFinalizationStatus() TxFinalizationStatus { + if m != nil { + return m.TxFinalizationStatus + } + return TxFinalizationStatus_NotFinalized +} + type ZetaAccounting struct { // aborted_zeta_amount stores the total aborted amount for cctx of coin-type ZETA AbortedZetaAmount github_com_cosmos_cosmos_sdk_types.Uint `protobuf:"bytes,1,opt,name=aborted_zeta_amount,json=abortedZetaAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Uint" json:"aborted_zeta_amount"` @@ -227,6 +263,7 @@ type OutboundTxParams struct { OutboundTxEffectiveGasPrice github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,21,opt,name=outbound_tx_effective_gas_price,json=outboundTxEffectiveGasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"outbound_tx_effective_gas_price"` OutboundTxEffectiveGasLimit uint64 `protobuf:"varint,22,opt,name=outbound_tx_effective_gas_limit,json=outboundTxEffectiveGasLimit,proto3" json:"outbound_tx_effective_gas_limit,omitempty"` TssPubkey string `protobuf:"bytes,11,opt,name=tss_pubkey,json=tssPubkey,proto3" json:"tss_pubkey,omitempty"` + TxFinalizationStatus TxFinalizationStatus `protobuf:"varint,12,opt,name=tx_finalization_status,json=txFinalizationStatus,proto3,enum=zetachain.zetacore.crosschain.TxFinalizationStatus" json:"tx_finalization_status,omitempty"` } func (m *OutboundTxParams) Reset() { *m = OutboundTxParams{} } @@ -346,6 +383,13 @@ func (m *OutboundTxParams) GetTssPubkey() string { return "" } +func (m *OutboundTxParams) GetTxFinalizationStatus() TxFinalizationStatus { + if m != nil { + return m.TxFinalizationStatus + } + return TxFinalizationStatus_NotFinalized +} + type Status struct { Status CctxStatus `protobuf:"varint,1,opt,name=status,proto3,enum=zetachain.zetacore.crosschain.CctxStatus" json:"status,omitempty"` StatusMessage string `protobuf:"bytes,2,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"` @@ -493,6 +537,7 @@ func (m *CrossChainTx) GetOutboundTxParams() []*OutboundTxParams { func init() { proto.RegisterEnum("zetachain.zetacore.crosschain.CctxStatus", CctxStatus_name, CctxStatus_value) + proto.RegisterEnum("zetachain.zetacore.crosschain.TxFinalizationStatus", TxFinalizationStatus_name, TxFinalizationStatus_value) proto.RegisterType((*InboundTxParams)(nil), "zetachain.zetacore.crosschain.InboundTxParams") proto.RegisterType((*ZetaAccounting)(nil), "zetachain.zetacore.crosschain.ZetaAccounting") proto.RegisterType((*OutboundTxParams)(nil), "zetachain.zetacore.crosschain.OutboundTxParams") @@ -503,72 +548,76 @@ func init() { func init() { proto.RegisterFile("crosschain/cross_chain_tx.proto", fileDescriptor_af3a0ad055343c21) } var fileDescriptor_af3a0ad055343c21 = []byte{ - // 1037 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcf, 0x6e, 0x1b, 0xb7, - 0x13, 0xf6, 0xfe, 0x24, 0xcb, 0xd2, 0x28, 0x96, 0xd6, 0xb4, 0x9c, 0xdf, 0xc2, 0x69, 0x24, 0x41, - 0x6d, 0x12, 0xa5, 0x80, 0x25, 0xd8, 0x45, 0x11, 0xa0, 0x37, 0xdb, 0x8d, 0x13, 0xa3, 0x49, 0x6c, - 0x6c, 0xed, 0x8b, 0x81, 0x62, 0x4b, 0xed, 0x8e, 0x25, 0x22, 0xd2, 0x52, 0x5d, 0x52, 0x86, 0x1c, - 0xf4, 0xd4, 0x27, 0xe8, 0x43, 0xb4, 0x40, 0xfb, 0x26, 0x39, 0xf4, 0x90, 0x63, 0xd1, 0x83, 0x51, - 0xd8, 0x6f, 0xd0, 0x27, 0x28, 0x48, 0xee, 0x4a, 0x2b, 0xd5, 0x8e, 0xfb, 0xe7, 0xb4, 0xc3, 0x21, - 0xbf, 0x8f, 0x33, 0xc3, 0x6f, 0xc8, 0x85, 0x9a, 0x1f, 0x71, 0x21, 0xfc, 0x1e, 0x65, 0x61, 0x5b, - 0x9b, 0x9e, 0xb6, 0x3d, 0x39, 0x6e, 0x0d, 0x23, 0x2e, 0x39, 0xb9, 0xff, 0x06, 0x25, 0xd5, 0xbe, - 0x96, 0xb6, 0x78, 0x84, 0xad, 0x29, 0x66, 0x7d, 0xd5, 0xe7, 0x83, 0x01, 0x0f, 0xdb, 0xe6, 0x63, - 0x30, 0xeb, 0x95, 0x2e, 0xef, 0x72, 0x6d, 0xb6, 0x95, 0x65, 0xbc, 0x8d, 0xef, 0xb2, 0x50, 0xde, - 0x0f, 0x3b, 0x7c, 0x14, 0x06, 0x47, 0xe3, 0x43, 0x1a, 0xd1, 0x81, 0x20, 0x77, 0x21, 0x27, 0x30, - 0x0c, 0x30, 0x72, 0xac, 0xba, 0xd5, 0x2c, 0xb8, 0xf1, 0x88, 0x3c, 0x84, 0xb2, 0xb1, 0xe2, 0x70, - 0x58, 0xe0, 0xfc, 0xaf, 0x6e, 0x35, 0x33, 0xee, 0xb2, 0x71, 0xef, 0x2a, 0xef, 0x7e, 0x40, 0xee, - 0x41, 0x41, 0x8e, 0x3d, 0x1e, 0xb1, 0x2e, 0x0b, 0x9d, 0x8c, 0xa6, 0xc8, 0xcb, 0xf1, 0x81, 0x1e, - 0x93, 0x0d, 0x28, 0xf8, 0x5c, 0xe5, 0x72, 0x3e, 0x44, 0x27, 0x5b, 0xb7, 0x9a, 0xa5, 0x2d, 0xbb, - 0x15, 0x07, 0xba, 0xcb, 0x59, 0x78, 0x74, 0x3e, 0x44, 0x37, 0xef, 0xc7, 0x16, 0xa9, 0xc0, 0x22, - 0x15, 0x02, 0xa5, 0xb3, 0xa8, 0x79, 0xcc, 0x80, 0x3c, 0x83, 0x1c, 0x1d, 0xf0, 0x51, 0x28, 0x9d, - 0x9c, 0x72, 0xef, 0xb4, 0xdf, 0x5e, 0xd4, 0x16, 0x7e, 0xbb, 0xa8, 0x3d, 0xea, 0x32, 0xd9, 0x1b, - 0x75, 0x14, 0x5f, 0xdb, 0xe7, 0x62, 0xc0, 0x45, 0xfc, 0xd9, 0x10, 0xc1, 0xeb, 0xb6, 0xda, 0x52, - 0xb4, 0x8e, 0x59, 0x28, 0xdd, 0x18, 0x4e, 0x9e, 0x80, 0xc3, 0x4c, 0xf6, 0x9e, 0x0a, 0xb9, 0x23, - 0x30, 0x3a, 0xc3, 0xc0, 0xeb, 0x51, 0xd1, 0x73, 0x96, 0xf4, 0x8e, 0x6b, 0x2c, 0xa9, 0xce, 0x41, - 0x3c, 0xfb, 0x9c, 0x8a, 0x1e, 0x79, 0x01, 0x1f, 0x5e, 0x07, 0xc4, 0xb1, 0xc4, 0x28, 0xa4, 0x7d, - 0xaf, 0x87, 0xac, 0xdb, 0x93, 0x4e, 0xbe, 0x6e, 0x35, 0xb3, 0x6e, 0xed, 0x2f, 0x1c, 0x4f, 0xe3, - 0x75, 0xcf, 0xf5, 0x32, 0xf2, 0x29, 0xfc, 0x3f, 0xc5, 0xd6, 0xa1, 0xfd, 0x3e, 0x97, 0x1e, 0x0b, - 0x03, 0x1c, 0x3b, 0x05, 0x1d, 0x45, 0x65, 0xc2, 0xb0, 0xa3, 0x27, 0xf7, 0xd5, 0x1c, 0xd9, 0x83, - 0x7a, 0x0a, 0x76, 0xca, 0x42, 0xda, 0x67, 0x6f, 0x30, 0xf0, 0x94, 0x26, 0x92, 0x08, 0x40, 0x47, - 0xf0, 0xc1, 0x04, 0xbf, 0x97, 0xac, 0x3a, 0x41, 0x49, 0xcd, 0xf6, 0x8d, 0x6f, 0xa0, 0xa4, 0x46, - 0xdb, 0xbe, 0xaf, 0x8a, 0xc2, 0xc2, 0x2e, 0xf1, 0x60, 0x95, 0x76, 0x78, 0x24, 0x13, 0xb2, 0xb8, - 0xda, 0xd6, 0xbf, 0xab, 0xf6, 0x4a, 0xcc, 0xa5, 0x37, 0xd1, 0x4c, 0x8d, 0x9f, 0x73, 0x60, 0x1f, - 0x8c, 0xe4, 0xac, 0xf0, 0xd6, 0x21, 0x1f, 0xa1, 0x8f, 0xec, 0x6c, 0x22, 0xbd, 0xc9, 0x98, 0x3c, - 0x06, 0x3b, 0xb1, 0x8d, 0xfc, 0xf6, 0x13, 0xf5, 0x95, 0x13, 0x7f, 0xa2, 0xbf, 0x19, 0x89, 0x65, - 0x6e, 0x95, 0xd8, 0x54, 0x4c, 0xd9, 0xff, 0x26, 0xa6, 0x4d, 0x58, 0xe3, 0x71, 0x4a, 0xea, 0x3c, - 0xa4, 0x10, 0x5e, 0xc8, 0x43, 0x1f, 0xb5, 0x76, 0xb3, 0x2e, 0xe1, 0x93, 0x7c, 0x8f, 0x84, 0x78, - 0xa5, 0x66, 0xe6, 0x21, 0x5d, 0x2a, 0xbc, 0x3e, 0x1b, 0x30, 0xa3, 0xeb, 0x19, 0xc8, 0x33, 0x2a, - 0x5e, 0xa8, 0x99, 0xeb, 0x20, 0xc3, 0x88, 0xf9, 0x18, 0xeb, 0x75, 0x16, 0x72, 0xa8, 0x66, 0x48, - 0x13, 0xec, 0x34, 0x44, 0xab, 0x3b, 0xaf, 0x57, 0x97, 0xa6, 0xab, 0xb5, 0xac, 0x9f, 0x80, 0x93, - 0x5e, 0x79, 0x8d, 0x12, 0xd7, 0xa6, 0x88, 0xb4, 0x14, 0x5f, 0xc1, 0x47, 0x69, 0xe0, 0x8d, 0x0d, - 0x61, 0xe4, 0x58, 0x9f, 0x92, 0xdc, 0xd0, 0x11, 0x6d, 0xa8, 0xcc, 0x67, 0x39, 0x12, 0x18, 0x38, - 0x15, 0x8d, 0x5f, 0x99, 0x49, 0xf2, 0x58, 0x60, 0x40, 0x24, 0xd4, 0xd2, 0x00, 0x3c, 0x3d, 0x45, - 0x5f, 0xb2, 0x33, 0x4c, 0x15, 0x68, 0x4d, 0x1f, 0x6f, 0x2b, 0x3e, 0xde, 0x87, 0x7f, 0xe3, 0x78, - 0xf7, 0x43, 0xe9, 0xde, 0x9b, 0xee, 0xf5, 0x34, 0x21, 0x9d, 0x54, 0xf6, 0xf3, 0xf7, 0xed, 0x6a, - 0x4e, 0xf2, 0xae, 0x8e, 0xf8, 0x06, 0x16, 0x73, 0xa4, 0xf7, 0x01, 0x94, 0x58, 0x86, 0xa3, 0xce, - 0x6b, 0x3c, 0x77, 0x8a, 0xba, 0xce, 0x05, 0x29, 0xc4, 0xa1, 0x76, 0x34, 0x7e, 0xb4, 0x20, 0xf7, - 0xa5, 0xa4, 0x72, 0x24, 0xc8, 0x36, 0xe4, 0x84, 0xb6, 0x74, 0x7f, 0x94, 0xb6, 0x1e, 0xb7, 0xde, - 0xfb, 0x12, 0xb4, 0x76, 0x7d, 0x39, 0x36, 0x50, 0x37, 0x06, 0x92, 0x07, 0x50, 0x32, 0x96, 0x37, - 0x40, 0x21, 0x68, 0x17, 0x75, 0x1b, 0x15, 0xdc, 0x65, 0xe3, 0x7d, 0x69, 0x9c, 0x64, 0x13, 0x2a, - 0x7d, 0x2a, 0xe4, 0xf1, 0x30, 0xa0, 0x12, 0x3d, 0xc9, 0x06, 0x28, 0x24, 0x1d, 0x0c, 0x75, 0x3f, - 0x65, 0xdc, 0xd5, 0xe9, 0xdc, 0x51, 0x32, 0xd5, 0xf8, 0x25, 0x03, 0x77, 0x76, 0xd5, 0xde, 0xba, - 0x11, 0x8f, 0xc6, 0xc4, 0x81, 0x25, 0x3f, 0x42, 0x2a, 0x79, 0xd2, 0xce, 0xc9, 0x50, 0x5d, 0xeb, - 0x46, 0x54, 0x66, 0x6f, 0x33, 0x20, 0x5f, 0x43, 0x41, 0xdf, 0x36, 0xa7, 0x88, 0xc2, 0x5c, 0xf8, - 0x3b, 0xbb, 0xff, 0xb0, 0x19, 0xff, 0xb8, 0xa8, 0xd9, 0xe7, 0x74, 0xd0, 0xff, 0xac, 0x31, 0x61, - 0x6a, 0xb8, 0x79, 0x65, 0xef, 0x21, 0x0a, 0xf2, 0x08, 0xca, 0x11, 0xf6, 0xe9, 0x39, 0x06, 0x93, - 0xec, 0x73, 0xa6, 0x11, 0x62, 0x77, 0x92, 0xfe, 0x1e, 0x14, 0x7d, 0x5f, 0x8e, 0xbd, 0xb8, 0xda, - 0xaa, 0x5b, 0x8a, 0x5b, 0x0f, 0x6e, 0xa9, 0x76, 0x5c, 0x69, 0xf0, 0x27, 0x55, 0x27, 0x27, 0xb0, - 0x92, 0xba, 0xa2, 0x87, 0xfa, 0x9e, 0xd3, 0x9d, 0x54, 0xdc, 0x6a, 0xdd, 0xc2, 0x36, 0xf7, 0x2c, - 0xbb, 0x65, 0x36, 0xf7, 0x4e, 0x7f, 0x05, 0x24, 0x2d, 0xbe, 0x98, 0x1c, 0xea, 0x99, 0x66, 0x71, - 0xab, 0x7d, 0x0b, 0xf9, 0xfc, 0xdd, 0xeb, 0xda, 0x7c, 0xce, 0xf3, 0xf1, 0xb7, 0x00, 0x53, 0xf9, - 0x10, 0x02, 0xa5, 0x43, 0x0c, 0x03, 0x16, 0x76, 0xe3, 0xb8, 0xec, 0x05, 0xb2, 0x0a, 0xe5, 0xd8, - 0x97, 0xd0, 0xd9, 0x16, 0x59, 0x81, 0xe5, 0x64, 0xf4, 0x92, 0x85, 0x18, 0xd8, 0x19, 0xe5, 0x8a, - 0xd7, 0xb9, 0x78, 0x86, 0x91, 0xb4, 0xb3, 0xe4, 0x0e, 0xe4, 0x8d, 0x8d, 0x81, 0xbd, 0x48, 0x8a, - 0xb0, 0xb4, 0x6d, 0x9e, 0x08, 0x3b, 0xb7, 0x9e, 0xfd, 0xe9, 0x87, 0xaa, 0xb5, 0xf3, 0xc5, 0xdb, - 0xcb, 0xaa, 0xf5, 0xee, 0xb2, 0x6a, 0xfd, 0x7e, 0x59, 0xb5, 0xbe, 0xbf, 0xaa, 0x2e, 0xbc, 0xbb, - 0xaa, 0x2e, 0xfc, 0x7a, 0x55, 0x5d, 0x38, 0xd9, 0x4c, 0x49, 0x41, 0xa5, 0xb6, 0x61, 0x7e, 0x94, - 0x92, 0x2c, 0xdb, 0xe3, 0x76, 0xea, 0xf7, 0x49, 0x2b, 0xa3, 0x93, 0xd3, 0x3f, 0x3b, 0x9f, 0xfc, - 0x19, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x5f, 0xb2, 0x04, 0x59, 0x09, 0x00, 0x00, + // 1100 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcd, 0x6e, 0x1b, 0x37, + 0x10, 0xd6, 0x46, 0x8a, 0x2c, 0x8d, 0x6c, 0x6b, 0x4d, 0xcb, 0xe9, 0xc2, 0x69, 0x24, 0x41, 0x6d, + 0x12, 0x25, 0x80, 0x25, 0xd8, 0x41, 0x11, 0xa0, 0x37, 0xdb, 0xb5, 0x13, 0x23, 0x89, 0x6d, 0x6c, + 0xed, 0x8b, 0x81, 0x62, 0x4b, 0xed, 0xd2, 0x12, 0x11, 0x69, 0xa9, 0x2e, 0x29, 0x43, 0x0e, 0xfa, + 0x10, 0x3d, 0xf4, 0x11, 0x5a, 0xa0, 0x8f, 0x92, 0x43, 0x0f, 0x39, 0x16, 0x3d, 0x18, 0x85, 0x7d, + 0xee, 0xa5, 0x4f, 0x50, 0xf0, 0x67, 0x57, 0x6b, 0xd5, 0x3f, 0xfd, 0x3b, 0xed, 0x70, 0xc8, 0xef, + 0x1b, 0x72, 0xe6, 0x1b, 0x2e, 0xa1, 0xe6, 0x47, 0x8c, 0x73, 0xbf, 0x87, 0x69, 0xd8, 0x56, 0xa6, + 0xa7, 0x6c, 0x4f, 0x8c, 0x5b, 0xc3, 0x88, 0x09, 0x86, 0x1e, 0xbc, 0x23, 0x02, 0x2b, 0x5f, 0x4b, + 0x59, 0x2c, 0x22, 0xad, 0x09, 0x66, 0x79, 0xd1, 0x67, 0x83, 0x01, 0x0b, 0xdb, 0xfa, 0xa3, 0x31, + 0xcb, 0x95, 0x2e, 0xeb, 0x32, 0x65, 0xb6, 0xa5, 0xa5, 0xbd, 0x8d, 0xdf, 0x73, 0x50, 0xde, 0x09, + 0x3b, 0x6c, 0x14, 0x06, 0x07, 0xe3, 0x7d, 0x1c, 0xe1, 0x01, 0x47, 0xf7, 0x20, 0xcf, 0x49, 0x18, + 0x90, 0xc8, 0xb1, 0xea, 0x56, 0xb3, 0xe8, 0x9a, 0x11, 0x7a, 0x04, 0x65, 0x6d, 0x99, 0xed, 0xd0, + 0xc0, 0xb9, 0x53, 0xb7, 0x9a, 0x59, 0x77, 0x4e, 0xbb, 0x37, 0xa5, 0x77, 0x27, 0x40, 0xf7, 0xa1, + 0x28, 0xc6, 0x1e, 0x8b, 0x68, 0x97, 0x86, 0x4e, 0x56, 0x51, 0x14, 0xc4, 0x78, 0x4f, 0x8d, 0xd1, + 0x0a, 0x14, 0x7d, 0x26, 0xcf, 0x72, 0x3a, 0x24, 0x4e, 0xae, 0x6e, 0x35, 0xe7, 0xd7, 0xec, 0x96, + 0xd9, 0xe8, 0x26, 0xa3, 0xe1, 0xc1, 0xe9, 0x90, 0xb8, 0x05, 0xdf, 0x58, 0xa8, 0x02, 0x77, 0x31, + 0xe7, 0x44, 0x38, 0x77, 0x15, 0x8f, 0x1e, 0xa0, 0x17, 0x90, 0xc7, 0x03, 0x36, 0x0a, 0x85, 0x93, + 0x97, 0xee, 0x8d, 0xf6, 0xfb, 0xb3, 0x5a, 0xe6, 0xd7, 0xb3, 0xda, 0xe3, 0x2e, 0x15, 0xbd, 0x51, + 0x47, 0xf2, 0xb5, 0x7d, 0xc6, 0x07, 0x8c, 0x9b, 0xcf, 0x0a, 0x0f, 0xde, 0xb6, 0x65, 0x48, 0xde, + 0x3a, 0xa4, 0xa1, 0x70, 0x0d, 0x1c, 0x3d, 0x07, 0x87, 0xea, 0xd3, 0x7b, 0x72, 0xcb, 0x1d, 0x4e, + 0xa2, 0x13, 0x12, 0x78, 0x3d, 0xcc, 0x7b, 0xce, 0x8c, 0x8a, 0xb8, 0x44, 0xe3, 0xec, 0xec, 0x99, + 0xd9, 0x97, 0x98, 0xf7, 0xd0, 0x6b, 0xf8, 0xe4, 0x2a, 0x20, 0x19, 0x0b, 0x12, 0x85, 0xb8, 0xef, + 0xf5, 0x08, 0xed, 0xf6, 0x84, 0x53, 0xa8, 0x5b, 0xcd, 0x9c, 0x5b, 0xfb, 0x0b, 0xc7, 0x96, 0x59, + 0xf7, 0x52, 0x2d, 0x43, 0x9f, 0xc1, 0x47, 0x29, 0xb6, 0x0e, 0xee, 0xf7, 0x99, 0xf0, 0x68, 0x18, + 0x90, 0xb1, 0x53, 0x54, 0xbb, 0xa8, 0x24, 0x0c, 0x1b, 0x6a, 0x72, 0x47, 0xce, 0xa1, 0x6d, 0xa8, + 0xa7, 0x60, 0xc7, 0x34, 0xc4, 0x7d, 0xfa, 0x8e, 0x04, 0x9e, 0xd4, 0x44, 0xbc, 0x03, 0x50, 0x3b, + 0xf8, 0x38, 0xc1, 0x6f, 0xc7, 0xab, 0x8e, 0x88, 0xc0, 0x26, 0x3c, 0x85, 0x7b, 0x13, 0x3c, 0x16, + 0x94, 0x85, 0x1e, 0x17, 0x58, 0x8c, 0xb8, 0x53, 0x52, 0x05, 0x7a, 0xd6, 0xba, 0x51, 0x6f, 0xad, + 0x84, 0x55, 0x61, 0xbf, 0x54, 0x50, 0xb7, 0x22, 0xae, 0xf0, 0x36, 0xbe, 0x81, 0x79, 0x19, 0x78, + 0xdd, 0xf7, 0x65, 0xfe, 0x69, 0xd8, 0x45, 0x1e, 0x2c, 0xe2, 0x0e, 0x8b, 0x44, 0xbc, 0x6f, 0x53, + 0x58, 0xeb, 0xdf, 0x15, 0x76, 0xc1, 0x70, 0xa9, 0x20, 0x8a, 0xa9, 0xf1, 0xfd, 0x0c, 0xd8, 0x7b, + 0x23, 0x71, 0x59, 0xe3, 0xcb, 0x50, 0x88, 0x88, 0x4f, 0xe8, 0x49, 0xa2, 0xf2, 0x64, 0x8c, 0x9e, + 0x80, 0x1d, 0xdb, 0x5a, 0xe9, 0x3b, 0xb1, 0xd0, 0xcb, 0xb1, 0x3f, 0x96, 0xfa, 0x25, 0x35, 0x67, + 0x6f, 0x55, 0xf3, 0x44, 0xb7, 0xb9, 0xff, 0xa6, 0xdb, 0x55, 0x58, 0x62, 0xe6, 0x48, 0xb2, 0xf4, + 0x82, 0x73, 0x2f, 0x64, 0xa1, 0x4f, 0x54, 0x9b, 0xe4, 0x5c, 0xc4, 0x92, 0xf3, 0x1e, 0x70, 0xbe, + 0x2b, 0x67, 0xa6, 0x21, 0x5d, 0xcc, 0xbd, 0x3e, 0x1d, 0x50, 0xdd, 0x42, 0x97, 0x20, 0x2f, 0x30, + 0x7f, 0x2d, 0x67, 0xae, 0x82, 0x0c, 0x23, 0xea, 0x13, 0xd3, 0x1a, 0x97, 0x21, 0xfb, 0x72, 0x06, + 0x35, 0xc1, 0x4e, 0x43, 0x54, 0x23, 0x15, 0xd4, 0xea, 0xf9, 0xc9, 0x6a, 0xd5, 0x41, 0xcf, 0xc1, + 0x49, 0xaf, 0xbc, 0x42, 0xf4, 0x4b, 0x13, 0x44, 0x5a, 0xf5, 0xbb, 0xf0, 0x69, 0x1a, 0x78, 0x6d, + 0xef, 0x69, 0xe5, 0xd7, 0x27, 0x24, 0xd7, 0x34, 0x5f, 0x1b, 0x2a, 0xd3, 0xa7, 0x1c, 0x71, 0x12, + 0x38, 0x15, 0x85, 0x5f, 0xb8, 0x74, 0xc8, 0x43, 0x4e, 0x02, 0x24, 0xa0, 0x96, 0x06, 0x90, 0xe3, + 0x63, 0xe2, 0x0b, 0x7a, 0x42, 0x52, 0x09, 0x5a, 0x52, 0xe5, 0x6d, 0x99, 0xf2, 0x3e, 0xfa, 0x1b, + 0xe5, 0xdd, 0x09, 0x85, 0x7b, 0x7f, 0x12, 0x6b, 0x2b, 0x26, 0x4d, 0x32, 0xfb, 0xc5, 0x4d, 0x51, + 0x75, 0x25, 0xef, 0xa9, 0x1d, 0x5f, 0xc3, 0xa2, 0x4b, 0xfa, 0x00, 0x40, 0x8a, 0x65, 0x38, 0xea, + 0xbc, 0x25, 0xa7, 0xaa, 0xbd, 0x8b, 0x6e, 0x51, 0x70, 0xbe, 0xaf, 0x1c, 0x37, 0xdc, 0x04, 0xb3, + 0xff, 0xf7, 0x4d, 0xf0, 0xa3, 0x05, 0x79, 0x6d, 0xa2, 0x75, 0xc8, 0x9b, 0x28, 0x96, 0x8a, 0xf2, + 0xe4, 0x96, 0x28, 0x9b, 0xbe, 0x18, 0x1b, 0x6e, 0x03, 0x44, 0x0f, 0x61, 0x5e, 0x5b, 0xde, 0x80, + 0x70, 0x8e, 0xbb, 0x44, 0x75, 0x6c, 0xd1, 0x9d, 0xd3, 0xde, 0x37, 0xda, 0x89, 0x56, 0xa1, 0xd2, + 0xc7, 0x5c, 0x1c, 0x0e, 0x03, 0x2c, 0x88, 0x27, 0xe8, 0x80, 0x70, 0x81, 0x07, 0x43, 0xd5, 0xba, + 0x59, 0x77, 0x71, 0x32, 0x77, 0x10, 0x4f, 0x35, 0x7e, 0xce, 0xc2, 0xec, 0xa6, 0x8c, 0xad, 0x7a, + 0xfe, 0x60, 0x8c, 0x1c, 0x98, 0xf1, 0x23, 0x82, 0x05, 0x8b, 0x6f, 0x8e, 0x78, 0x28, 0x7f, 0x56, + 0x5a, 0xbf, 0x3a, 0xb6, 0x1e, 0xa0, 0xaf, 0xa1, 0xa8, 0x2e, 0xb6, 0x63, 0x42, 0xb8, 0xfe, 0x8d, + 0x6d, 0x6c, 0xfe, 0xc3, 0xbe, 0xff, 0xe3, 0xac, 0x66, 0x9f, 0xe2, 0x41, 0xff, 0xf3, 0x46, 0xc2, + 0xd4, 0x70, 0x0b, 0xd2, 0xde, 0x26, 0x84, 0xa3, 0xc7, 0x50, 0x8e, 0x48, 0x1f, 0x9f, 0x92, 0x20, + 0x39, 0x7d, 0x5e, 0xf7, 0x9c, 0x71, 0xc7, 0xc7, 0xdf, 0x86, 0x92, 0xef, 0x8b, 0x71, 0x5c, 0x53, + 0xd9, 0x98, 0xa5, 0xb5, 0x87, 0xb7, 0x64, 0xdb, 0x64, 0x1a, 0xfc, 0x24, 0xeb, 0xe8, 0x08, 0x16, + 0x52, 0x3f, 0x9e, 0xa1, 0xba, 0x52, 0x55, 0xd3, 0x96, 0xd6, 0x5a, 0xb7, 0xb0, 0x4d, 0x3d, 0x36, + 0xdc, 0x32, 0x9d, 0x7a, 0x7d, 0x7c, 0x05, 0x28, 0xad, 0x73, 0x43, 0x0e, 0xf5, 0x6c, 0xb3, 0xb4, + 0xd6, 0xbe, 0x85, 0x7c, 0xfa, 0x9a, 0x77, 0x6d, 0x36, 0xe5, 0x79, 0xfa, 0x2d, 0xc0, 0x44, 0x3e, + 0x08, 0xc1, 0xfc, 0x3e, 0x09, 0x03, 0x1a, 0x76, 0xcd, 0xbe, 0xec, 0x0c, 0x5a, 0x84, 0xb2, 0xf1, + 0xc5, 0x74, 0xb6, 0x85, 0x16, 0x60, 0x2e, 0x1e, 0xbd, 0xa1, 0x21, 0x09, 0xec, 0xac, 0x74, 0x99, + 0x75, 0x2e, 0x39, 0x21, 0x91, 0xb0, 0x73, 0x68, 0x16, 0x0a, 0xda, 0x26, 0x81, 0x7d, 0x17, 0x95, + 0x60, 0x66, 0x5d, 0xff, 0x8d, 0xec, 0xfc, 0x72, 0xee, 0xa7, 0x1f, 0xaa, 0xd6, 0xd3, 0x57, 0x50, + 0xb9, 0xaa, 0x45, 0x90, 0x0d, 0xb3, 0xbb, 0x4c, 0x24, 0xff, 0x66, 0x3b, 0x83, 0xe6, 0xa0, 0x38, + 0x19, 0x5a, 0x92, 0x79, 0x6b, 0x4c, 0xfc, 0x91, 0x24, 0xbb, 0xa3, 0xc9, 0x36, 0x5e, 0xbd, 0x3f, + 0xaf, 0x5a, 0x1f, 0xce, 0xab, 0xd6, 0x6f, 0xe7, 0x55, 0xeb, 0xbb, 0x8b, 0x6a, 0xe6, 0xc3, 0x45, + 0x35, 0xf3, 0xcb, 0x45, 0x35, 0x73, 0xb4, 0x9a, 0xd2, 0x95, 0xcc, 0xd3, 0x8a, 0x7e, 0x4b, 0xc6, + 0x29, 0x6b, 0x8f, 0xdb, 0xa9, 0x17, 0xa6, 0x92, 0x59, 0x27, 0xaf, 0xde, 0x83, 0xcf, 0xfe, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xd3, 0x52, 0xba, 0xe1, 0x7c, 0x0a, 0x00, 0x00, } func (m *InboundTxParams) Marshal() (dAtA []byte, err error) { @@ -591,6 +640,11 @@ func (m *InboundTxParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TxFinalizationStatus != 0 { + i = encodeVarintCrossChainTx(dAtA, i, uint64(m.TxFinalizationStatus)) + i-- + dAtA[i] = 0x58 + } if m.InboundTxFinalizedZetaHeight != 0 { i = encodeVarintCrossChainTx(dAtA, i, uint64(m.InboundTxFinalizedZetaHeight)) i-- @@ -738,6 +792,11 @@ func (m *OutboundTxParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xa0 } + if m.TxFinalizationStatus != 0 { + i = encodeVarintCrossChainTx(dAtA, i, uint64(m.TxFinalizationStatus)) + i-- + dAtA[i] = 0x60 + } if len(m.TssPubkey) > 0 { i -= len(m.TssPubkey) copy(dAtA[i:], m.TssPubkey) @@ -994,6 +1053,9 @@ func (m *InboundTxParams) Size() (n int) { if m.InboundTxFinalizedZetaHeight != 0 { n += 1 + sovCrossChainTx(uint64(m.InboundTxFinalizedZetaHeight)) } + if m.TxFinalizationStatus != 0 { + n += 1 + sovCrossChainTx(uint64(m.TxFinalizationStatus)) + } return n } @@ -1051,6 +1113,9 @@ func (m *OutboundTxParams) Size() (n int) { if l > 0 { n += 1 + l + sovCrossChainTx(uint64(l)) } + if m.TxFinalizationStatus != 0 { + n += 1 + sovCrossChainTx(uint64(m.TxFinalizationStatus)) + } if m.OutboundTxGasUsed != 0 { n += 2 + sovCrossChainTx(uint64(m.OutboundTxGasUsed)) } @@ -1423,6 +1488,25 @@ func (m *InboundTxParams) Unmarshal(dAtA []byte) error { break } } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxFinalizationStatus", wireType) + } + m.TxFinalizationStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxFinalizationStatus |= TxFinalizationStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipCrossChainTx(dAtA[iNdEx:]) @@ -1846,6 +1930,25 @@ func (m *OutboundTxParams) Unmarshal(dAtA []byte) error { } m.TssPubkey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxFinalizationStatus", wireType) + } + m.TxFinalizationStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrossChainTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxFinalizationStatus |= TxFinalizationStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } case 20: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field OutboundTxGasUsed", wireType) diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 42274e4698..8dc589e878 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -34,12 +34,13 @@ var ( ErrCannotFindCctx = errorsmod.Register(ModuleName, 1134, "cannot find cctx") ErrStatusNotPending = errorsmod.Register(ModuleName, 1135, "Status not pending") - ErrCannotFindGasParams = errorsmod.Register(ModuleName, 1136, "cannot find gas params") - ErrInvalidGasAmount = errorsmod.Register(ModuleName, 1137, "invalid gas amount") - ErrNoLiquidityPool = errorsmod.Register(ModuleName, 1138, "no liquidity pool") - ErrInvalidCoinType = errorsmod.Register(ModuleName, 1139, "invalid coin type") - ErrCannotMigrateTssFunds = errorsmod.Register(ModuleName, 1140, "cannot migrate TSS funds") - ErrTxBodyVerificationFail = errorsmod.Register(ModuleName, 1141, "transaction body verification fail") - ErrReceiverIsEmpty = errorsmod.Register(ModuleName, 1142, "receiver is empty") - ErrUnsupportedStatus = errorsmod.Register(ModuleName, 1143, "unsupported status") + ErrCannotFindGasParams = errorsmod.Register(ModuleName, 1136, "cannot find gas params") + ErrInvalidGasAmount = errorsmod.Register(ModuleName, 1137, "invalid gas amount") + ErrNoLiquidityPool = errorsmod.Register(ModuleName, 1138, "no liquidity pool") + ErrInvalidCoinType = errorsmod.Register(ModuleName, 1139, "invalid coin type") + ErrCannotMigrateTssFunds = errorsmod.Register(ModuleName, 1140, "cannot migrate TSS funds") + ErrTxBodyVerificationFail = errorsmod.Register(ModuleName, 1141, "transaction body verification fail") + ErrReceiverIsEmpty = errorsmod.Register(ModuleName, 1142, "receiver is empty") + ErrUnsupportedStatus = errorsmod.Register(ModuleName, 1143, "unsupported status") + ErrObservedTxAlreadyFinalized = errorsmod.Register(ModuleName, 1144, "observed tx already finalized") ) diff --git a/x/crosschain/types/genesis.pb.go b/x/crosschain/types/genesis.pb.go index 250dc7128d..43a21227fb 100644 --- a/x/crosschain/types/genesis.pb.go +++ b/x/crosschain/types/genesis.pb.go @@ -34,6 +34,7 @@ type GenesisState struct { InTxHashToCctxList []InTxHashToCctx `protobuf:"bytes,9,rep,name=inTxHashToCctxList,proto3" json:"inTxHashToCctxList"` InTxTrackerList []InTxTracker `protobuf:"bytes,11,rep,name=in_tx_tracker_list,json=inTxTrackerList,proto3" json:"in_tx_tracker_list"` ZetaAccounting ZetaAccounting `protobuf:"bytes,12,opt,name=zeta_accounting,json=zetaAccounting,proto3" json:"zeta_accounting"` + FinalizedInbounds []string `protobuf:"bytes,16,rep,name=FinalizedInbounds,proto3" json:"FinalizedInbounds,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -125,6 +126,13 @@ func (m *GenesisState) GetZetaAccounting() ZetaAccounting { return ZetaAccounting{} } +func (m *GenesisState) GetFinalizedInbounds() []string { + if m != nil { + return m.FinalizedInbounds + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "zetachain.zetacore.crosschain.GenesisState") } @@ -132,37 +140,39 @@ func init() { func init() { proto.RegisterFile("crosschain/genesis.proto", fileDescriptor_dd51403692d571f4) } var fileDescriptor_dd51403692d571f4 = []byte{ - // 468 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x51, 0x6b, 0x14, 0x31, - 0x10, 0xc7, 0x6f, 0xd5, 0x56, 0xcd, 0x9d, 0x56, 0xa2, 0xe0, 0x72, 0xe0, 0xb6, 0x54, 0xc4, 0xa2, - 0x74, 0x17, 0xeb, 0x27, 0xb0, 0xf7, 0xd0, 0x4a, 0x0b, 0xd6, 0xf3, 0x9e, 0x8a, 0x25, 0xe6, 0x42, - 0xd8, 0x0d, 0xbd, 0x6e, 0x96, 0xcd, 0x2c, 0xac, 0xfd, 0x14, 0x7e, 0xac, 0x3e, 0xf6, 0x49, 0x7c, - 0x12, 0xb9, 0xfb, 0x22, 0x92, 0xd9, 0x58, 0xb3, 0x5c, 0xe9, 0xf6, 0x6d, 0xc8, 0xcc, 0xff, 0xf7, - 0x9f, 0xcc, 0x24, 0x24, 0x14, 0xa5, 0x36, 0x46, 0x64, 0x5c, 0xe5, 0x49, 0x2a, 0x73, 0x69, 0x94, - 0x89, 0x8b, 0x52, 0x83, 0xa6, 0x2f, 0xce, 0x25, 0x70, 0x4c, 0xc4, 0x18, 0xe9, 0x52, 0xc6, 0xff, - 0x8b, 0x87, 0xeb, 0x9e, 0x10, 0x43, 0x86, 0x31, 0x83, 0xba, 0xd1, 0x0f, 0x87, 0x3e, 0x99, 0x1b, - 0x56, 0x94, 0x4a, 0x48, 0x97, 0x7b, 0xe9, 0xe5, 0x50, 0xc3, 0x32, 0x6e, 0x32, 0x06, 0x9a, 0x09, - 0x71, 0x05, 0x88, 0x96, 0x8a, 0xa0, 0xe4, 0xe2, 0x54, 0x96, 0x2e, 0xbf, 0xe9, 0xe5, 0x67, 0xdc, - 0x00, 0x9b, 0xce, 0xb4, 0x38, 0x65, 0x99, 0x54, 0x69, 0x06, 0xae, 0xc6, 0xef, 0x52, 0x57, 0xb0, - 0x0c, 0x79, 0xee, 0x15, 0x14, 0xbc, 0xe4, 0x67, 0xee, 0xfa, 0xc3, 0x67, 0xa9, 0x4e, 0x35, 0x86, - 0x89, 0x8d, 0x9a, 0xd3, 0xcd, 0x9f, 0x2b, 0x64, 0xb0, 0xd7, 0x8c, 0xe9, 0x0b, 0x70, 0x90, 0x74, - 0x44, 0x56, 0x1b, 0x59, 0x18, 0x6c, 0x04, 0x5b, 0xfd, 0x9d, 0x57, 0xf1, 0x8d, 0x63, 0x8b, 0x8f, - 0xb0, 0x78, 0xf7, 0xde, 0xc5, 0xef, 0xf5, 0xde, 0xd8, 0x49, 0xe9, 0x09, 0x79, 0xa2, 0x2b, 0x98, - 0xd4, 0x93, 0xa6, 0xb5, 0x43, 0x65, 0x20, 0xbc, 0xb3, 0x71, 0x77, 0xab, 0xbf, 0xf3, 0xb6, 0x03, - 0xf7, 0xc9, 0x93, 0x39, 0xe8, 0x12, 0x8a, 0x1e, 0x90, 0x41, 0xca, 0xcd, 0x91, 0x9d, 0x3f, 0xa2, - 0x57, 0x10, 0xfd, 0xba, 0x03, 0xbd, 0xe7, 0x24, 0xe3, 0x96, 0x98, 0x7e, 0x26, 0x8f, 0x46, 0xb6, - 0x68, 0x64, 0x8b, 0x26, 0xb5, 0x09, 0xef, 0xdf, 0xaa, 0x51, 0x5f, 0x33, 0x6e, 0x13, 0xe8, 0x37, - 0xf2, 0xd4, 0xee, 0x6f, 0xd7, 0xae, 0x6f, 0x1f, 0xb7, 0x87, 0x6d, 0x3e, 0x40, 0x70, 0xdc, 0x01, - 0x3e, 0x6c, 0x2b, 0xc7, 0xd7, 0xa1, 0xa8, 0x20, 0xd4, 0x5a, 0xed, 0x73, 0x93, 0x4d, 0xf4, 0x48, - 0x40, 0x8d, 0x06, 0x0f, 0xd1, 0x60, 0xbb, 0xc3, 0xe0, 0x63, 0x4b, 0xe8, 0x86, 0x7c, 0x0d, 0x8e, - 0x9e, 0x58, 0x13, 0xef, 0x85, 0xb1, 0x99, 0x35, 0xe9, 0xa3, 0xc9, 0x9b, 0x5b, 0x98, 0xb4, 0xd7, - 0xb8, 0xa6, 0xf2, 0xf6, 0x16, 0xbf, 0x92, 0x35, 0xab, 0x64, 0x5c, 0x08, 0x5d, 0xe5, 0xa0, 0xf2, - 0x34, 0x1c, 0xe0, 0x93, 0xeb, 0xba, 0xc0, 0xb1, 0x04, 0xfe, 0xe1, 0x4a, 0xe4, 0xf0, 0x8f, 0xcf, - 0xdb, 0xa7, 0x07, 0x17, 0xf3, 0x28, 0xb8, 0x9c, 0x47, 0xc1, 0x9f, 0x79, 0x14, 0xfc, 0x58, 0x44, - 0xbd, 0xcb, 0x45, 0xd4, 0xfb, 0xb5, 0x88, 0x7a, 0xc7, 0xef, 0x52, 0x05, 0x59, 0x35, 0x8d, 0x85, - 0x3e, 0x4b, 0xac, 0x68, 0xbb, 0xf9, 0x2c, 0xff, 0x9c, 0x92, 0x3a, 0xf1, 0xbe, 0x10, 0x7c, 0x2f, - 0xa4, 0x99, 0xae, 0xe2, 0x67, 0x79, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x06, 0xe1, 0xb6, 0x7c, - 0x5d, 0x04, 0x00, 0x00, + // 498 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xd1, 0x6e, 0xd3, 0x3c, + 0x14, 0xc7, 0x9b, 0x6f, 0x1f, 0x85, 0xb9, 0x85, 0x0d, 0x83, 0x44, 0x54, 0x89, 0xac, 0x1a, 0x42, + 0x54, 0xc0, 0x12, 0x31, 0x9e, 0x80, 0x56, 0x62, 0x9b, 0x36, 0x89, 0x11, 0x7a, 0x35, 0x31, 0x19, + 0xd7, 0xb3, 0x12, 0x6b, 0x5d, 0x5c, 0xc5, 0x8e, 0x14, 0x7a, 0xcd, 0x03, 0xf0, 0x58, 0xbb, 0xdc, + 0x25, 0x57, 0x08, 0xb5, 0x2f, 0x82, 0x7c, 0x62, 0x86, 0xa3, 0x4e, 0x64, 0x77, 0x47, 0x3e, 0xe7, + 0xff, 0xfb, 0x1f, 0x9f, 0x63, 0x23, 0x9f, 0xe5, 0x52, 0x29, 0x96, 0x52, 0x91, 0x45, 0x09, 0xcf, + 0xb8, 0x12, 0x2a, 0x9c, 0xe5, 0x52, 0x4b, 0xfc, 0x74, 0xce, 0x35, 0x85, 0x44, 0x08, 0x91, 0xcc, + 0x79, 0xf8, 0xb7, 0xb8, 0xb7, 0xe5, 0x08, 0x21, 0x24, 0x10, 0x13, 0x5d, 0x56, 0xfa, 0x5e, 0xcf, + 0x25, 0x53, 0x45, 0x66, 0xb9, 0x60, 0xdc, 0xe6, 0x9e, 0x39, 0x39, 0xd0, 0x90, 0x94, 0xaa, 0x94, + 0x68, 0x49, 0x18, 0xbb, 0x06, 0x04, 0x2b, 0x45, 0x3a, 0xa7, 0xec, 0x9c, 0xe7, 0x36, 0xbf, 0xed, + 0xe4, 0xa7, 0x54, 0x69, 0x32, 0x99, 0x4a, 0x76, 0x4e, 0x52, 0x2e, 0x92, 0x54, 0xdb, 0x1a, 0xb7, + 0x4b, 0x59, 0xe8, 0x55, 0xc8, 0x13, 0xa7, 0x60, 0x46, 0x73, 0x7a, 0x61, 0xaf, 0xdf, 0x7b, 0x9c, + 0xc8, 0x44, 0x42, 0x18, 0x99, 0xa8, 0x3a, 0xdd, 0xfe, 0xd6, 0x46, 0xdd, 0xbd, 0x6a, 0x4c, 0x9f, + 0x34, 0xd5, 0x1c, 0x8f, 0x50, 0xbb, 0x92, 0xf9, 0x5e, 0xdf, 0x1b, 0x74, 0x76, 0x9f, 0x87, 0xff, + 0x1c, 0x5b, 0x78, 0x0c, 0xc5, 0xc3, 0xff, 0x2f, 0x7f, 0x6e, 0xb5, 0x62, 0x2b, 0xc5, 0xa7, 0x68, + 0x53, 0x16, 0x7a, 0x5c, 0x8e, 0xab, 0xd6, 0x8e, 0x84, 0xd2, 0xfe, 0x7f, 0xfd, 0xb5, 0x41, 0x67, + 0xf7, 0x55, 0x03, 0xee, 0x83, 0x23, 0xb3, 0xd0, 0x15, 0x14, 0x3e, 0x44, 0xdd, 0x84, 0xaa, 0x63, + 0x33, 0x7f, 0x40, 0xdf, 0x01, 0xf4, 0x8b, 0x06, 0xf4, 0x9e, 0x95, 0xc4, 0x35, 0x31, 0xfe, 0x88, + 0xee, 0x8f, 0x4c, 0xd1, 0xc8, 0x14, 0x8d, 0x4b, 0xe5, 0xdf, 0xbd, 0x55, 0xa3, 0xae, 0x26, 0xae, + 0x13, 0xf0, 0x17, 0xf4, 0xc8, 0xec, 0x6f, 0x68, 0xd6, 0xb7, 0x0f, 0xdb, 0x83, 0x36, 0xef, 0x01, + 0x38, 0x6c, 0x00, 0x1f, 0xd5, 0x95, 0xf1, 0x4d, 0x28, 0xcc, 0x10, 0x36, 0x56, 0xfb, 0x54, 0xa5, + 0x63, 0x39, 0x62, 0xba, 0x04, 0x83, 0x75, 0x30, 0xd8, 0x69, 0x30, 0x38, 0xa8, 0x09, 0xed, 0x90, + 0x6f, 0xc0, 0xe1, 0x53, 0x63, 0xe2, 0xbc, 0x30, 0x32, 0x35, 0x26, 0x1d, 0x30, 0x79, 0x79, 0x0b, + 0x93, 0xfa, 0x1a, 0x37, 0x44, 0x56, 0xdf, 0xe2, 0x67, 0xb4, 0x61, 0x94, 0x84, 0x32, 0x26, 0x8b, + 0x4c, 0x8b, 0x2c, 0xf1, 0xbb, 0xf0, 0xe4, 0x9a, 0x2e, 0x70, 0xc2, 0x35, 0x7d, 0x77, 0x2d, 0xb2, + 0xf8, 0x07, 0xf3, 0xda, 0x29, 0x7e, 0x8d, 0x1e, 0xbe, 0x17, 0x19, 0x9d, 0x8a, 0x39, 0x3f, 0x3b, + 0xc8, 0x26, 0xb2, 0xc8, 0xce, 0x94, 0xbf, 0xd9, 0x5f, 0x1b, 0xac, 0xc7, 0xab, 0x89, 0xe1, 0xe1, + 0xe5, 0x22, 0xf0, 0xae, 0x16, 0x81, 0xf7, 0x6b, 0x11, 0x78, 0xdf, 0x97, 0x41, 0xeb, 0x6a, 0x19, + 0xb4, 0x7e, 0x2c, 0x83, 0xd6, 0xc9, 0x9b, 0x44, 0xe8, 0xb4, 0x98, 0x84, 0x4c, 0x5e, 0x44, 0xc6, + 0x62, 0xa7, 0xfa, 0x5a, 0x7f, 0xfa, 0x8a, 0xca, 0xc8, 0xf9, 0x70, 0xfa, 0xeb, 0x8c, 0xab, 0x49, + 0x1b, 0xbe, 0xd6, 0xdb, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x69, 0x4a, 0x62, 0x7d, 0x8b, 0x04, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -185,6 +195,17 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.FinalizedInbounds) > 0 { + for iNdEx := len(m.FinalizedInbounds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.FinalizedInbounds[iNdEx]) + copy(dAtA[i:], m.FinalizedInbounds[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.FinalizedInbounds[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + } { size, err := m.ZetaAccounting.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -349,6 +370,12 @@ func (m *GenesisState) Size() (n int) { } l = m.ZetaAccounting.Size() n += 1 + l + sovGenesis(uint64(l)) + if len(m.FinalizedInbounds) > 0 { + for _, s := range m.FinalizedInbounds { + l = len(s) + n += 2 + l + sovGenesis(uint64(l)) + } + } return n } @@ -657,6 +684,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalizedInbounds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FinalizedInbounds = append(m.FinalizedInbounds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/crosschain/types/keys.go b/x/crosschain/types/keys.go index 7e710562a4..8777d8df0c 100644 --- a/x/crosschain/types/keys.go +++ b/x/crosschain/types/keys.go @@ -36,8 +36,9 @@ func KeyPrefix(p string) []byte { } const ( - SendKey = "Send-value-" - LastBlockHeightKey = "LastBlockHeight-value-" + SendKey = "Send-value-" + LastBlockHeightKey = "LastBlockHeight-value-" + FinalizedInboundsKey = "FinalizedInbounds-value-" GasPriceKey = "GasPrice-value-" @@ -75,6 +76,10 @@ func (m CrossChainTx) LogIdentifierForCCTX() string { } +func FinalizedInboundKey(intxHash string, chainID int64, eventIndex uint64) string { + return fmt.Sprintf("%d-%s-%d", chainID, intxHash, eventIndex) +} + var ( ModuleAddress = authtypes.NewModuleAddress(ModuleName) //ModuleAddressEVM common.EVMAddress diff --git a/x/observer/keeper/chain_nonces.go b/x/observer/keeper/chain_nonces.go index cf386545d0..7a9a6ab53c 100644 --- a/x/observer/keeper/chain_nonces.go +++ b/x/observer/keeper/chain_nonces.go @@ -39,9 +39,7 @@ func (k Keeper) RemoveChainNonces(ctx sdk.Context, index string) { func (k Keeper) GetAllChainNonces(ctx sdk.Context) (list []types.ChainNonces) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ChainNoncesKey)) iterator := sdk.KVStorePrefixIterator(store, []byte{}) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { var val types.ChainNonces k.cdc.MustUnmarshal(iterator.Value(), &val) From abe2d5609b60741e0432f73af70a9f4245fa8a54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:28:19 -0800 Subject: [PATCH 25/67] chore(deps): bump tj-actions/changed-files from 39 to 41 in /.github/workflows (#1564) * chore(deps): bump tj-actions/changed-files in /.github/workflows Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 39 to 41. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v39...v41) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production ... Signed-off-by: dependabot[bot] * Update changelog.md --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Christopher Fuka <97121270+CryptoFewka@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- .github/workflows/sast-linters.yml | 2 +- changelog.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sast-linters.yml b/.github/workflows/sast-linters.yml index 2433577d73..bd8910893f 100644 --- a/.github/workflows/sast-linters.yml +++ b/.github/workflows/sast-linters.yml @@ -88,7 +88,7 @@ jobs: - name: Getting files updated in the PR id: changed-files - uses: tj-actions/changed-files@v39 + uses: tj-actions/changed-files@v41 with: base_sha: ${{ github.event.pull_request.base.sha }} diff --git a/changelog.md b/changelog.md index c80a744c33..b53af3e008 100644 --- a/changelog.md +++ b/changelog.md @@ -66,6 +66,7 @@ * [1499](https://github.com/zeta-chain/node/pull/1499) - Add scripts to localnet to help test gov proposals * [1442](https://github.com/zeta-chain/node/pull/1442) - remove build types in `.goreleaser.yaml` * [1504](https://github.com/zeta-chain/node/pull/1504) - remove `-race` in the `make install` commmand +* [1564](https://github.com/zeta-chain/node/pull/1564) - bump ti-actions/changed-files ### Tests From a599fe5eee71dacc7222b5de70ab7e347531d9f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:54:25 -0800 Subject: [PATCH 26/67] chore(deps): bump golang.org/x/net from 0.10.0 to 0.17.0 (#1566) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.10.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.10.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index b583a97b16..f6c751a6df 100644 --- a/go.mod +++ b/go.mod @@ -300,15 +300,15 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 + golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.2.0 - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.114.0 // indirect diff --git a/go.sum b/go.sum index da78e7283c..b7f61d49e3 100644 --- a/go.sum +++ b/go.sum @@ -3233,8 +3233,8 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3403,8 +3403,8 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -3647,8 +3647,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -3662,8 +3662,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3679,8 +3679,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 4e97767b7c1eda2656f157fab88bd48be2bf0d01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:11:14 -0800 Subject: [PATCH 27/67] chore(deps): bump github.com/dvsekhvalnov/jose2go from 1.5.0 to 1.6.0 (#1568) Bumps [github.com/dvsekhvalnov/jose2go](https://github.com/dvsekhvalnov/jose2go) from 1.5.0 to 1.6.0. - [Commits](https://github.com/dvsekhvalnov/jose2go/compare/v1.5...v1.6.0) --- updated-dependencies: - dependency-name: github.com/dvsekhvalnov/jose2go dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f6c751a6df..15aeca6f75 100644 --- a/go.mod +++ b/go.mod @@ -158,7 +158,7 @@ require ( github.com/dlclark/regexp2 v1.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/edsrzf/mmap-go v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect diff --git a/go.sum b/go.sum index b7f61d49e3..61f01ea783 100644 --- a/go.sum +++ b/go.sum @@ -1172,8 +1172,8 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= +github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= From e1b4d0be146635f492f523884067bed1d3f97a71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:29:47 -0800 Subject: [PATCH 28/67] chore(deps): bump google.golang.org/grpc from 1.55.0 to 1.56.3 (#1565) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.55.0 to 1.56.3. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.55.0...v1.56.3) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 15aeca6f75..e655c64809 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/tendermint/tendermint v0.34.28 github.com/tendermint/tm-db v0.6.7 google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect - google.golang.org/grpc v1.55.0 + google.golang.org/grpc v1.56.3 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c ) @@ -113,7 +113,7 @@ require ( require ( cloud.google.com/go v0.110.0 // indirect - cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/storage v1.28.1 // indirect diff --git a/go.sum b/go.sum index 61f01ea783..ad8e4c8dcb 100644 --- a/go.sum +++ b/go.sum @@ -134,8 +134,8 @@ cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -4139,8 +4139,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 815fa124b9fa27219badff0e5eec9ea4555949fe Mon Sep 17 00:00:00 2001 From: GoodDaisy <90915921+GoodDaisy@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:53:43 +0800 Subject: [PATCH 29/67] fix(common): typos in comments (#1531) Co-authored-by: Lucas Bertrand --- common/bitcoin/proof.go | 2 +- common/headers_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/bitcoin/proof.go b/common/bitcoin/proof.go index 4846b7af32..a6fcb94462 100644 --- a/common/bitcoin/proof.go +++ b/common/bitcoin/proof.go @@ -41,7 +41,7 @@ func (m *Merkle) BuildMerkleProof(txIndex int) ([]byte, uint, error) { path := make([]byte, 0) var siblingIndexes uint - // Find intermediate nodes on the path to the root buttom-up. + // Find intermediate nodes on the path to the root bottom-up. nodeIndex := txIndex nodesOnLevel := N / 2 for nodesOnLevel > 1 { diff --git a/common/headers_test.go b/common/headers_test.go index 218d4a67fb..2a0ed6bb74 100644 --- a/common/headers_test.go +++ b/common/headers_test.go @@ -174,7 +174,7 @@ func unmarshalHeader(t *testing.T, headerBytes []byte) *wire.BlockHeader { func validateTrueBitcoinHeader(t *testing.T, header *wire.BlockHeader, headerBytes []byte) { blockHash := header.BlockHash() - // Ture Bitcoin header should pass validation + // True Bitcoin header should pass validation err := common.ValidateBitcoinHeader(headerBytes, blockHash[:], 18332) require.NoError(t, err) From 329b96b11d19cbc5e370395697f16617c4fc1497 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:22:21 -0800 Subject: [PATCH 30/67] chore(deps): bump golang.org/x/crypto from 0.10.0 to 0.17.0 (#1569) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.10.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.10.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Co-authored-by: lumtis --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e655c64809..942af7d565 100644 --- a/go.mod +++ b/go.mod @@ -300,15 +300,15 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.2.0 - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.9.1 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.114.0 // indirect diff --git a/go.sum b/go.sum index ad8e4c8dcb..6d1e76aba3 100644 --- a/go.sum +++ b/go.sum @@ -3233,8 +3233,8 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3647,8 +3647,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -3662,8 +3662,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3679,8 +3679,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From b3b608d1da78fecdaec8d8266b0d99d94abb99e1 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jan 2024 22:18:10 -0500 Subject: [PATCH 31/67] fix: add chain id to get tss address rpc (#1567) --- changelog.md | 2 + docs/openapi/openapi.swagger.yaml | 6 +- proto/observer/query.proto | 2 +- x/observer/types/query.pb.go | 314 +++++++++++++++--------------- x/observer/types/query.pb.gw.go | 44 +++-- 5 files changed, 194 insertions(+), 174 deletions(-) diff --git a/changelog.md b/changelog.md index b53af3e008..db702f1fba 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ * PendingNonces :Changed from `/zeta-chain/crosschain/pendingNonces/{chain_id}/{address}` to `/zeta-chain/observer/pendingNonces/{chain_id}/{address}` . It returns all the pending nonces for a chain id and address. This returns the current pending nonces for the chain. * ChainNonces : Changed from `/zeta-chain/criosschain/chainNonces/{chain_id}` to`/zeta-chain/observer/chainNonces/{chain_id}` . It returns all the chain nonces for a chain id. This returns the current nonce oof the TSS address for the chain. * ChainNoncesAll :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. +* GetTssAddress : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoing chain id can now now passed as a parameter to fetch the correct tss for required BTC chain.This parameter only affects the BTC tss address in the response. ### Features * [1498](https://github.com/zeta-chain/node/pull/1498) - Add monitoring(grafana, prometheus, ethbalance) for localnet testing @@ -41,6 +42,7 @@ * [1536](https://github.com/zeta-chain/node/pull/1536) - add index to check previously finalized inbounds * [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB +* [1567](https://github.com/zeta-chain/node/pull/1567) - add bitcoin chain id to fetch the tss address rpc endpoint ### Refactoring diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 6c170fc142..2e2b7c54c3 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27817,7 +27817,7 @@ paths: format: int64 tags: - Query - /zeta-chain/observer/get_tss_address: + /zeta-chain/observer/get_tss_address/{bitcoin_chain_id}: get: summary: Queries a list of GetTssAddress items. operationId: Query_GetTssAddress @@ -27832,8 +27832,8 @@ paths: $ref: '#/definitions/googlerpcStatus' parameters: - name: bitcoin_chain_id - in: query - required: false + in: path + required: true type: string format: int64 tags: diff --git a/proto/observer/query.proto b/proto/observer/query.proto index 6fb0fc291d..0ef0914d74 100644 --- a/proto/observer/query.proto +++ b/proto/observer/query.proto @@ -111,7 +111,7 @@ service Query { // Queries a list of GetTssAddress items. rpc GetTssAddress(QueryGetTssAddressRequest) returns (QueryGetTssAddressResponse) { - option (google.api.http).get = "/zeta-chain/observer/get_tss_address"; + option (google.api.http).get = "/zeta-chain/observer/get_tss_address/{bitcoin_chain_id}"; } rpc GetTssAddressByFinalizedHeight(QueryGetTssAddressByFinalizedHeightRequest) returns (QueryGetTssAddressByFinalizedHeightResponse) { diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 752350f029..73d1d320b3 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -2611,163 +2611,163 @@ func init() { func init() { proto.RegisterFile("observer/query.proto", fileDescriptor_dcb801e455adaee4) } var fileDescriptor_dcb801e455adaee4 = []byte{ - // 2488 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcf, 0x6f, 0xdc, 0xc6, - 0x15, 0x36, 0xad, 0x48, 0x96, 0x9e, 0x7e, 0x58, 0x1e, 0xcb, 0xbf, 0x68, 0x5b, 0x96, 0xa9, 0x38, - 0x96, 0x15, 0x7b, 0x19, 0xcb, 0x49, 0xac, 0xd8, 0x56, 0x6c, 0xad, 0x6b, 0x4b, 0x76, 0x52, 0x5b, - 0xd9, 0x55, 0x9b, 0xc2, 0x69, 0xbb, 0xe5, 0xee, 0x8e, 0x76, 0xd9, 0xac, 0xc8, 0x0d, 0x39, 0x52, - 0xb4, 0x51, 0x85, 0x16, 0x3d, 0x06, 0x3d, 0x18, 0x28, 0xd0, 0xde, 0x8a, 0x5c, 0xda, 0x5b, 0x8b, - 0x22, 0x40, 0xd1, 0x02, 0x45, 0x0f, 0x3d, 0x35, 0x87, 0x1e, 0x52, 0x14, 0x28, 0xda, 0x4b, 0x1b, - 0xd8, 0xed, 0xff, 0x51, 0x70, 0xf8, 0x48, 0x0e, 0xb9, 0x5c, 0xee, 0xac, 0xb2, 0x39, 0x69, 0x39, - 0x33, 0xef, 0xcd, 0xf7, 0xbd, 0x79, 0x33, 0xf3, 0x3e, 0x91, 0x30, 0x65, 0x97, 0x5d, 0xea, 0x6c, - 0x53, 0x47, 0xff, 0x60, 0x8b, 0x3a, 0xad, 0x5c, 0xd3, 0xb1, 0x99, 0x4d, 0x4e, 0x7f, 0x44, 0x99, - 0x51, 0xa9, 0x1b, 0xa6, 0x95, 0xe3, 0xbf, 0x6c, 0x87, 0xe6, 0x82, 0x81, 0xea, 0xd1, 0x8a, 0xbd, - 0xb9, 0x69, 0x5b, 0xba, 0xff, 0xc7, 0xb7, 0x50, 0xe7, 0x2b, 0xb6, 0xbb, 0x69, 0xbb, 0x7a, 0xd9, - 0x70, 0xa9, 0xef, 0x4a, 0xdf, 0xbe, 0x5a, 0xa6, 0xcc, 0xb8, 0xaa, 0x37, 0x8d, 0x9a, 0x69, 0x19, - 0xcc, 0x0c, 0xc7, 0x4e, 0xd5, 0xec, 0x9a, 0xcd, 0x7f, 0xea, 0xde, 0x2f, 0x6c, 0x3d, 0x53, 0xb3, - 0xed, 0x5a, 0x83, 0xea, 0x46, 0xd3, 0xd4, 0x0d, 0xcb, 0xb2, 0x19, 0x37, 0x71, 0xb1, 0xf7, 0x58, - 0x88, 0xb3, 0x6c, 0x34, 0x1a, 0x36, 0x0b, 0x5c, 0x45, 0xcd, 0x0d, 0x63, 0x93, 0x62, 0xeb, 0x69, - 0xa1, 0xd5, 0xae, 0xbc, 0x5f, 0xaa, 0x53, 0xa3, 0x4a, 0x9d, 0xb6, 0x4e, 0x4e, 0xb0, 0x64, 0xd9, - 0x56, 0x85, 0x06, 0xd3, 0x9c, 0x8b, 0x3a, 0x1d, 0xdb, 0x75, 0xfd, 0x11, 0x1b, 0x0d, 0xa3, 0xd6, - 0x8e, 0xe3, 0x7d, 0xda, 0xaa, 0x51, 0xab, 0xcd, 0xa9, 0x65, 0x57, 0x69, 0xc9, 0xa8, 0x54, 0xec, - 0x2d, 0x2b, 0x00, 0x79, 0x22, 0xec, 0x0c, 0x7e, 0xb4, 0x39, 0x6b, 0x1a, 0x8e, 0xb1, 0x19, 0xcc, - 0x71, 0x36, 0x6a, 0xa6, 0x56, 0xd5, 0xb4, 0x6a, 0x71, 0x8c, 0x24, 0xec, 0x66, 0x2e, 0xb6, 0x69, - 0x0b, 0xa0, 0xbe, 0xe3, 0x05, 0x7d, 0x85, 0xb2, 0xbb, 0x1e, 0xe6, 0x47, 0xdc, 0xa0, 0x40, 0x3f, - 0xd8, 0xa2, 0x2e, 0x23, 0x53, 0x30, 0x68, 0x5a, 0x55, 0xba, 0x73, 0x52, 0x99, 0x51, 0xe6, 0x46, - 0x0a, 0xfe, 0x83, 0x66, 0xc3, 0xe9, 0x54, 0x1b, 0xb7, 0x69, 0x5b, 0x2e, 0x25, 0x6b, 0x30, 0x2a, - 0x34, 0x73, 0xd3, 0xd1, 0x85, 0xb9, 0x5c, 0x46, 0x66, 0xe4, 0x84, 0xf1, 0xf9, 0x17, 0x3e, 0xfb, - 0xf7, 0xb9, 0x03, 0x05, 0xd1, 0x85, 0x56, 0x45, 0x90, 0xcb, 0x8d, 0x46, 0x0a, 0xc8, 0xfb, 0x00, - 0x51, 0xa6, 0xe0, 0x74, 0x2f, 0xe5, 0xfc, 0xb4, 0xca, 0x79, 0x69, 0x95, 0xf3, 0x33, 0x14, 0xd3, - 0x2a, 0xb7, 0x66, 0xd4, 0x28, 0xda, 0x16, 0x04, 0x4b, 0xed, 0x0f, 0x0a, 0xf2, 0x4a, 0x4e, 0xd3, - 0x89, 0xd7, 0xc0, 0x97, 0xe4, 0x45, 0x56, 0x62, 0xc8, 0x0f, 0x72, 0xe4, 0x17, 0xbb, 0x22, 0xf7, - 0xe1, 0xc4, 0xa0, 0x6f, 0xc0, 0x99, 0x00, 0xf9, 0x9a, 0xbf, 0xf2, 0x5f, 0x4d, 0x88, 0xfe, 0xac, - 0xc0, 0xd9, 0x0e, 0x13, 0x61, 0x90, 0xde, 0x85, 0x89, 0x78, 0xee, 0x61, 0x9c, 0xe6, 0x33, 0xe3, - 0x14, 0xf3, 0x85, 0x91, 0x1a, 0x6f, 0x8a, 0x8d, 0xfd, 0x8b, 0xd5, 0x12, 0xcc, 0x70, 0x0a, 0xf1, - 0x39, 0x5b, 0x7c, 0x5d, 0x82, 0x78, 0x9d, 0x82, 0x61, 0x7f, 0x07, 0x9b, 0x55, 0x1e, 0xad, 0x81, - 0xc2, 0x21, 0xfe, 0xfc, 0xa0, 0xaa, 0xfd, 0x00, 0xce, 0x67, 0x98, 0x67, 0x44, 0x41, 0xe9, 0x43, - 0x14, 0xb4, 0x29, 0x20, 0xc1, 0xd6, 0x5b, 0x2f, 0x16, 0x11, 0xae, 0xf6, 0x18, 0x8e, 0xc6, 0x5a, - 0x11, 0xc5, 0x22, 0x0c, 0xac, 0x17, 0x8b, 0x38, 0xf5, 0x4c, 0xe6, 0xd4, 0xeb, 0xc5, 0x22, 0x4e, - 0xe8, 0x99, 0x68, 0xf7, 0xe0, 0x54, 0xe8, 0xd0, 0x75, 0x97, 0xab, 0x55, 0x87, 0xba, 0x61, 0x32, - 0xcd, 0xc1, 0x64, 0xd9, 0x64, 0x15, 0xdb, 0xb4, 0x4a, 0x61, 0x90, 0x0e, 0xf2, 0x20, 0x4d, 0x60, - 0xfb, 0x5d, 0x8c, 0xd5, 0x9d, 0xe8, 0x70, 0x11, 0xdd, 0x20, 0xbc, 0x49, 0x18, 0xa0, 0xac, 0x8e, - 0x47, 0x8b, 0xf7, 0xd3, 0x6b, 0x29, 0xb3, 0x0a, 0x77, 0x36, 0x52, 0xf0, 0x7e, 0x6a, 0x1f, 0x2b, - 0x30, 0xdf, 0xee, 0x22, 0xdf, 0xba, 0x6f, 0x5a, 0x46, 0xc3, 0xfc, 0x88, 0x56, 0x57, 0xa9, 0x59, - 0xab, 0xb3, 0x00, 0xda, 0x02, 0x1c, 0xdb, 0x08, 0x7a, 0x4a, 0x1e, 0xcb, 0x52, 0x9d, 0xf7, 0xe3, - 0x22, 0x1e, 0x0d, 0x3b, 0x9f, 0x50, 0x66, 0xf8, 0xa6, 0x3d, 0xd0, 0x79, 0x07, 0x5e, 0x96, 0xc2, - 0xd2, 0x03, 0xbf, 0xef, 0xc1, 0x71, 0xee, 0x72, 0xdd, 0x75, 0x57, 0x4d, 0x97, 0xd9, 0x4e, 0xab, - 0xdf, 0x5b, 0xf6, 0x97, 0x0a, 0x9c, 0x68, 0x9b, 0x02, 0x11, 0x2e, 0xc3, 0x30, 0x73, 0xdd, 0x52, - 0xc3, 0x74, 0x19, 0x6e, 0x53, 0xd9, 0x2c, 0x39, 0xc4, 0x5c, 0xf7, 0x6d, 0xd3, 0x65, 0xfd, 0xdb, - 0x96, 0xbf, 0x52, 0xe0, 0x88, 0xbf, 0xb1, 0x1c, 0x7b, 0x9b, 0x76, 0xdf, 0x88, 0xe4, 0x04, 0x1c, - 0x62, 0x3b, 0xa5, 0xba, 0xe1, 0xd6, 0x31, 0xa0, 0x43, 0x6c, 0x67, 0xd5, 0x70, 0xeb, 0x64, 0x16, - 0x06, 0x9b, 0x8e, 0x6d, 0x6f, 0x9c, 0x1c, 0xe0, 0x68, 0xc6, 0x73, 0x58, 0x6f, 0xac, 0x79, 0x8d, - 0x05, 0xbf, 0x8f, 0x9c, 0x05, 0xc0, 0x2b, 0xde, 0x73, 0xf0, 0x02, 0x77, 0x30, 0xc2, 0x5b, 0xb8, - 0x8f, 0x53, 0x30, 0xcc, 0x76, 0x4a, 0xfe, 0xdd, 0x37, 0xe8, 0xcf, 0xcb, 0x76, 0x1e, 0xf0, 0xdb, - 0x6f, 0x1e, 0xb7, 0x20, 0xe2, 0xc4, 0x50, 0x4e, 0xc1, 0xe0, 0xb6, 0xd1, 0x40, 0x94, 0xc3, 0x05, - 0xff, 0x21, 0xdc, 0xae, 0x6b, 0xfc, 0x96, 0x0e, 0xb6, 0xeb, 0xb7, 0x70, 0xbb, 0x06, 0xad, 0xe1, - 0x6a, 0x0c, 0xf9, 0xb7, 0x39, 0xae, 0xf6, 0x6c, 0xf6, 0x61, 0xc1, 0x87, 0xe2, 0x72, 0xa0, 0xa1, - 0x56, 0x87, 0x29, 0xee, 0x79, 0xd5, 0x70, 0xbf, 0x69, 0x33, 0x5a, 0x0d, 0xc2, 0xf8, 0x32, 0x1c, - 0xf1, 0xab, 0x9f, 0x92, 0x59, 0xa5, 0x16, 0x33, 0x37, 0x4c, 0xea, 0x60, 0x62, 0x4e, 0xfa, 0x1d, - 0x0f, 0xc2, 0x76, 0x32, 0x0b, 0xe3, 0xdb, 0x36, 0xa3, 0x4e, 0xc9, 0xf0, 0x33, 0x1c, 0xc3, 0x3b, - 0xc6, 0x1b, 0x31, 0xeb, 0xb5, 0x57, 0xe1, 0x58, 0x62, 0x26, 0x64, 0x71, 0x1a, 0x46, 0xea, 0x86, - 0x5b, 0xf2, 0x06, 0x07, 0xc1, 0x18, 0xae, 0xe3, 0x20, 0xed, 0xeb, 0x30, 0xcd, 0xad, 0xf2, 0x7c, - 0xce, 0x7c, 0x2b, 0x9a, 0x75, 0x3f, 0x48, 0x35, 0x06, 0x23, 0x9e, 0x5f, 0x87, 0x67, 0x62, 0x1b, - 0x6c, 0xa5, 0x1d, 0x36, 0xc9, 0xc3, 0x88, 0xf7, 0x5c, 0x62, 0xad, 0x26, 0xe5, 0xbc, 0x26, 0x16, - 0x2e, 0x64, 0x86, 0xd9, 0xf3, 0xbf, 0xde, 0x6a, 0xd2, 0xc2, 0xf0, 0x36, 0xfe, 0xd2, 0x7e, 0x7f, - 0x10, 0xce, 0x75, 0x64, 0x81, 0x51, 0xe8, 0x29, 0xe0, 0x6f, 0xc2, 0x10, 0x07, 0xe9, 0x45, 0x7a, - 0x80, 0x6f, 0xf3, 0x6e, 0x88, 0x38, 0xe3, 0x02, 0x5a, 0x91, 0x77, 0x61, 0xd2, 0xef, 0xe5, 0x3b, - 0xc9, 0xe7, 0x36, 0xc0, 0xb9, 0x5d, 0xce, 0xf4, 0xf4, 0x38, 0x32, 0xe2, 0x14, 0x0f, 0xdb, 0xf1, - 0x06, 0xf2, 0x08, 0xc6, 0x91, 0x85, 0xcb, 0x0c, 0xb6, 0xe5, 0xf2, 0x7d, 0x32, 0xb1, 0x70, 0x29, - 0xd3, 0xab, 0x1f, 0x95, 0x22, 0x37, 0x28, 0x8c, 0x95, 0x85, 0x27, 0x8d, 0xc0, 0x24, 0x0f, 0xdc, - 0x63, 0x1c, 0x5b, 0xa4, 0x4c, 0x5b, 0x84, 0x93, 0xc9, 0xb6, 0x30, 0x8a, 0x67, 0x60, 0x24, 0x70, - 0xeb, 0xd7, 0x11, 0x23, 0x85, 0xa8, 0x41, 0x3b, 0x8e, 0xc9, 0x5e, 0xdc, 0x6a, 0x36, 0x6d, 0x87, - 0xd1, 0x2a, 0x3f, 0xa7, 0x5d, 0xed, 0x1e, 0x16, 0x43, 0x89, 0xf6, 0xd0, 0xeb, 0x05, 0x18, 0xe2, - 0xd8, 0x83, 0xd2, 0x24, 0x3c, 0x20, 0xfc, 0x3b, 0x1c, 0x3b, 0xb5, 0xdb, 0xa0, 0xc5, 0xaa, 0x5c, - 0x7f, 0xc3, 0xdd, 0xb7, 0x1d, 0xd9, 0x4a, 0xc1, 0x81, 0xd9, 0x4c, 0x07, 0x08, 0xe7, 0x2d, 0x18, - 0xf3, 0x3d, 0xc4, 0x36, 0xbf, 0x44, 0x5d, 0x89, 0xc7, 0xc7, 0x68, 0x25, 0x7a, 0xd0, 0xce, 0x24, - 0xca, 0xf9, 0xf8, 0xc1, 0x63, 0x25, 0x0a, 0xf7, 0xc4, 0x01, 0xf4, 0x38, 0x15, 0xc9, 0x65, 0x59, - 0x24, 0x3c, 0x27, 0x63, 0x68, 0x04, 0x71, 0xf1, 0xc8, 0xae, 0xd2, 0x65, 0x5f, 0xdc, 0x64, 0x8b, - 0x8b, 0xef, 0x47, 0x18, 0x63, 0x36, 0x51, 0xb4, 0x44, 0xa1, 0x24, 0x15, 0x2d, 0xd1, 0xcf, 0xa8, - 0x15, 0x3d, 0x88, 0xba, 0x22, 0x05, 0x5f, 0xbf, 0x6e, 0xe0, 0x4f, 0x05, 0x5d, 0x91, 0x46, 0xe9, - 0x21, 0x8c, 0x0a, 0xcd, 0x52, 0xba, 0x22, 0xc6, 0x48, 0x78, 0xe8, 0xdf, 0x75, 0x3c, 0x83, 0x27, - 0xb5, 0x97, 0x2a, 0xa1, 0xa0, 0xbd, 0xef, 0xe9, 0xd9, 0x20, 0x99, 0x7e, 0xa4, 0xe0, 0x31, 0x98, - 0x36, 0x04, 0xa9, 0x7d, 0x07, 0x26, 0x93, 0x72, 0x58, 0x2e, 0xab, 0xe2, 0xfe, 0xf0, 0x96, 0x3b, - 0x5c, 0x89, 0x37, 0x6b, 0x27, 0xf0, 0x12, 0x5a, 0xa1, 0xec, 0x2d, 0x2e, 0xaa, 0x03, 0x6c, 0xdf, - 0xc0, 0xb2, 0x4a, 0xe8, 0x40, 0x44, 0x37, 0x61, 0xc8, 0xd7, 0xdf, 0x52, 0x97, 0x2c, 0x1a, 0xa3, - 0x89, 0x76, 0x0e, 0xd5, 0x4f, 0xb1, 0x6e, 0x7f, 0x18, 0x9c, 0x57, 0x77, 0x85, 0x94, 0xf1, 0x62, - 0x32, 0xdd, 0x69, 0x04, 0x02, 0xf8, 0x2e, 0x1c, 0x6d, 0x18, 0x2e, 0x2b, 0x05, 0x73, 0x94, 0xc4, - 0x3c, 0xce, 0x65, 0xa2, 0x79, 0xdb, 0x70, 0x59, 0xdc, 0xe9, 0x91, 0x46, 0xb2, 0x49, 0x7b, 0x88, - 0x18, 0xf3, 0x0d, 0x63, 0x93, 0xa6, 0xdd, 0xb0, 0x97, 0x60, 0x92, 0xff, 0xcb, 0xa3, 0xfd, 0x66, - 0x3a, 0xcc, 0xdb, 0x85, 0xfb, 0xb5, 0x12, 0x5c, 0xd7, 0xed, 0xbe, 0xc2, 0x9a, 0x05, 0xd0, 0x99, - 0xb5, 0x61, 0x23, 0x09, 0x2d, 0xfb, 0x7a, 0xf0, 0x86, 0x7b, 0xa5, 0x96, 0x37, 0x95, 0xb5, 0x61, - 0x6b, 0x34, 0xda, 0x1d, 0x7e, 0x1f, 0xad, 0xd8, 0x4e, 0xb5, 0xef, 0xd2, 0xf5, 0xb7, 0x4a, 0xa4, - 0x91, 0xe3, 0xf3, 0x20, 0x95, 0x95, 0x04, 0x95, 0x01, 0x39, 0x2a, 0x98, 0x9b, 0x11, 0xa1, 0xfe, - 0xed, 0xc1, 0x22, 0x2a, 0x55, 0x0c, 0x3f, 0x3f, 0x6a, 0x97, 0xad, 0x2a, 0x97, 0x82, 0x12, 0x05, - 0xf2, 0x14, 0x0c, 0x72, 0xf1, 0x89, 0x6a, 0xc6, 0x7f, 0xd0, 0x36, 0x50, 0xbf, 0xa6, 0x3b, 0xed, - 0xb0, 0xac, 0x03, 0xbd, 0x2f, 0xab, 0x70, 0xb6, 0xe6, 0x79, 0x59, 0xcd, 0xff, 0x95, 0xd6, 0xef, - 0x55, 0xfd, 0x44, 0x11, 0xb3, 0x47, 0x98, 0x26, 0x94, 0xc0, 0xe3, 0xe2, 0x7f, 0xf2, 0x82, 0x2b, - 0xff, 0x68, 0x70, 0xe5, 0x8b, 0x36, 0x63, 0xe5, 0xe8, 0xa1, 0x8f, 0xff, 0x6f, 0x58, 0xc6, 0x55, - 0x5c, 0xa1, 0x4c, 0x98, 0x2d, 0xef, 0x55, 0xce, 0xf5, 0x20, 0x1c, 0x71, 0x35, 0xe2, 0x85, 0x63, - 0x4c, 0x50, 0x23, 0xda, 0x7b, 0xb8, 0x66, 0xe9, 0x2e, 0x90, 0xea, 0xeb, 0x30, 0x26, 0x52, 0xc5, - 0xa0, 0xa6, 0x32, 0x1d, 0x15, 0x98, 0x6a, 0xb7, 0xa2, 0x63, 0x5c, 0x18, 0xe3, 0x55, 0x6c, 0x12, - 0x49, 0xa6, 0xfd, 0x30, 0x95, 0x1d, 0x5a, 0x23, 0xb2, 0xf7, 0x80, 0x88, 0xc8, 0x78, 0x31, 0x49, - 0x11, 0xdf, 0x95, 0x2e, 0x59, 0x95, 0x70, 0x39, 0x59, 0x4e, 0xb4, 0x2c, 0x3c, 0x9d, 0x83, 0x41, - 0x8e, 0x80, 0x3c, 0x55, 0x60, 0xc8, 0x2f, 0x3c, 0x88, 0x9e, 0xe9, 0xb5, 0x5d, 0x92, 0xa9, 0xaf, - 0xc8, 0x1b, 0xf8, 0xa4, 0xb4, 0xd9, 0x1f, 0xff, 0xfd, 0xbf, 0x3f, 0x3d, 0x78, 0x96, 0x9c, 0xd6, - 0xbd, 0xf1, 0x57, 0xb8, 0xa9, 0x9e, 0xf8, 0xb7, 0x2c, 0xf9, 0x93, 0x02, 0xc3, 0x81, 0x42, 0x22, - 0x57, 0xbb, 0xcf, 0x91, 0xd0, 0x6d, 0xea, 0x42, 0x2f, 0x26, 0x08, 0xec, 0x21, 0x07, 0xf6, 0x35, - 0x92, 0x4f, 0x05, 0x16, 0x6a, 0x33, 0x7d, 0xb7, 0x4d, 0xa0, 0xec, 0xe9, 0xbb, 0x31, 0x05, 0xb5, - 0x47, 0xfe, 0xa1, 0x00, 0x69, 0x57, 0x39, 0xe4, 0x66, 0x77, 0x58, 0x1d, 0x15, 0x9e, 0x7a, 0x6b, - 0x7f, 0xc6, 0xc8, 0xee, 0x1e, 0x67, 0x77, 0x9b, 0x2c, 0xa5, 0xb2, 0x43, 0x4a, 0xe5, 0x96, 0xc0, - 0x2a, 0x8d, 0x28, 0xf9, 0x85, 0x02, 0xa3, 0x82, 0xe2, 0x20, 0x57, 0xba, 0x83, 0x12, 0x86, 0xab, - 0xaf, 0xf5, 0x34, 0x3c, 0x04, 0x7f, 0x89, 0x83, 0x9f, 0x25, 0xe7, 0x53, 0xc1, 0x87, 0x15, 0x81, - 0x4b, 0x19, 0xf9, 0xb5, 0x02, 0x87, 0x13, 0x02, 0x46, 0x26, 0x81, 0x12, 0x26, 0xea, 0x1b, 0x3d, - 0x9b, 0x84, 0x60, 0x2f, 0x73, 0xb0, 0x2f, 0x91, 0x17, 0x53, 0xc1, 0xba, 0x09, 0x6c, 0xff, 0x51, - 0xe0, 0x78, 0xba, 0xd0, 0x21, 0xb7, 0xbb, 0x63, 0xc8, 0xd4, 0x58, 0xea, 0x9d, 0xfd, 0x3b, 0x40, - 0x2e, 0x79, 0xce, 0xe5, 0x16, 0xb9, 0x91, 0xca, 0xa5, 0x46, 0x59, 0x49, 0x14, 0x3e, 0xa5, 0x0d, - 0xdb, 0xf1, 0x1b, 0xf4, 0xdd, 0xe0, 0xdc, 0xdb, 0x23, 0x9f, 0x2a, 0x30, 0x11, 0x9f, 0x86, 0x5c, - 0xef, 0x15, 0x58, 0xc0, 0x68, 0xb1, 0x77, 0x43, 0x64, 0x72, 0x85, 0x33, 0xb9, 0x48, 0x2e, 0x48, - 0x31, 0xf1, 0x40, 0xc7, 0xf4, 0x81, 0x1c, 0xe2, 0x76, 0x31, 0x24, 0x89, 0x38, 0x45, 0xde, 0x68, - 0xaf, 0x70, 0xc4, 0xf3, 0x64, 0x2e, 0x15, 0xb1, 0x20, 0xc7, 0xf4, 0x5d, 0xae, 0x00, 0xf7, 0xbc, - 0xdc, 0x9f, 0x10, 0x3c, 0x2d, 0x37, 0x1a, 0x32, 0xb8, 0x53, 0x45, 0x9c, 0x0c, 0xee, 0x74, 0x59, - 0xa6, 0xcd, 0x71, 0xdc, 0x1a, 0x99, 0xe9, 0x86, 0x9b, 0xfc, 0x51, 0x81, 0xc3, 0x09, 0xc5, 0x22, - 0x73, 0x44, 0x76, 0x94, 0x56, 0x32, 0x47, 0x64, 0x67, 0xd1, 0xd5, 0x25, 0x45, 0x92, 0x7a, 0x8c, - 0xfc, 0x4c, 0x81, 0x21, 0x5f, 0xe7, 0x90, 0x05, 0xa9, 0x79, 0x63, 0x52, 0x4b, 0xbd, 0xd6, 0x93, - 0x8d, 0xd4, 0xe5, 0xe9, 0xab, 0x2d, 0xf2, 0x17, 0x05, 0x8e, 0xb4, 0xe9, 0x28, 0x72, 0x43, 0xe2, - 0x44, 0xeb, 0x20, 0xcf, 0xd4, 0x9b, 0xfb, 0xb2, 0x45, 0xcc, 0x6f, 0x70, 0xcc, 0xd7, 0xc8, 0x55, - 0x11, 0x73, 0xe0, 0x45, 0x38, 0x18, 0xeb, 0xf6, 0x87, 0x09, 0x71, 0x47, 0xfe, 0xa6, 0xc0, 0x91, - 0x36, 0x0d, 0x25, 0xc3, 0xa4, 0x93, 0x88, 0x93, 0x61, 0xd2, 0x51, 0xb4, 0x69, 0x77, 0x39, 0x93, - 0x25, 0x72, 0x33, 0xfd, 0x0e, 0xe5, 0x85, 0x7f, 0xf2, 0x0a, 0x4d, 0x28, 0xc6, 0x3d, 0xaf, 0xb4, - 0x21, 0x2b, 0x94, 0x25, 0xd4, 0x14, 0x91, 0xdb, 0x6f, 0x29, 0x42, 0x4f, 0xe6, 0xaa, 0xea, 0x20, - 0xdd, 0xb4, 0x05, 0x4e, 0xe8, 0x32, 0x99, 0xef, 0x78, 0x28, 0x1a, 0x8d, 0x46, 0xc9, 0xe7, 0xe0, - 0x20, 0xd0, 0x2f, 0x14, 0x38, 0xc6, 0x9d, 0xb9, 0x09, 0x11, 0x44, 0x96, 0xa4, 0x63, 0x9b, 0xa6, - 0xc8, 0xd4, 0x37, 0xf7, 0x6b, 0x8e, 0x64, 0x56, 0x39, 0x99, 0x3c, 0xb9, 0x93, 0xbd, 0x3a, 0xfe, - 0x16, 0x36, 0xac, 0xaa, 0xff, 0x86, 0x51, 0xb8, 0xa9, 0xf4, 0x5d, 0xde, 0xb2, 0xe7, 0x9d, 0x4b, - 0xe1, 0x12, 0x09, 0xca, 0xe6, 0xba, 0x64, 0xa0, 0x93, 0xa2, 0x4d, 0x5d, 0xec, 0xdd, 0xb0, 0xc7, - 0x05, 0x12, 0x94, 0x1a, 0xf9, 0x97, 0x02, 0x53, 0x69, 0x82, 0x47, 0x66, 0x7d, 0x32, 0xb4, 0x96, - 0xcc, 0xfa, 0x64, 0xe9, 0x2c, 0x89, 0x5a, 0x22, 0x26, 0x76, 0xca, 0x2d, 0x2e, 0xea, 0xbc, 0x2d, - 0x14, 0x08, 0xbc, 0x3d, 0xf2, 0x3f, 0x05, 0xd4, 0x14, 0xc5, 0x84, 0x29, 0x41, 0x6e, 0xf5, 0x0a, - 0x51, 0x54, 0x6b, 0xea, 0xd2, 0x3e, 0xad, 0xa5, 0xf4, 0x43, 0x1b, 0x3f, 0x2e, 0xe6, 0xa2, 0x84, - 0x34, 0xab, 0x62, 0xcd, 0xf4, 0x13, 0x05, 0x06, 0xf9, 0x7b, 0x32, 0x92, 0x93, 0x10, 0x58, 0xc2, - 0x8b, 0x3f, 0x55, 0x97, 0x1e, 0x8f, 0xb0, 0x35, 0x0e, 0xfb, 0x0c, 0x51, 0xd3, 0xf5, 0x18, 0x07, - 0xf1, 0x1b, 0x05, 0xc6, 0x63, 0x2f, 0x6f, 0xc9, 0xeb, 0x52, 0xb1, 0x6a, 0x7b, 0x07, 0xae, 0x5e, - 0xef, 0xd9, 0x4e, 0xaa, 0xaa, 0xf6, 0xa2, 0xcb, 0x5c, 0x37, 0x10, 0x60, 0xe4, 0xe7, 0x07, 0x61, - 0x3a, 0xfb, 0x6d, 0x33, 0x59, 0xe9, 0x11, 0x49, 0xa7, 0x77, 0xe7, 0xea, 0xea, 0x97, 0x77, 0x84, - 0x1c, 0xcb, 0x9c, 0xe3, 0xb7, 0xc9, 0x13, 0x19, 0x8e, 0xa5, 0x3a, 0x7f, 0x29, 0x6d, 0x56, 0x8c, - 0x86, 0xbe, 0x9b, 0xfa, 0xf2, 0x7e, 0x4f, 0xdf, 0x4d, 0xbe, 0xa0, 0xdf, 0x23, 0x1f, 0x2b, 0xfc, - 0xe3, 0x06, 0x19, 0xa5, 0x1f, 0xfb, 0x56, 0x42, 0x46, 0xe9, 0xc7, 0x3f, 0xa3, 0xd0, 0x66, 0x38, - 0x1d, 0x95, 0x9c, 0x4c, 0xa5, 0xe3, 0x81, 0xf8, 0x44, 0x01, 0x88, 0x5e, 0xaf, 0x13, 0x89, 0x92, - 0xa8, 0xed, 0x7d, 0xbf, 0xfa, 0x6a, 0x6f, 0x46, 0x88, 0xed, 0x22, 0xc7, 0x76, 0x9e, 0x9c, 0x4b, - 0xc5, 0xc6, 0x22, 0x4c, 0xbf, 0x53, 0x60, 0x32, 0xf6, 0x7d, 0x89, 0x57, 0x55, 0xcb, 0x5d, 0xb9, - 0x69, 0x5f, 0x14, 0xa9, 0x37, 0xf6, 0x63, 0x8a, 0xa0, 0xe7, 0x39, 0xe8, 0x17, 0x89, 0x96, 0xbe, - 0x55, 0x63, 0x9f, 0xfd, 0xfc, 0x55, 0x81, 0xa9, 0xb4, 0x4f, 0x6d, 0x64, 0x6e, 0x81, 0x8c, 0x2f, - 0x7c, 0x64, 0x6e, 0x81, 0xac, 0x2f, 0x7c, 0xb4, 0xd7, 0x38, 0x07, 0x9d, 0x5c, 0xe9, 0xce, 0x21, - 0x21, 0x22, 0x63, 0x5f, 0x80, 0xf5, 0xa0, 0x20, 0xe3, 0xf1, 0x5f, 0xec, 0xdd, 0x50, 0x4a, 0x8f, - 0x55, 0x22, 0x8b, 0x98, 0x1e, 0x13, 0x3c, 0xc9, 0xeb, 0xb1, 0xfd, 0xe1, 0x4e, 0xff, 0xfc, 0xae, - 0x8b, 0x1e, 0x13, 0x70, 0xe7, 0x1f, 0x7c, 0xf6, 0x6c, 0x5a, 0xf9, 0xfc, 0xd9, 0xb4, 0xf2, 0xc5, - 0xb3, 0x69, 0xe5, 0xe9, 0xf3, 0xe9, 0x03, 0x9f, 0x3f, 0x9f, 0x3e, 0xf0, 0xcf, 0xe7, 0xd3, 0x07, - 0x9e, 0xe8, 0x35, 0x93, 0xd5, 0xb7, 0xca, 0xb9, 0x8a, 0xbd, 0x99, 0x5a, 0xc5, 0xef, 0x08, 0x7b, - 0xa7, 0xd5, 0xa4, 0x6e, 0x79, 0x88, 0x7f, 0x25, 0x79, 0xed, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x07, 0xed, 0xea, 0x3d, 0xee, 0x2a, 0x00, 0x00, + // 2495 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x6f, 0xdc, 0xc6, + 0x15, 0x37, 0xad, 0x48, 0x96, 0x9e, 0x3e, 0x2c, 0x8f, 0xe5, 0x2f, 0xda, 0x96, 0x65, 0x2a, 0x8e, + 0x65, 0xc5, 0x5e, 0xc6, 0x72, 0x12, 0xcb, 0x1f, 0x8a, 0xad, 0x75, 0x6d, 0xc9, 0x4e, 0x6a, 0x2b, + 0xbb, 0x6a, 0x53, 0x38, 0x6d, 0xb7, 0xdc, 0xdd, 0xd1, 0x2e, 0x9b, 0x15, 0xb9, 0x21, 0x47, 0x8a, + 0x36, 0xaa, 0xd0, 0xa2, 0xc7, 0xa0, 0x87, 0x00, 0x05, 0xda, 0x5b, 0x11, 0xa0, 0x68, 0x6f, 0x05, + 0x8a, 0x00, 0x45, 0x0b, 0x14, 0x3d, 0xe4, 0xd4, 0x1c, 0x7a, 0x48, 0x51, 0xa0, 0x68, 0x2f, 0x6d, + 0x60, 0xb7, 0xff, 0x47, 0xc1, 0xe1, 0x23, 0x39, 0xe4, 0x72, 0xb9, 0xb3, 0xca, 0xf6, 0xa4, 0xe5, + 0xcc, 0xbc, 0x37, 0xbf, 0xdf, 0x9b, 0x37, 0x33, 0xef, 0x27, 0x12, 0xa6, 0xec, 0xb2, 0x4b, 0x9d, + 0x6d, 0xea, 0xe8, 0xef, 0x6f, 0x51, 0xa7, 0x95, 0x6b, 0x3a, 0x36, 0xb3, 0xc9, 0xe9, 0x0f, 0x29, + 0x33, 0x2a, 0x75, 0xc3, 0xb4, 0x72, 0xfc, 0x97, 0xed, 0xd0, 0x5c, 0x30, 0x50, 0x3d, 0x5a, 0xb1, + 0x37, 0x37, 0x6d, 0x4b, 0xf7, 0xff, 0xf8, 0x16, 0xea, 0x7c, 0xc5, 0x76, 0x37, 0x6d, 0x57, 0x2f, + 0x1b, 0x2e, 0xf5, 0x5d, 0xe9, 0xdb, 0x57, 0xcb, 0x94, 0x19, 0x57, 0xf5, 0xa6, 0x51, 0x33, 0x2d, + 0x83, 0x99, 0xe1, 0xd8, 0xa9, 0x9a, 0x5d, 0xb3, 0xf9, 0x4f, 0xdd, 0xfb, 0x85, 0xad, 0x67, 0x6a, + 0xb6, 0x5d, 0x6b, 0x50, 0xdd, 0x68, 0x9a, 0xba, 0x61, 0x59, 0x36, 0xe3, 0x26, 0x2e, 0xf6, 0x1e, + 0x0b, 0x71, 0x96, 0x8d, 0x46, 0xc3, 0x66, 0x81, 0xab, 0xa8, 0xb9, 0x61, 0x6c, 0x52, 0x6c, 0x3d, + 0x2d, 0xb4, 0xda, 0x95, 0xf7, 0x4a, 0x75, 0x6a, 0x54, 0xa9, 0xd3, 0xd6, 0xc9, 0x09, 0x96, 0x2c, + 0xdb, 0xaa, 0xd0, 0x60, 0x9a, 0x73, 0x51, 0xa7, 0x63, 0xbb, 0xae, 0x3f, 0x62, 0xa3, 0x61, 0xd4, + 0xda, 0x71, 0xbc, 0x47, 0x5b, 0x35, 0x6a, 0xb5, 0x39, 0xb5, 0xec, 0x2a, 0x2d, 0x19, 0x95, 0x8a, + 0xbd, 0x65, 0x05, 0x20, 0x4f, 0x84, 0x9d, 0xc1, 0x8f, 0x36, 0x67, 0x4d, 0xc3, 0x31, 0x36, 0x83, + 0x39, 0xce, 0x46, 0xcd, 0xd4, 0xaa, 0x9a, 0x56, 0x2d, 0x8e, 0x91, 0x84, 0xdd, 0xcc, 0xc5, 0x36, + 0x6d, 0x01, 0xd4, 0xb7, 0xbd, 0xa0, 0xaf, 0x50, 0x76, 0xcf, 0xc3, 0xfc, 0x98, 0x1b, 0x14, 0xe8, + 0xfb, 0x5b, 0xd4, 0x65, 0x64, 0x0a, 0x06, 0x4d, 0xab, 0x4a, 0x77, 0x4e, 0x2a, 0x33, 0xca, 0xdc, + 0x48, 0xc1, 0x7f, 0xd0, 0x6c, 0x38, 0x9d, 0x6a, 0xe3, 0x36, 0x6d, 0xcb, 0xa5, 0x64, 0x0d, 0x46, + 0x85, 0x66, 0x6e, 0x3a, 0xba, 0x30, 0x97, 0xcb, 0xc8, 0x8c, 0x9c, 0x30, 0x3e, 0xff, 0xc2, 0xe7, + 0xff, 0x3a, 0x77, 0xa0, 0x20, 0xba, 0xd0, 0xaa, 0x08, 0x72, 0xb9, 0xd1, 0x48, 0x01, 0xf9, 0x00, + 0x20, 0xca, 0x14, 0x9c, 0xee, 0xa5, 0x9c, 0x9f, 0x56, 0x39, 0x2f, 0xad, 0x72, 0x7e, 0x86, 0x62, + 0x5a, 0xe5, 0xd6, 0x8c, 0x1a, 0x45, 0xdb, 0x82, 0x60, 0xa9, 0xfd, 0x41, 0x41, 0x5e, 0xc9, 0x69, + 0x3a, 0xf1, 0x1a, 0xf8, 0x8a, 0xbc, 0xc8, 0x4a, 0x0c, 0xf9, 0x41, 0x8e, 0xfc, 0x62, 0x57, 0xe4, + 0x3e, 0x9c, 0x18, 0xf4, 0x0d, 0x38, 0x13, 0x20, 0x5f, 0xf3, 0x57, 0xfe, 0xff, 0x13, 0xa2, 0xcf, + 0x14, 0x38, 0xdb, 0x61, 0x22, 0x0c, 0xd2, 0x3b, 0x30, 0x11, 0xcf, 0x3d, 0x8c, 0xd3, 0x7c, 0x66, + 0x9c, 0x62, 0xbe, 0x30, 0x52, 0xe3, 0x4d, 0xb1, 0xb1, 0x7f, 0xb1, 0x5a, 0x82, 0x19, 0x4e, 0x21, + 0x3e, 0x67, 0x8b, 0xaf, 0x4b, 0x10, 0xaf, 0x53, 0x30, 0xec, 0xef, 0x60, 0xb3, 0xca, 0xa3, 0x35, + 0x50, 0x38, 0xc4, 0x9f, 0x1f, 0x56, 0xb5, 0x1f, 0xc0, 0xf9, 0x0c, 0xf3, 0x8c, 0x28, 0x28, 0x7d, + 0x88, 0x82, 0x36, 0x05, 0x24, 0xd8, 0x7a, 0xeb, 0xc5, 0x22, 0xc2, 0xd5, 0x9e, 0xc0, 0xd1, 0x58, + 0x2b, 0xa2, 0x58, 0x84, 0x81, 0xf5, 0x62, 0x11, 0xa7, 0x9e, 0xc9, 0x9c, 0x7a, 0xbd, 0x58, 0xc4, + 0x09, 0x3d, 0x13, 0xed, 0x3e, 0x9c, 0x0a, 0x1d, 0xba, 0xee, 0x72, 0xb5, 0xea, 0x50, 0x37, 0x4c, + 0xa6, 0x39, 0x98, 0x2c, 0x9b, 0xac, 0x62, 0x9b, 0x56, 0x29, 0x0c, 0xd2, 0x41, 0x1e, 0xa4, 0x09, + 0x6c, 0xbf, 0x87, 0xb1, 0xba, 0x1b, 0x1d, 0x2e, 0xa2, 0x1b, 0x84, 0x37, 0x09, 0x03, 0x94, 0xd5, + 0xf1, 0x68, 0xf1, 0x7e, 0x7a, 0x2d, 0x65, 0x56, 0xe1, 0xce, 0x46, 0x0a, 0xde, 0x4f, 0xed, 0x23, + 0x05, 0xe6, 0xdb, 0x5d, 0xe4, 0x5b, 0x0f, 0x4c, 0xcb, 0x68, 0x98, 0x1f, 0xd2, 0xea, 0x2a, 0x35, + 0x6b, 0x75, 0x16, 0x40, 0x5b, 0x80, 0x63, 0x1b, 0x41, 0x4f, 0xc9, 0x63, 0x59, 0xaa, 0xf3, 0x7e, + 0x5c, 0xc4, 0xa3, 0x61, 0xe7, 0x53, 0xca, 0x0c, 0xdf, 0xb4, 0x07, 0x3a, 0x6f, 0xc3, 0xcb, 0x52, + 0x58, 0x7a, 0xe0, 0xf7, 0x3d, 0x38, 0xce, 0x5d, 0xae, 0xbb, 0xee, 0xaa, 0xe9, 0x32, 0xdb, 0x69, + 0xf5, 0x7b, 0xcb, 0xfe, 0x4a, 0x81, 0x13, 0x6d, 0x53, 0x20, 0xc2, 0x65, 0x18, 0x66, 0xae, 0x5b, + 0x6a, 0x98, 0x2e, 0xc3, 0x6d, 0x2a, 0x9b, 0x25, 0x87, 0x98, 0xeb, 0xbe, 0x65, 0xba, 0xac, 0x7f, + 0xdb, 0xf2, 0xd7, 0x0a, 0x1c, 0xf1, 0x37, 0x96, 0x63, 0x6f, 0xd3, 0xee, 0x1b, 0x91, 0x9c, 0x80, + 0x43, 0x6c, 0xa7, 0x54, 0x37, 0xdc, 0x3a, 0x06, 0x74, 0x88, 0xed, 0xac, 0x1a, 0x6e, 0x9d, 0xcc, + 0xc2, 0x60, 0xd3, 0xb1, 0xed, 0x8d, 0x93, 0x03, 0x1c, 0xcd, 0x78, 0x0e, 0xeb, 0x8d, 0x35, 0xaf, + 0xb1, 0xe0, 0xf7, 0x91, 0xb3, 0x00, 0x78, 0xc5, 0x7b, 0x0e, 0x5e, 0xe0, 0x0e, 0x46, 0x78, 0x0b, + 0xf7, 0x71, 0x0a, 0x86, 0xd9, 0x4e, 0xc9, 0xbf, 0xfb, 0x06, 0xfd, 0x79, 0xd9, 0xce, 0x43, 0x7e, + 0xfb, 0xcd, 0xe3, 0x16, 0x44, 0x9c, 0x18, 0xca, 0x29, 0x18, 0xdc, 0x36, 0x1a, 0x88, 0x72, 0xb8, + 0xe0, 0x3f, 0x84, 0xdb, 0x75, 0x8d, 0xdf, 0xd2, 0xc1, 0x76, 0xfd, 0x16, 0x6e, 0xd7, 0xa0, 0x35, + 0x5c, 0x8d, 0x21, 0xff, 0x36, 0xc7, 0xd5, 0x9e, 0xcd, 0x3e, 0x2c, 0xf8, 0x50, 0x5c, 0x0e, 0x34, + 0xd4, 0xea, 0x30, 0xc5, 0x3d, 0xaf, 0x1a, 0xee, 0x37, 0x6d, 0x46, 0xab, 0x41, 0x18, 0x5f, 0x86, + 0x23, 0x7e, 0xf5, 0x53, 0x32, 0xab, 0xd4, 0x62, 0xe6, 0x86, 0x49, 0x1d, 0x4c, 0xcc, 0x49, 0xbf, + 0xe3, 0x61, 0xd8, 0x4e, 0x66, 0x61, 0x7c, 0xdb, 0x66, 0xd4, 0x29, 0x19, 0x7e, 0x86, 0x63, 0x78, + 0xc7, 0x78, 0x23, 0x66, 0xbd, 0xf6, 0x2a, 0x1c, 0x4b, 0xcc, 0x84, 0x2c, 0x4e, 0xc3, 0x48, 0xdd, + 0x70, 0x4b, 0xde, 0xe0, 0x20, 0x18, 0xc3, 0x75, 0x1c, 0xa4, 0x7d, 0x1d, 0xa6, 0xb9, 0x55, 0x9e, + 0xcf, 0x99, 0x6f, 0x45, 0xb3, 0xee, 0x07, 0xa9, 0xc6, 0x60, 0xc4, 0xf3, 0xeb, 0xf0, 0x4c, 0x6c, + 0x83, 0xad, 0xb4, 0xc3, 0x26, 0x79, 0x18, 0xf1, 0x9e, 0x4b, 0xac, 0xd5, 0xa4, 0x9c, 0xd7, 0xc4, + 0xc2, 0x85, 0xcc, 0x30, 0x7b, 0xfe, 0xd7, 0x5b, 0x4d, 0x5a, 0x18, 0xde, 0xc6, 0x5f, 0xda, 0xef, + 0x0f, 0xc2, 0xb9, 0x8e, 0x2c, 0x30, 0x0a, 0x3d, 0x05, 0xfc, 0x0d, 0x18, 0xe2, 0x20, 0xbd, 0x48, + 0x0f, 0xf0, 0x6d, 0xde, 0x0d, 0x11, 0x67, 0x5c, 0x40, 0x2b, 0xf2, 0x0e, 0x4c, 0xfa, 0xbd, 0x7c, + 0x27, 0xf9, 0xdc, 0x06, 0x38, 0xb7, 0xcb, 0x99, 0x9e, 0x9e, 0x44, 0x46, 0x9c, 0xe2, 0x61, 0x3b, + 0xde, 0x40, 0x1e, 0xc3, 0x38, 0xb2, 0x70, 0x99, 0xc1, 0xb6, 0x5c, 0xbe, 0x4f, 0x26, 0x16, 0x2e, + 0x65, 0x7a, 0xf5, 0xa3, 0x52, 0xe4, 0x06, 0x85, 0xb1, 0xb2, 0xf0, 0xa4, 0x11, 0x98, 0xe4, 0x81, + 0x7b, 0x82, 0x63, 0x8b, 0x94, 0x69, 0x8b, 0x70, 0x32, 0xd9, 0x16, 0x46, 0xf1, 0x0c, 0x8c, 0x04, + 0x6e, 0xfd, 0x3a, 0x62, 0xa4, 0x10, 0x35, 0x68, 0xc7, 0x31, 0xd9, 0x8b, 0x5b, 0xcd, 0xa6, 0xed, + 0x30, 0x5a, 0xe5, 0xe7, 0xb4, 0xab, 0xdd, 0xc7, 0x62, 0x28, 0xd1, 0x1e, 0x7a, 0xbd, 0x00, 0x43, + 0x1c, 0x7b, 0x50, 0x9a, 0x84, 0x07, 0x84, 0x7f, 0x87, 0x63, 0xa7, 0x76, 0x07, 0xb4, 0x58, 0x95, + 0xeb, 0x6f, 0xb8, 0x07, 0xb6, 0x23, 0x5b, 0x29, 0x38, 0x30, 0x9b, 0xe9, 0x00, 0xe1, 0xbc, 0x09, + 0x63, 0xbe, 0x87, 0xd8, 0xe6, 0x97, 0xa8, 0x2b, 0xf1, 0xf8, 0x18, 0xad, 0x44, 0x0f, 0xda, 0x99, + 0x44, 0x39, 0x1f, 0x3f, 0x78, 0xac, 0x44, 0xe1, 0x9e, 0x38, 0x80, 0x9e, 0xa4, 0x22, 0xb9, 0x2c, + 0x8b, 0x84, 0xe7, 0x64, 0x0c, 0x8d, 0x20, 0x2e, 0x1e, 0xdb, 0x55, 0xba, 0xec, 0x8b, 0x9b, 0x6c, + 0x71, 0xf1, 0xfd, 0x08, 0x63, 0xcc, 0x26, 0x8a, 0x96, 0x28, 0x94, 0xa4, 0xa2, 0x25, 0xfa, 0x19, + 0xb5, 0xa2, 0x07, 0x51, 0x57, 0xa4, 0xe0, 0xeb, 0xd7, 0x0d, 0xfc, 0xa9, 0xa0, 0x2b, 0xd2, 0x28, + 0x3d, 0x82, 0x51, 0xa1, 0x59, 0x4a, 0x57, 0xc4, 0x18, 0x09, 0x0f, 0xfd, 0xbb, 0x8e, 0x67, 0xf0, + 0xa4, 0xf6, 0x52, 0x25, 0x14, 0xb4, 0x0f, 0x3c, 0x3d, 0x1b, 0x24, 0xd3, 0x8f, 0x14, 0x3c, 0x06, + 0xd3, 0x86, 0x20, 0xb5, 0xef, 0xc0, 0x64, 0x52, 0x0e, 0xcb, 0x65, 0x55, 0xdc, 0x1f, 0xde, 0x72, + 0x87, 0x2b, 0xf1, 0x66, 0xed, 0x04, 0x5e, 0x42, 0x2b, 0x94, 0xbd, 0xc9, 0x45, 0x75, 0x80, 0xed, + 0x1b, 0x58, 0x56, 0x09, 0x1d, 0x88, 0xe8, 0x16, 0x0c, 0xf9, 0xfa, 0x5b, 0xea, 0x92, 0x45, 0x63, + 0x34, 0xd1, 0xce, 0xa1, 0xfa, 0x29, 0xd6, 0xed, 0x0f, 0x82, 0xf3, 0xea, 0x9e, 0x90, 0x32, 0x5e, + 0x4c, 0xa6, 0x3b, 0x8d, 0x40, 0x00, 0xdf, 0x85, 0xa3, 0x0d, 0xc3, 0x65, 0xa5, 0x60, 0x8e, 0x92, + 0x98, 0xc7, 0xb9, 0x4c, 0x34, 0x6f, 0x19, 0x2e, 0x8b, 0x3b, 0x3d, 0xd2, 0x48, 0x36, 0x69, 0x8f, + 0x10, 0x63, 0xbe, 0x61, 0x6c, 0xd2, 0xb4, 0x1b, 0xf6, 0x12, 0x4c, 0xf2, 0x7f, 0x79, 0xb4, 0xdf, + 0x4c, 0x87, 0x79, 0xbb, 0x70, 0xbf, 0x56, 0x82, 0xeb, 0xba, 0xdd, 0x57, 0x58, 0xb3, 0x00, 0x3a, + 0xb3, 0x36, 0x6c, 0x24, 0xa1, 0x65, 0x5f, 0x0f, 0xde, 0x70, 0xaf, 0xd4, 0xf2, 0xa6, 0xb2, 0x36, + 0x6c, 0x8d, 0x46, 0xbb, 0xc3, 0xef, 0xa3, 0x15, 0xdb, 0xa9, 0xf6, 0x5d, 0xba, 0xfe, 0x56, 0x89, + 0x34, 0x72, 0x7c, 0x1e, 0xa4, 0xb2, 0x92, 0xa0, 0x32, 0x20, 0x47, 0x05, 0x73, 0x33, 0x22, 0xd4, + 0xbf, 0x3d, 0x58, 0x44, 0xa5, 0x8a, 0xe1, 0xe7, 0x47, 0xed, 0xb2, 0x55, 0xe5, 0x52, 0x50, 0xa2, + 0x40, 0x9e, 0x82, 0x41, 0x2e, 0x3e, 0x51, 0xcd, 0xf8, 0x0f, 0xda, 0x06, 0xea, 0xd7, 0x74, 0xa7, + 0x1d, 0x96, 0x75, 0xa0, 0xf7, 0x65, 0x15, 0xce, 0xd6, 0x3c, 0x2f, 0xab, 0xf9, 0xbf, 0xd2, 0xfa, + 0xbd, 0xaa, 0x9f, 0x28, 0x62, 0xf6, 0x08, 0xd3, 0x84, 0x12, 0x78, 0x5c, 0xfc, 0x4f, 0x5e, 0x70, + 0xe5, 0x1f, 0x0d, 0xae, 0x7c, 0xd1, 0x66, 0xac, 0x1c, 0x3d, 0xf4, 0xf1, 0xff, 0x0d, 0xcb, 0xb8, + 0x8a, 0x2b, 0x94, 0x09, 0xb3, 0xe5, 0xbd, 0xca, 0xb9, 0x1e, 0x84, 0x23, 0xae, 0x46, 0xbc, 0x70, + 0x8c, 0x09, 0x6a, 0x44, 0x7b, 0x17, 0xd7, 0x2c, 0xdd, 0x05, 0x52, 0x7d, 0x1d, 0xc6, 0x44, 0xaa, + 0x18, 0xd4, 0x54, 0xa6, 0xa3, 0x02, 0x53, 0xed, 0x76, 0x74, 0x8c, 0x0b, 0x63, 0xbc, 0x8a, 0x4d, + 0x22, 0xc9, 0xb4, 0x1f, 0xa6, 0xb2, 0x43, 0x6b, 0x44, 0xf6, 0x2e, 0x10, 0x11, 0x19, 0x2f, 0x26, + 0x29, 0xe2, 0xbb, 0xd2, 0x25, 0xab, 0x12, 0x2e, 0x27, 0xcb, 0x89, 0x96, 0x85, 0x5f, 0xce, 0xc1, + 0x20, 0x47, 0x40, 0x3e, 0x56, 0x60, 0xc8, 0x2f, 0x3c, 0x88, 0x9e, 0xe9, 0xb5, 0x5d, 0x92, 0xa9, + 0xaf, 0xc8, 0x1b, 0xf8, 0xa4, 0xb4, 0xd9, 0x1f, 0xff, 0xed, 0x3f, 0x3f, 0x3d, 0x78, 0x96, 0x9c, + 0xd6, 0xbd, 0xf1, 0x57, 0xb8, 0xa9, 0x9e, 0xf8, 0xb7, 0x2c, 0xf9, 0x93, 0x02, 0xc3, 0x81, 0x42, + 0x22, 0x57, 0xbb, 0xcf, 0x91, 0xd0, 0x6d, 0xea, 0x42, 0x2f, 0x26, 0x08, 0xec, 0x11, 0x07, 0xf6, + 0x35, 0x92, 0x4f, 0x05, 0x16, 0x6a, 0x33, 0x7d, 0xb7, 0x4d, 0xa0, 0xec, 0xe9, 0xbb, 0x31, 0x05, + 0xb5, 0x47, 0xfe, 0xae, 0x00, 0x69, 0x57, 0x39, 0xe4, 0x56, 0x77, 0x58, 0x1d, 0x15, 0x9e, 0x7a, + 0x7b, 0x7f, 0xc6, 0xc8, 0xee, 0x3e, 0x67, 0x77, 0x87, 0x2c, 0xa5, 0xb2, 0x43, 0x4a, 0xe5, 0x96, + 0xc0, 0x2a, 0x8d, 0x28, 0xf9, 0x85, 0x02, 0xa3, 0x82, 0xe2, 0x20, 0x57, 0xba, 0x83, 0x12, 0x86, + 0xab, 0xaf, 0xf5, 0x34, 0x3c, 0x04, 0x7f, 0x89, 0x83, 0x9f, 0x25, 0xe7, 0x53, 0xc1, 0x87, 0x15, + 0x81, 0x4b, 0x19, 0xf9, 0x8d, 0x02, 0x87, 0x13, 0x02, 0x46, 0x26, 0x81, 0x12, 0x26, 0xea, 0x8d, + 0x9e, 0x4d, 0x42, 0xb0, 0x97, 0x39, 0xd8, 0x97, 0xc8, 0x8b, 0xa9, 0x60, 0xdd, 0x04, 0xb6, 0x7f, + 0x2b, 0x70, 0x3c, 0x5d, 0xe8, 0x90, 0x3b, 0xdd, 0x31, 0x64, 0x6a, 0x2c, 0xf5, 0xee, 0xfe, 0x1d, + 0x20, 0x97, 0x3c, 0xe7, 0x72, 0x9b, 0xdc, 0x4c, 0xe5, 0x52, 0xa3, 0xac, 0x24, 0x0a, 0x9f, 0xd2, + 0x86, 0xed, 0xf8, 0x0d, 0xfa, 0x6e, 0x70, 0xee, 0xed, 0x91, 0x4f, 0x15, 0x98, 0x88, 0x4f, 0x43, + 0xae, 0xf7, 0x0a, 0x2c, 0x60, 0xb4, 0xd8, 0xbb, 0x21, 0x32, 0xb9, 0xc2, 0x99, 0x5c, 0x24, 0x17, + 0xa4, 0x98, 0x78, 0xa0, 0x63, 0xfa, 0x40, 0x0e, 0x71, 0xbb, 0x18, 0x92, 0x44, 0x9c, 0x22, 0x6f, + 0xb4, 0x57, 0x38, 0xe2, 0x79, 0x32, 0x97, 0x8a, 0x58, 0x90, 0x63, 0xfa, 0x2e, 0x57, 0x80, 0x7b, + 0x5e, 0xee, 0x4f, 0x08, 0x9e, 0x96, 0x1b, 0x0d, 0x19, 0xdc, 0xa9, 0x22, 0x4e, 0x06, 0x77, 0xba, + 0x2c, 0xd3, 0xe6, 0x38, 0x6e, 0x8d, 0xcc, 0x74, 0xc3, 0x4d, 0xfe, 0xa8, 0xc0, 0xe1, 0x84, 0x62, + 0x91, 0x39, 0x22, 0x3b, 0x4a, 0x2b, 0x99, 0x23, 0xb2, 0xb3, 0xe8, 0xea, 0x92, 0x22, 0x49, 0x3d, + 0x46, 0x7e, 0xa6, 0xc0, 0x90, 0xaf, 0x73, 0xc8, 0x82, 0xd4, 0xbc, 0x31, 0xa9, 0xa5, 0x5e, 0xeb, + 0xc9, 0x46, 0xea, 0xf2, 0xf4, 0xd5, 0x16, 0xf9, 0xb3, 0x02, 0x47, 0xda, 0x74, 0x14, 0xb9, 0x29, + 0x71, 0xa2, 0x75, 0x90, 0x67, 0xea, 0xad, 0x7d, 0xd9, 0x22, 0xe6, 0x1b, 0x1c, 0xf3, 0x35, 0x72, + 0x55, 0xc4, 0x1c, 0x78, 0x11, 0x0e, 0xc6, 0xba, 0xfd, 0x41, 0x42, 0xdc, 0x91, 0xbf, 0x2a, 0x70, + 0xa4, 0x4d, 0x43, 0xc9, 0x30, 0xe9, 0x24, 0xe2, 0x64, 0x98, 0x74, 0x14, 0x6d, 0xda, 0x3d, 0xce, + 0x64, 0x89, 0xdc, 0x4a, 0xbf, 0x43, 0x79, 0xe1, 0x9f, 0xbc, 0x42, 0x13, 0x8a, 0x71, 0xcf, 0x2b, + 0x6d, 0xc8, 0x0a, 0x65, 0x09, 0x35, 0x45, 0xe4, 0xf6, 0x5b, 0x8a, 0xd0, 0x93, 0xb9, 0xaa, 0x3a, + 0x48, 0x37, 0x6d, 0x81, 0x13, 0xba, 0x4c, 0xe6, 0x3b, 0x1e, 0x8a, 0x46, 0xa3, 0x51, 0xf2, 0x39, + 0x38, 0x08, 0xf4, 0x4b, 0x05, 0x8e, 0x71, 0x67, 0x6e, 0x42, 0x04, 0x91, 0x25, 0xe9, 0xd8, 0xa6, + 0x29, 0x32, 0xf5, 0x8d, 0xfd, 0x9a, 0x23, 0x99, 0x55, 0x4e, 0x26, 0x4f, 0xee, 0x66, 0xaf, 0x8e, + 0xbf, 0x85, 0x0d, 0xab, 0xea, 0xbf, 0x61, 0x14, 0x6e, 0x2a, 0x7d, 0x97, 0xb7, 0xec, 0x79, 0xe7, + 0x52, 0xb8, 0x44, 0x82, 0xb2, 0xb9, 0x2e, 0x19, 0xe8, 0xa4, 0x68, 0x53, 0x17, 0x7b, 0x37, 0xec, + 0x71, 0x81, 0x04, 0xa5, 0x46, 0xfe, 0xa9, 0xc0, 0x54, 0x9a, 0xe0, 0x91, 0x59, 0x9f, 0x0c, 0xad, + 0x25, 0xb3, 0x3e, 0x59, 0x3a, 0x4b, 0xa2, 0x96, 0x88, 0x89, 0x9d, 0x72, 0x8b, 0x8b, 0x3a, 0x6f, + 0x0b, 0x05, 0x02, 0x6f, 0x8f, 0xfc, 0x57, 0x01, 0x35, 0x45, 0x31, 0x61, 0x4a, 0x90, 0xdb, 0xbd, + 0x42, 0x14, 0xd5, 0x9a, 0xba, 0xb4, 0x4f, 0x6b, 0x29, 0xfd, 0xd0, 0xc6, 0x8f, 0x8b, 0xb9, 0x28, + 0x21, 0xcd, 0xaa, 0x58, 0x33, 0xfd, 0x44, 0x81, 0x41, 0xfe, 0x9e, 0x8c, 0xe4, 0x24, 0x04, 0x96, + 0xf0, 0xe2, 0x4f, 0xd5, 0xa5, 0xc7, 0x23, 0x6c, 0x8d, 0xc3, 0x3e, 0x43, 0xd4, 0x74, 0x3d, 0xc6, + 0x41, 0x7c, 0xa6, 0xc0, 0x78, 0xec, 0xe5, 0x2d, 0x79, 0x5d, 0x2a, 0x56, 0x6d, 0xef, 0xc0, 0xd5, + 0xeb, 0x3d, 0xdb, 0x21, 0xcc, 0x3b, 0x1c, 0xe6, 0x0d, 0x72, 0xbd, 0x63, 0x74, 0x99, 0xeb, 0x06, + 0x02, 0x4c, 0xdf, 0x4d, 0xbe, 0x99, 0xde, 0x23, 0x3f, 0x3f, 0x08, 0xd3, 0xd9, 0x2f, 0xa0, 0xc9, + 0x4a, 0x8f, 0xe0, 0x3a, 0xbd, 0x4e, 0x57, 0x57, 0xbf, 0xba, 0x23, 0xa4, 0x5d, 0xe6, 0xb4, 0xbf, + 0x4d, 0x9e, 0xca, 0xd0, 0x2e, 0xd5, 0xf9, 0x7b, 0x6a, 0xb3, 0x62, 0x34, 0xf4, 0xdd, 0xd4, 0xf7, + 0xf9, 0x7b, 0x69, 0x91, 0xf9, 0x48, 0xe1, 0xdf, 0x3b, 0xc8, 0x88, 0xff, 0xd8, 0xe7, 0x13, 0x32, + 0xe2, 0x3f, 0xfe, 0x65, 0x85, 0x36, 0xc3, 0xe9, 0xa8, 0xe4, 0x64, 0x2a, 0x1d, 0x0f, 0xc4, 0x27, + 0x0a, 0x40, 0xf4, 0xc6, 0x9d, 0x48, 0x54, 0x49, 0x6d, 0x9f, 0x00, 0xa8, 0xaf, 0xf6, 0x66, 0x84, + 0xd8, 0x2e, 0x72, 0x6c, 0xe7, 0xc9, 0xb9, 0x54, 0x6c, 0x2c, 0xc2, 0xf4, 0x3b, 0x05, 0x26, 0x63, + 0x9f, 0x9c, 0x78, 0x85, 0xb6, 0xdc, 0x2d, 0x9c, 0xf6, 0x91, 0x91, 0x7a, 0x73, 0x3f, 0xa6, 0x08, + 0x7a, 0x9e, 0x83, 0x7e, 0x91, 0x68, 0xe9, 0xbb, 0x37, 0xf6, 0x25, 0xd0, 0x5f, 0x14, 0x98, 0x4a, + 0xfb, 0xfa, 0x46, 0xe6, 0x62, 0xc8, 0xf8, 0xe8, 0x47, 0xe6, 0x62, 0xc8, 0xfa, 0xe8, 0x47, 0x7b, + 0x8d, 0x73, 0xd0, 0xc9, 0x95, 0xee, 0x1c, 0x12, 0xba, 0x32, 0xf6, 0x51, 0x58, 0x0f, 0xa2, 0x32, + 0x1e, 0xff, 0xc5, 0xde, 0x0d, 0xa5, 0x24, 0x5a, 0x25, 0xb2, 0x88, 0x49, 0x34, 0xc1, 0x93, 0xbc, + 0x44, 0xdb, 0x1f, 0xee, 0xf4, 0x2f, 0xf2, 0xba, 0x48, 0x34, 0x01, 0x77, 0xfe, 0xe1, 0xe7, 0xcf, + 0xa6, 0x95, 0x2f, 0x9e, 0x4d, 0x2b, 0x5f, 0x3e, 0x9b, 0x56, 0x3e, 0x7e, 0x3e, 0x7d, 0xe0, 0x8b, + 0xe7, 0xd3, 0x07, 0xfe, 0xf1, 0x7c, 0xfa, 0xc0, 0x53, 0xbd, 0x66, 0xb2, 0xfa, 0x56, 0x39, 0x57, + 0xb1, 0x37, 0x53, 0x0b, 0xfb, 0x1d, 0x61, 0xef, 0xb4, 0x9a, 0xd4, 0x2d, 0x0f, 0xf1, 0x0f, 0x27, + 0xaf, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x52, 0xe2, 0xbb, 0x9a, 0x01, 0x2b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index a58fb7ea00..16460849d8 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -779,19 +779,26 @@ func local_request_Query_Prove_0(ctx context.Context, marshaler runtime.Marshale } -var ( - filter_Query_GetTssAddress_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - func request_Query_GetTssAddress_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryGetTssAddressRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bitcoin_chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bitcoin_chain_id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetTssAddress_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.BitcoinChainId, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bitcoin_chain_id", err) } msg, err := client.GetTssAddress(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -803,11 +810,22 @@ func local_request_Query_GetTssAddress_0(ctx context.Context, marshaler runtime. var protoReq QueryGetTssAddressRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["bitcoin_chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bitcoin_chain_id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetTssAddress_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.BitcoinChainId, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bitcoin_chain_id", err) } msg, err := server.GetTssAddress(ctx, &protoReq) @@ -2375,7 +2393,7 @@ var ( pattern_Query_Prove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "prove"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_GetTssAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_tss_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_GetTssAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "get_tss_address", "bitcoin_chain_id"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_GetTssAddressByFinalizedHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"zeta-chain", "observer", "get_tss_address_historical", "finalized_zeta_height", "bitcoin_chain_id"}, "", runtime.AssumeColonVerbOpt(false))) From c657669b0240d3e8a26a62af4f8128603e99e4cf Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 12 Jan 2024 10:55:45 -0500 Subject: [PATCH 32/67] fix: pending nonces genesis import (#1546) --- changelog.md | 1 + testutil/network/genesis_state.go | 10 ++++++ .../client/integrationtests/cli_helpers.go | 2 +- .../integrationtests/inbound_voter_test.go | 20 +++++------- x/crosschain/keeper/msg_server_tss_voter.go | 1 - .../cli/tx_update_update_system_contract.go | 3 -- x/observer/genesis.go | 31 +++++++++++-------- x/observer/keeper/pending_nonces.go | 1 - 8 files changed, 37 insertions(+), 32 deletions(-) diff --git a/changelog.md b/changelog.md index db702f1fba..40b38a4322 100644 --- a/changelog.md +++ b/changelog.md @@ -41,6 +41,7 @@ * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses * [1536](https://github.com/zeta-chain/node/pull/1536) - add index to check previously finalized inbounds * [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing +* [1546](https://github.com/zeta-chain/node/pull/1546) - fix reset of pending nonces on genesis import * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB * [1567](https://github.com/zeta-chain/node/pull/1567) - add bitcoin chain id to fetch the tss address rpc endpoint diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index a88018e8f7..d74b5c4c8f 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -127,8 +127,18 @@ func AddObserverData(t *testing.T, n int, genesisState map[string]json.RawMessag FinalizedZetaHeight: 1, KeyGenZetaHeight: 1, } + pendingNonces := make([]observertypes.PendingNonces, len(common.DefaultChainsList())) + for i, chain := range common.DefaultChainsList() { + pendingNonces[i] = observertypes.PendingNonces{ + ChainId: chain.ChainId, + NonceLow: 0, + NonceHigh: 0, + Tss: tss.TssPubkey, + } + } state.Tss = &tss state.TssHistory = []observertypes.TSS{tss} + state.PendingNonces = pendingNonces // set crosschain flags crosschainFlags := &observertypes.CrosschainFlags{ diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 03f565fc97..626706a627 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -181,7 +181,7 @@ func BuildSignedTssVote(t testing.TB, val *network.Validator, denom string, acco cmd := cli.CmdCreateTSSVoter() inboundVoterArgs := []string{ "tsspubkey", - strconv.FormatInt(common.GoerliLocalnetChain().ChainId, 10), + "1", "0", } txArgs := []string{ diff --git a/x/crosschain/client/integrationtests/inbound_voter_test.go b/x/crosschain/client/integrationtests/inbound_voter_test.go index ce0a0043e8..424a7e68eb 100644 --- a/x/crosschain/client/integrationtests/inbound_voter_test.go +++ b/x/crosschain/client/integrationtests/inbound_voter_test.go @@ -237,20 +237,14 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { _, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) s.Require().NoError(err) } - s.Require().NoError(s.network.WaitForNBlocks(2)) - - // Vote the tss - for _, val := range s.network.Validators { - out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetAccountCmd(), []string{val.Address.String(), "--output", "json"}) - s.Require().NoError(err) - var account authtypes.AccountI - s.NoError(val.ClientCtx.Codec.UnmarshalInterfaceJSON(out.Bytes(), &account)) - signedTx := BuildSignedTssVote(s.T(), val, s.cfg.BondDenom, account) - out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, authcli.GetBroadcastCommand(), []string{signedTx.Name(), "--broadcast-mode", "sync"}) - s.Require().NoError(err) - } s.Require().NoError(s.network.WaitForNBlocks(2)) + out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdListPendingNonces(), []string{"--output", "json"}) + s.Require().NoError(err) + fmt.Println(out.String()) + out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdGetSupportedChains(), []string{"--output", "json"}) + s.Require().NoError(err) + fmt.Println(out.String()) // Vote the inbound tx for _, val := range s.network.Validators { @@ -274,7 +268,7 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { // Get the ballot ballotIdentifier := GetBallotIdentifier(test.name, i) - out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdBallotByIdentifier(), []string{ballotIdentifier, "--output", "json"}) + out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdBallotByIdentifier(), []string{ballotIdentifier, "--output", "json"}) s.Require().NoError(err) ballot := observerTypes.QueryBallotByIdentifierResponse{} s.NoError(broadcaster.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &ballot)) diff --git a/x/crosschain/keeper/msg_server_tss_voter.go b/x/crosschain/keeper/msg_server_tss_voter.go index b15dfcabc9..13a97e58ae 100644 --- a/x/crosschain/keeper/msg_server_tss_voter.go +++ b/x/crosschain/keeper/msg_server_tss_voter.go @@ -97,7 +97,6 @@ func (k msgServer) CreateTSSVoter(goCtx context.Context, msg *types.MsgCreateTSS } // Set TSS history only, current TSS is updated via admin transaction // In Case this is the first TSS address update both current and history - tssList := k.zetaObserverKeeper.GetAllTSS(ctx) if len(tssList) == 0 { k.GetObserverKeeper().SetTssAndUpdateNonce(ctx, tss) diff --git a/x/fungible/client/cli/tx_update_update_system_contract.go b/x/fungible/client/cli/tx_update_update_system_contract.go index 2f30a528e9..63f367c402 100644 --- a/x/fungible/client/cli/tx_update_update_system_contract.go +++ b/x/fungible/client/cli/tx_update_update_system_contract.go @@ -1,8 +1,6 @@ package cli import ( - "fmt" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -20,7 +18,6 @@ func CmdUpdateSystemContract() *cobra.Command { if err != nil { return err } - fmt.Printf("CLI address: %s\n", clientCtx.GetFromAddress().String()) msg := types.NewMsgUpdateSystemContract(clientCtx.GetFromAddress().String(), args[0]) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/observer/genesis.go b/x/observer/genesis.go index 1f22e4208f..8098394f65 100644 --- a/x/observer/genesis.go +++ b/x/observer/genesis.go @@ -94,21 +94,30 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetLastObserverCount(ctx, &types.LastObserverCount{LastChangeHeight: 0, Count: observerCount}) } + tss := types.TSS{} if genState.Tss != nil { - tss := *genState.Tss + tss = *genState.Tss k.SetTSS(ctx, tss) + } + + // Set all the pending nonces + if genState.PendingNonces != nil { + for _, pendingNonce := range genState.PendingNonces { + k.SetPendingNonces(ctx, pendingNonce) + } + } else { for _, chain := range common.DefaultChainsList() { - k.SetPendingNonces(ctx, types.PendingNonces{ - NonceLow: 0, - NonceHigh: 0, - ChainId: chain.ChainId, - Tss: tss.TssPubkey, - }) + if genState.Tss != nil { + k.SetPendingNonces(ctx, types.PendingNonces{ + NonceLow: 0, + NonceHigh: 0, + ChainId: chain.ChainId, + Tss: tss.TssPubkey, + }) + } } } - // Get all chain nonces - for _, elem := range genState.TssHistory { k.SetTSSHistory(ctx, elem) } @@ -121,10 +130,6 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetBlame(ctx, elem) } - // Set all the pending nonces - for _, pendingNonce := range genState.PendingNonces { - k.SetPendingNonces(ctx, pendingNonce) - } for _, chainNonce := range genState.ChainNonces { k.SetChainNonces(ctx, chainNonce) } diff --git a/x/observer/keeper/pending_nonces.go b/x/observer/keeper/pending_nonces.go index eb140ee4bd..198a1219b5 100644 --- a/x/observer/keeper/pending_nonces.go +++ b/x/observer/keeper/pending_nonces.go @@ -91,7 +91,6 @@ func (k Keeper) SetTssAndUpdateNonce(ctx sdk.Context, tss types.TSS) { FinalizedHeight: uint64(ctx.BlockHeight()), } k.SetChainNonces(ctx, chainNonce) - p := types.PendingNonces{ NonceLow: 0, NonceHigh: 0, From bfd3c01fb6cac78da8e631f4a8774371c178f618 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Fri, 12 Jan 2024 16:54:56 -0800 Subject: [PATCH 33/67] fix: resolve migration script for v12 (#1549) * move migration script * update tests * add monitoring for vote tx results * changelog entry * fix invalid contract setup * fix smoke tests * optimize zeta deposit * latest experimentation * revert back e2e tests * add migration script for finalized inbound * add tests * goimport * lint issues * reformat breaking changes * fix typo --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- changelog.md | 27 +++++-- cmd/zetae2e/local/bitcoin.go | 13 ++-- cmd/zetae2e/local/erc20.go | 5 -- cmd/zetae2e/local/ethereum.go | 8 -- cmd/zetae2e/local/local.go | 5 +- .../smoketest/cmd/smoketest/local/bitcoin.go | 3 +- .../smoketest/cmd/smoketest/local/ethereum.go | 2 - .../smoketest/runner/accounting.go | 10 ++- .../smoketest/runner/setup_bitcoin.go | 32 ++++---- .../smoketest/runner/setup_zeta.go | 24 +++--- .../localnet/orchestrator/start-upgrade.sh | 2 +- contrib/localnet/scripts/genesis-stateful.sh | 15 +++- contrib/localnet/scripts/genesis.sh | 14 +++- x/crosschain/keeper/migrator.go | 2 +- x/crosschain/migrations/v4/migrate.go | 43 ++++++++-- x/crosschain/migrations/v4/migrate_test.go | 76 +++++++++++++++++- x/observer/keeper/migrator.go | 2 +- x/observer/migrations/v4/migrate.go | 33 +------- x/observer/migrations/v4/migrate_test.go | 76 ------------------ x/observer/migrations/v5/migrate.go | 47 ++++++++++- x/observer/migrations/v5/migrate_test.go | 78 ++++++++++++++++++- zetaclient/bitcoin_client.go | 4 +- zetaclient/broadcast.go | 18 +++-- zetaclient/tx.go | 44 +++++++++++ 24 files changed, 386 insertions(+), 197 deletions(-) diff --git a/changelog.md b/changelog.md index 40b38a4322..860a46e6db 100644 --- a/changelog.md +++ b/changelog.md @@ -2,16 +2,28 @@ ## Unreleased -* ci: adding typescript publishing pipeline. - ### Breaking Changes -* PendingNonces :Changed from `/zeta-chain/crosschain/pendingNonces/{chain_id}/{address}` to `/zeta-chain/observer/pendingNonces/{chain_id}/{address}` . It returns all the pending nonces for a chain id and address. This returns the current pending nonces for the chain. -* ChainNonces : Changed from `/zeta-chain/criosschain/chainNonces/{chain_id}` to`/zeta-chain/observer/chainNonces/{chain_id}` . It returns all the chain nonces for a chain id. This returns the current nonce oof the TSS address for the chain. -* ChainNoncesAll :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. -* GetTssAddress : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoing chain id can now now passed as a parameter to fetch the correct tss for required BTC chain.This parameter only affects the BTC tss address in the response. +TSS and chain validation related queries have been moved from `crosschain` module to `observer` module: +* `PendingNonces` :Changed from `/zeta-chain/crosschain/pendingNonces/{chain_id}/{address}` to `/zeta-chain/observer/pendingNonces/{chain_id}/{address}` . It returns all the pending nonces for a chain id and address. This returns the current pending nonces for the chain. +* `ChainNonces` : Changed from `/zeta-chain/crosschain/chainNonces/{chain_id}` to`/zeta-chain/observer/chainNonces/{chain_id}` . It returns all the chain nonces for a chain id. This returns the current nonce oof the TSS address for the chain. +* `ChainNoncesAll` :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. + +All chains now have the same observer set: +* `ObserversByChain`: `/zeta-chain/observer/observers_by_chain/{observation_chain}` has been removed and replaced with `/zeta-chain/observer/observer_set`. All chains have the same observer set. +* `AllObserverMappers`: `/zeta-chain/observer/all_observer_mappers` has been removed. `/zeta-chain/observer/observer_set` should be used to get observers. + +Observer params and core params have been merged into chain params: +* `Params`: `/zeta-chain/observer/params` no longer returns observer params. Observer params data have been moved to chain params described below. +* `GetCoreParams`: Renamed into `GetChainParams`. `/zeta-chain/observer/get_core_params` moved to `/zeta-chain/observer/get_chain_params`. +* `GetCoreParamsByChain`: Renamed into `GetChainParamsForChain`. `/zeta-chain/observer/get_core_params_by_chain` moved to `/zeta-chain/observer/get_chain_params_by_chain`. + +Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin chain id: +* `GetTssAddress` : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoing chain id can now now passed as a parameter to fetch the correct tss for required BTC chain.This parameter only affects the BTC tss address in the response. ### Features + +* [1549](https://github.com/zeta-chain/node/pull/1549) - add monitoring for vote tx results in ZetaClient * [1498](https://github.com/zeta-chain/node/pull/1498) - Add monitoring(grafana, prometheus, ethbalance) for localnet testing * [1395](https://github.com/zeta-chain/node/pull/1395) - Add state variable to track aborted zeta amount * [1410](https://github.com/zeta-chain/node/pull/1410) - `snapshots` commands @@ -65,6 +77,7 @@ * Update --ledger flag hint ### Chores + * [1446](https://github.com/zeta-chain/node/pull/1446) - renamed file `zetaclientd/aux.go` to `zetaclientd/utils.go` to avoid complaints from go package resolver. * [1499](https://github.com/zeta-chain/node/pull/1499) - Add scripts to localnet to help test gov proposals * [1442](https://github.com/zeta-chain/node/pull/1442) - remove build types in `.goreleaser.yaml` @@ -76,7 +89,9 @@ * [1538](https://github.com/zeta-chain/node/pull/1538) - improve stateful e2e testing ### CI + * Removed private runners and unused GitHub Action +* Adding typescript publishing pipeline. ## Version: v11.0.0 diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index 73a1bdaeee..a27d619138 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -16,6 +16,7 @@ func bitcoinTestRoutine( conf config.Config, deployerRunner *runner.SmokeTestRunner, verbose bool, + initBitcoinNetwork bool, ) func() error { return func() (err error) { // return an error on panic @@ -47,23 +48,19 @@ func bitcoinTestRoutine( startTime := time.Now() // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserBitcoinAddress, 1000) txUSDTSend := deployerRunner.SendUSDTOnEvm(UserBitcoinAddress, 1000) - - bitcoinRunner.WaitForTxReceiptOnEvm(txZetaSend) bitcoinRunner.WaitForTxReceiptOnEvm(txUSDTSend) // depositing the necessary tokens on ZetaChain - txZetaDeposit := bitcoinRunner.DepositZeta() txEtherDeposit := bitcoinRunner.DepositEther(false) txERC20Deposit := bitcoinRunner.DepositERC20() - bitcoinRunner.SetupBitcoinAccount() - bitcoinRunner.DepositBTC(false) - bitcoinRunner.SetupZEVMSwapApp() - bitcoinRunner.WaitForMinedCCTX(txZetaDeposit) + bitcoinRunner.WaitForMinedCCTX(txEtherDeposit) bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) + bitcoinRunner.SetupBitcoinAccount(initBitcoinNetwork) + bitcoinRunner.DepositBTC(false) + // run bitcoin test // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first // to make it faster to catch up with the latest block header diff --git a/cmd/zetae2e/local/erc20.go b/cmd/zetae2e/local/erc20.go index c745077547..8e5a286fa8 100644 --- a/cmd/zetae2e/local/erc20.go +++ b/cmd/zetae2e/local/erc20.go @@ -47,17 +47,12 @@ func erc20TestRoutine( startTime := time.Now() // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserERC20Address, 1000) txUSDTSend := deployerRunner.SendUSDTOnEvm(UserERC20Address, 10) - - erc20Runner.WaitForTxReceiptOnEvm(txZetaSend) erc20Runner.WaitForTxReceiptOnEvm(txUSDTSend) // depositing the necessary tokens on ZetaChain - txZetaDeposit := erc20Runner.DepositZeta() txEtherDeposit := erc20Runner.DepositEther(false) txERC20Deposit := erc20Runner.DepositERC20() - erc20Runner.WaitForMinedCCTX(txZetaDeposit) erc20Runner.WaitForMinedCCTX(txEtherDeposit) erc20Runner.WaitForMinedCCTX(txERC20Deposit) diff --git a/cmd/zetae2e/local/ethereum.go b/cmd/zetae2e/local/ethereum.go index f8328035ba..74a57a6470 100644 --- a/cmd/zetae2e/local/ethereum.go +++ b/cmd/zetae2e/local/ethereum.go @@ -46,18 +46,10 @@ func ethereumTestRoutine( ethereumRunner.Logger.Print("🏃 starting Ethereum tests") startTime := time.Now() - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserEtherAddress, 1000) - ethereumRunner.WaitForTxReceiptOnEvm(txZetaSend) - // depositing the necessary tokens on ZetaChain - txZetaDeposit := ethereumRunner.DepositZeta() txEtherDeposit := ethereumRunner.DepositEther(false) - ethereumRunner.WaitForMinedCCTX(txZetaDeposit) ethereumRunner.WaitForMinedCCTX(txEtherDeposit) - ethereumRunner.SetupContextApp() - // run ethereum test // Note: due to the extensive block generation in Ethereum localnet, block header test is run first // to make it faster to catch up with the latest block header diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 72023b8e9b..f1a723f26e 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -201,7 +201,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { deployerRunner.SetZEVMContracts() deployerRunner.MintUSDTOnEvm(10000) logger.Print("✅ setup completed in %s", time.Since(startTime)) - deployerRunner.PrintContractAddresses() } // if a config output is specified, write the config @@ -220,6 +219,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ config file written in %s", configOut) } + deployerRunner.PrintContractAddresses() + // if setup only, quit if setupOnly { os.Exit(0) @@ -230,7 +231,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if !skipRegular { eg.Go(erc20TestRoutine(conf, deployerRunner, verbose)) eg.Go(zetaTestRoutine(conf, deployerRunner, verbose)) - eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose)) + eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipSetup)) eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose)) } if testAdmin { diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go index 6813be52b1..f791e1c29b 100644 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go +++ b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go @@ -57,9 +57,8 @@ func bitcoinTestRoutine( txZetaDeposit := bitcoinRunner.DepositZeta() txEtherDeposit := bitcoinRunner.DepositEther(false) txERC20Deposit := bitcoinRunner.DepositERC20() - bitcoinRunner.SetupBitcoinAccount() + bitcoinRunner.SetupBitcoinAccount(true) bitcoinRunner.DepositBTC(true) - bitcoinRunner.SetupZEVMSwapApp() bitcoinRunner.WaitForMinedCCTX(txZetaDeposit) bitcoinRunner.WaitForMinedCCTX(txEtherDeposit) bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go index 82e62ca976..7f2eae6792 100644 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go +++ b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go @@ -56,8 +56,6 @@ func ethereumTestRoutine( ethereumRunner.WaitForMinedCCTX(txZetaDeposit) ethereumRunner.WaitForMinedCCTX(txEtherDeposit) - ethereumRunner.SetupContextApp() - // run ethereum test // Note: due to the extensive block generation in Ethereum localnet, block header test is run first // to make it faster to catch up with the latest block header diff --git a/contrib/localnet/orchestrator/smoketest/runner/accounting.go b/contrib/localnet/orchestrator/smoketest/runner/accounting.go index 8e9dcd0e02..98cad6f2f8 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/accounting.go +++ b/contrib/localnet/orchestrator/smoketest/runner/accounting.go @@ -57,6 +57,7 @@ func (sm *SmokeTestRunner) CheckBtcTSSBalance() error { btcBalance += utxo.Amount } } + zrc20Supply, err := sm.BTCZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err @@ -67,10 +68,15 @@ func (sm *SmokeTestRunner) CheckBtcTSSBalance() error { // #nosec G701 smoketest - always in range if int64(btcBalance*1e8) < (zrc20Supply.Int64() - 10000000) { // #nosec G701 smoketest - always in range - return fmt.Errorf("BTC: TSS Balance (%d) < ZRC20 TotalSupply (%d) ", int64(btcBalance*1e8), zrc20Supply) + return fmt.Errorf( + "BTC: TSS Balance (%d) < ZRC20 TotalSupply (%d)", + int64(btcBalance*1e8), + zrc20Supply.Int64()-10000000, + ) } // #nosec G701 smoketest - always in range - sm.Logger.Info("BTC: Balance (%d) >= ZRC20 TotalSupply (%d)", int64(btcBalance*1e8), zrc20Supply) + sm.Logger.Info("BTC: Balance (%d) >= ZRC20 TotalSupply (%d)", int64(btcBalance*1e8), zrc20Supply.Int64()-10000000) + return nil } diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go b/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go index 10ad22eb7d..1b4a1ce671 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go @@ -11,15 +11,14 @@ import ( "github.com/btcsuite/btcutil" ) -func (sm *SmokeTestRunner) SetupBitcoinAccount() { +func (sm *SmokeTestRunner) SetupBitcoinAccount(initNetwork bool) { sm.Logger.Print("⚙️ setting up Bitcoin account") startTime := time.Now() defer func() { sm.Logger.Print("✅ Bitcoin account setup in %s\n", time.Since(startTime)) }() - btc := sm.BtcRPCClient - _, err := btc.CreateWallet(sm.Name, rpcclient.WithCreateWalletBlank()) + _, err := sm.BtcRPCClient.CreateWallet(sm.Name, rpcclient.WithCreateWalletBlank()) if err != nil { if !strings.Contains(err.Error(), "Database already exists") { panic(err) @@ -28,20 +27,23 @@ func (sm *SmokeTestRunner) SetupBitcoinAccount() { sm.setBtcAddress() - err = btc.ImportAddress(sm.BTCTSSAddress.EncodeAddress()) - if err != nil { - panic(err) - } + if initNetwork { + // import the TSS address + err = sm.BtcRPCClient.ImportAddress(sm.BTCTSSAddress.EncodeAddress()) + if err != nil { + panic(err) + } - // mine some blocks to get some BTC into the deployer address - _, err = btc.GenerateToAddress(101, sm.BTCDeployerAddress, nil) - if err != nil { - panic(err) - } + // mine some blocks to get some BTC into the deployer address + _, err = sm.BtcRPCClient.GenerateToAddress(101, sm.BTCDeployerAddress, nil) + if err != nil { + panic(err) + } - _, err = btc.GenerateToAddress(4, sm.BTCDeployerAddress, nil) - if err != nil { - panic(err) + _, err = sm.BtcRPCClient.GenerateToAddress(4, sm.BTCDeployerAddress, nil) + if err != nil { + panic(err) + } } } diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go index 5a266f3156..4ce1ba196a 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go @@ -115,12 +115,12 @@ func (sm *SmokeTestRunner) SetZEVMContracts() { sm.SystemContract = SystemContract sm.SystemContractAddr = systemContractAddr + // set ZRC20 contracts sm.SetupETHZRC20() sm.SetupBTCZRC20() -} -func (sm *SmokeTestRunner) SetupZEVMSwapApp() { - zevmSwapAppAddr, tx, zevmSwapApp, err := zevmswap.DeployZEVMSwapApp( + // deploy ZEVMSwapApp and ContextApp + zevmSwapAppAddr, txZEVMSwapApp, zevmSwapApp, err := zevmswap.DeployZEVMSwapApp( sm.ZevmAuth, sm.ZevmClient, sm.UniswapV2RouterAddr, @@ -129,25 +129,23 @@ func (sm *SmokeTestRunner) SetupZEVMSwapApp() { if err != nil { panic(err) } - receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + + contextAppAddr, txContextApp, contextApp, err := contextapp.DeployContextApp(sm.ZevmAuth, sm.ZevmClient) + if err != nil { + panic(err) + } + + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, txZEVMSwapApp, sm.Logger, sm.ReceiptTimeout) if receipt.Status != 1 { panic("ZEVMSwapApp deployment failed") } - sm.Logger.Info("ZEVMSwapApp contract address: %s, tx hash: %s", zevmSwapAppAddr.Hex(), tx.Hash().Hex()) sm.ZEVMSwapAppAddr = zevmSwapAppAddr sm.ZEVMSwapApp = zevmSwapApp -} -func (sm *SmokeTestRunner) SetupContextApp() { - contextAppAddr, tx, contextApp, err := contextapp.DeployContextApp(sm.ZevmAuth, sm.ZevmClient) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, txContextApp, sm.Logger, sm.ReceiptTimeout) if receipt.Status != 1 { panic("ContextApp deployment failed") } - sm.Logger.Info("ContextApp contract address: %s, tx hash: %s", contextAppAddr.Hex(), tx.Hash().Hex()) sm.ContextAppAddr = contextAppAddr sm.ContextApp = contextApp } diff --git a/contrib/localnet/orchestrator/start-upgrade.sh b/contrib/localnet/orchestrator/start-upgrade.sh index 1d8c5aa570..f13666aa57 100644 --- a/contrib/localnet/orchestrator/start-upgrade.sh +++ b/contrib/localnet/orchestrator/start-upgrade.sh @@ -47,7 +47,7 @@ fi echo "E2E setup passed, waiting for upgrade height..." # Restart zetaclients at upgrade height -/work/restart-zetaclientd.sh -u 180 -n 2 +/work/restart-zetaclientd.sh -u 200 -n 2 echo "waiting 10 seconds for node to restart..." diff --git a/contrib/localnet/scripts/genesis-stateful.sh b/contrib/localnet/scripts/genesis-stateful.sh index 5099fcfc4a..d9d377f42f 100755 --- a/contrib/localnet/scripts/genesis-stateful.sh +++ b/contrib/localnet/scripts/genesis-stateful.sh @@ -100,12 +100,23 @@ then cat $HOME/.zetacored/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="500000000"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["gov"]["voting_params"]["voting_period"]="100s"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json - # set fungible admin account as admin for fungible token +# set fungible admin account as admin for fungible token zetacored add-genesis-account zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk 100000000000000000000000000azeta zetacored add-genesis-account zeta1n0rn6sne54hv7w2uu93fl48ncyqz97d3kty6sh 100000000000000000000000000azeta # Funds the localnet_gov_admin account cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][0]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][1]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json +# give balance to deployer account to deploy contracts directly on zEVM + zetacored add-genesis-account zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd 100000000000000000000000000azeta +# erc20 tester + zetacored add-genesis-account zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv 100000000000000000000000000azeta +# zeta tester + zetacored add-genesis-account zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer 100000000000000000000000000azeta +# bitcoin tester + zetacored add-genesis-account zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80 100000000000000000000000000azeta +# ethers tester + zetacored add-genesis-account zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga 100000000000000000000000000azeta + # 3. Copy the genesis.json to all the nodes .And use it to create a gentx for every node zetacored gentx operator 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING # Copy host gentx to other nodes @@ -175,7 +186,7 @@ echo if [ $HOSTNAME = "zetacore0" ] then -/root/.zetacored/cosmovisor/genesis/bin/zetacored tx gov submit-legacy-proposal software-upgrade $UpgradeName --from hotkey --deposit 100000000azeta --upgrade-height 180 --title $UpgradeName --description $UpgradeName --keyring-backend test --chain-id $CHAINID --yes --no-validate --fees=200azeta --broadcast-mode block +/root/.zetacored/cosmovisor/genesis/bin/zetacored tx gov submit-legacy-proposal software-upgrade $UpgradeName --from hotkey --deposit 100000000azeta --upgrade-height 200 --title $UpgradeName --description $UpgradeName --keyring-backend test --chain-id $CHAINID --yes --no-validate --fees=200azeta --broadcast-mode block fi sleep 8 diff --git a/contrib/localnet/scripts/genesis.sh b/contrib/localnet/scripts/genesis.sh index 4ed0d22270..93c8833541 100755 --- a/contrib/localnet/scripts/genesis.sh +++ b/contrib/localnet/scripts/genesis.sh @@ -91,12 +91,24 @@ then cat $HOME/.zetacored/config/genesis.json | jq '.app_state["gov"]["voting_params"]["voting_period"]="100s"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["feemarket"]["params"]["min_gas_price"]="10000000000.0000"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json - # set admin account +# set admin account zetacored add-genesis-account zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk 100000000000000000000000000azeta zetacored add-genesis-account zeta1n0rn6sne54hv7w2uu93fl48ncyqz97d3kty6sh 100000000000000000000000000azeta # Funds the localnet_gov_admin account cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][0]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json cat $HOME/.zetacored/config/genesis.json | jq '.app_state["observer"]["params"]["admin_policy"][1]["address"]="zeta1srsq755t654agc0grpxj4y3w0znktrpr9tcdgk"' > $HOME/.zetacored/config/tmp_genesis.json && mv $HOME/.zetacored/config/tmp_genesis.json $HOME/.zetacored/config/genesis.json +# give balance to runner accounts to deploy contracts directly on zEVM +# deployer + zetacored add-genesis-account zeta1uhznv7uzyjq84s3q056suc8pkme85lkvhrz3dd 100000000000000000000000000azeta +# erc20 tester + zetacored add-genesis-account zeta1datate7xmwm4uk032f9rmcu0cwy7ch7kg6y6zv 100000000000000000000000000azeta +# zeta tester + zetacored add-genesis-account zeta1tnp0hvsq4y5mxuhrq9h3jfwulxywpq0ads0rer 100000000000000000000000000azeta +# bitcoin tester + zetacored add-genesis-account zeta19q7czqysah6qg0n4y3l2a08gfzqxydla492v80 100000000000000000000000000azeta +# ethers tester + zetacored add-genesis-account zeta134rakuus43xn63yucgxhn88ywj8ewcv6ezn2ga 100000000000000000000000000azeta + # 3. Copy the genesis.json to all the nodes .And use it to create a gentx for every node zetacored gentx operator 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING --gas-prices 20000000000azeta # Copy host gentx to other nodes diff --git a/x/crosschain/keeper/migrator.go b/x/crosschain/keeper/migrator.go index 30c1274b8a..cfdc1bba94 100644 --- a/x/crosschain/keeper/migrator.go +++ b/x/crosschain/keeper/migrator.go @@ -31,5 +31,5 @@ func (m Migrator) Migrate2to3(ctx sdk.Context) error { // Migrate3to4 migrates the store from consensus version 3 to 4 func (m Migrator) Migrate3to4(ctx sdk.Context) error { - return v4.MigrateStore(ctx, m.crossChainKeeper.zetaObserverKeeper, m.crossChainKeeper.storeKey, m.crossChainKeeper.cdc) + return v4.MigrateStore(ctx, m.crossChainKeeper.zetaObserverKeeper, m.crossChainKeeper) } diff --git a/x/crosschain/migrations/v4/migrate.go b/x/crosschain/migrations/v4/migrate.go index 1d94748fcc..e4b368e44c 100644 --- a/x/crosschain/migrations/v4/migrate.go +++ b/x/crosschain/migrations/v4/migrate.go @@ -13,24 +13,34 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) +// crosschainKeeper is an interface to prevent cyclic dependency +type crosschainKeeper interface { + GetStoreKey() storetypes.StoreKey + GetCodec() codec.Codec + GetAllCrossChainTx(ctx sdk.Context) []types.CrossChainTx + AddFinalizedInbound(ctx sdk.Context, inboundTxHash string, senderChainID int64, height uint64) +} + // MigrateStore migrates the x/crosschain module state from the consensus version 3 to 4 // It initializes the aborted zeta amount to 0 func MigrateStore( ctx sdk.Context, observerKeeper types.ObserverKeeper, - crossChainStoreKey storetypes.StoreKey, - cdc codec.BinaryCodec, + crosschainKeeper crosschainKeeper, ) error { - SetZetaAccounting(ctx, crossChainStoreKey, cdc) - MoveTssToObserverModule(ctx, observerKeeper, crossChainStoreKey, cdc) - MoveNonceToObserverModule(ctx, observerKeeper, crossChainStoreKey, cdc) + SetZetaAccounting(ctx, crosschainKeeper.GetStoreKey(), crosschainKeeper.GetCodec()) + MoveTssToObserverModule(ctx, observerKeeper, crosschainKeeper.GetStoreKey(), crosschainKeeper.GetCodec()) + MoveNonceToObserverModule(ctx, observerKeeper, crosschainKeeper.GetStoreKey(), crosschainKeeper.GetCodec()) + SetBitcoinFinalizedInbound(ctx, crosschainKeeper) + return nil } func SetZetaAccounting( ctx sdk.Context, crossChainStoreKey storetypes.StoreKey, - cdc codec.BinaryCodec) { + cdc codec.BinaryCodec, +) { p := types.KeyPrefix(fmt.Sprintf("%s", types.SendKey)) prefixedStore := prefix.NewStore(ctx.KVStore(crossChainStoreKey), p) abortedAmountZeta := sdkmath.ZeroUint() @@ -124,7 +134,8 @@ func MoveNonceToObserverModule( func MoveTssToObserverModule(ctx sdk.Context, observerKeeper types.ObserverKeeper, crossChainStoreKey storetypes.StoreKey, - cdc codec.BinaryCodec) { + cdc codec.BinaryCodec, +) { // Using New Types from observer module as the structure is the same var tss observertypes.TSS var tssHistory []observertypes.TSS @@ -159,3 +170,21 @@ func MoveTssToObserverModule(ctx sdk.Context, observerKeeper.SetTSS(ctx, tss) } } + +// SetBitcoinFinalizedInbound sets the finalized inbound for bitcoin chains to prevent new ballots from being created with same intxhash +func SetBitcoinFinalizedInbound(ctx sdk.Context, crosschainKeeper crosschainKeeper) { + for _, cctx := range crosschainKeeper.GetAllCrossChainTx(ctx) { + if cctx.InboundTxParams != nil { + // check if bitcoin inbound + if common.IsBitcoinChain(cctx.InboundTxParams.SenderChainId) { + // add finalized inbound + crosschainKeeper.AddFinalizedInbound( + ctx, + cctx.InboundTxParams.InboundTxObservedHash, + cctx.InboundTxParams.SenderChainId, + 0, + ) + } + } + } +} diff --git a/x/crosschain/migrations/v4/migrate_test.go b/x/crosschain/migrations/v4/migrate_test.go index eb119873e1..5ff2f9ee54 100644 --- a/x/crosschain/migrations/v4/migrate_test.go +++ b/x/crosschain/migrations/v4/migrate_test.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -23,7 +24,7 @@ func TestMigrateStore(t *testing.T) { t.Run("test migrate store add zeta accounting", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) amountZeta := SetRandomCctx(ctx, *k) - err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k.GetStoreKey(), k.GetCodec()) + err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k) assert.NoError(t, err) zetaAccounting, found := k.GetZetaAccounting(ctx) assert.True(t, found) @@ -44,7 +45,7 @@ func TestMigrateStore(t *testing.T) { store.Set(observertypes.KeyPrefix(fmt.Sprintf("%d", tss1.FinalizedZetaHeight)), tss1Bytes) store.Set(observertypes.KeyPrefix(fmt.Sprintf("%d", tss2.FinalizedZetaHeight)), tss2Bytes) - err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k.GetStoreKey(), k.GetCodec()) + err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k) assert.NoError(t, err) tss, found := zk.ObserverKeeper.GetTSS(ctx) @@ -72,7 +73,7 @@ func TestMigrateStore(t *testing.T) { for _, nonce := range nonceToCctxList { store.Set(types.KeyPrefix(fmt.Sprintf("%s-%d-%d", nonce.Tss, nonce.ChainId, nonce.Nonce)), k.GetCodec().MustMarshal(&nonce)) } - err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k.GetStoreKey(), k.GetCodec()) + err := v4.MigrateStore(ctx, k.GetObserverKeeper(), k) assert.NoError(t, err) pn, err := k.GetObserverKeeper().GetAllPendingNonces(ctx) assert.NoError(t, err) @@ -85,6 +86,75 @@ func TestMigrateStore(t *testing.T) { assert.Equal(t, pendingNonces, pn) assert.Equal(t, chainNonces, k.GetObserverKeeper().GetAllChainNonces(ctx)) assert.Equal(t, nonceToCctxList, k.GetObserverKeeper().GetAllNonceToCctx(ctx)) + }) +} + +func TestSetBitcoinFinalizedInbound(t *testing.T) { + t.Run("test setting finalized inbound for Bitcoin", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + + // set some cctxs with Bitcoin and non-Bitcoin chains + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "0", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.GoerliChain().ChainId, + InboundTxObservedHash: "0xaaa", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "1", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.BtcMainnetChain().ChainId, + InboundTxObservedHash: "0x111", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "2", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.EthChain().ChainId, + InboundTxObservedHash: "0xbbb", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "3", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.BtcTestNetChain().ChainId, + InboundTxObservedHash: "0x222", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "4", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.BtcTestNetChain().ChainId, + InboundTxObservedHash: "0x333", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "5", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.MumbaiChain().ChainId, + InboundTxObservedHash: "0xccc", + }, + }) + k.SetCrossChainTx(ctx, types.CrossChainTx{ + Index: "6", + InboundTxParams: &types.InboundTxParams{ + SenderChainId: common.BtcRegtestChain().ChainId, + InboundTxObservedHash: "0x444", + }, + }) + + // migration + v4.SetBitcoinFinalizedInbound(ctx, k) + + // check finalized inbound + require.False(t, k.IsFinalizedInbound(ctx, "0xaaa", common.GoerliChain().ChainId, 0)) + require.False(t, k.IsFinalizedInbound(ctx, "0xbbb", common.EthChain().ChainId, 0)) + require.False(t, k.IsFinalizedInbound(ctx, "0xccc", common.MumbaiChain().ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x111", common.BtcMainnetChain().ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x222", common.BtcTestNetChain().ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x333", common.BtcTestNetChain().ChainId, 0)) + require.True(t, k.IsFinalizedInbound(ctx, "0x444", common.BtcRegtestChain().ChainId, 0)) }) } diff --git a/x/observer/keeper/migrator.go b/x/observer/keeper/migrator.go index e256358d87..47b8ecfcc7 100644 --- a/x/observer/keeper/migrator.go +++ b/x/observer/keeper/migrator.go @@ -35,5 +35,5 @@ func (m Migrator) Migrate3to4(ctx sdk.Context) error { } func (m Migrator) Migrate4to5(ctx sdk.Context) error { - return v5.MigrateStore(ctx, m.observerKeeper.storeKey, m.observerKeeper.cdc) + return v5.MigrateStore(ctx, m.observerKeeper) } diff --git a/x/observer/migrations/v4/migrate.go b/x/observer/migrations/v4/migrate.go index a23cc28dd5..7444c46233 100644 --- a/x/observer/migrations/v4/migrate.go +++ b/x/observer/migrations/v4/migrate.go @@ -19,10 +19,7 @@ type observerKeeper interface { } func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error { - if err := MigrateCrosschainFlags(ctx, observerKeeper.StoreKey(), observerKeeper.Codec()); err != nil { - return err - } - return MigrateObserverParams(ctx, observerKeeper) + return MigrateCrosschainFlags(ctx, observerKeeper.StoreKey(), observerKeeper.Codec()) } func MigrateCrosschainFlags(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { @@ -45,31 +42,3 @@ func MigrateCrosschainFlags(ctx sdk.Context, observerStoreKey storetypes.StoreKe store.Set([]byte{0}, b) return nil } - -// MigrateObserverParams migrates the observer params to the chain params -// the function assumes that each oberver params entry has a corresponding chain params entry -// if the chain is not found, the observer params entry is ignored because it is considered as not supported -func MigrateObserverParams(ctx sdk.Context, observerKeeper observerKeeper) error { - chainParamsList, found := observerKeeper.GetChainParamsList(ctx) - if !found { - // no chain params found, nothing to migrate - return nil - } - - // search for the observer params with chain params entry - observerParams := observerKeeper.GetParams(ctx).ObserverParams - for _, observerParam := range observerParams { - for i := range chainParamsList.ChainParams { - // if the chain is found, update the chain params with the observer params - if chainParamsList.ChainParams[i].ChainId == observerParam.Chain.ChainId { - chainParamsList.ChainParams[i].MinObserverDelegation = observerParam.MinObserverDelegation - chainParamsList.ChainParams[i].BallotThreshold = observerParam.BallotThreshold - chainParamsList.ChainParams[i].IsSupported = observerParam.IsSupported - break - } - } - } - - observerKeeper.SetChainParamsList(ctx, chainParamsList) - return nil -} diff --git a/x/observer/migrations/v4/migrate_test.go b/x/observer/migrations/v4/migrate_test.go index 3a64fd97ab..b7d025fa60 100644 --- a/x/observer/migrations/v4/migrate_test.go +++ b/x/observer/migrations/v4/migrate_test.go @@ -4,12 +4,8 @@ import ( "testing" "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/testutil/sample" v4 "github.com/zeta-chain/zetacore/x/observer/migrations/v4" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -33,75 +29,3 @@ func TestMigrateCrosschainFlags(t *testing.T) { assert.True(t, flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled) assert.True(t, flags.BlockHeaderVerificationFlags.IsEthTypeChainEnabled) } - -func TestMigrateObserverParams(t *testing.T) { - k, ctx := keepertest.ObserverKeeper(t) - - // set chain params - previousChainParamsList := types.ChainParamsList{ - ChainParams: []*types.ChainParams{ - sample.ChainParams(1), - sample.ChainParams(2), - sample.ChainParams(3), - sample.ChainParams(4), - }, - } - k.SetChainParamsList(ctx, previousChainParamsList) - - // set observer params - dec42, err := sdk.NewDecFromStr("0.42") - require.NoError(t, err) - dec43, err := sdk.NewDecFromStr("0.43") - require.NoError(t, err) - dec1000, err := sdk.NewDecFromStr("1000.0") - require.NoError(t, err) - dec1001, err := sdk.NewDecFromStr("1001.0") - require.NoError(t, err) - params := types.Params{ - ObserverParams: []*types.ObserverParams{ - { - Chain: &common.Chain{ChainId: 2}, - BallotThreshold: dec42, - MinObserverDelegation: dec1000, - IsSupported: true, - }, - { - Chain: &common.Chain{ChainId: 3}, - BallotThreshold: dec43, - MinObserverDelegation: dec1001, - IsSupported: true, - }, - }, - } - k.SetParams(ctx, params) - - // perform migration - err = v4.MigrateObserverParams(ctx, *k) - require.NoError(t, err) - - // check chain params - newChainParamsList, found := k.GetChainParamsList(ctx) - require.True(t, found) - - // unchanged values - require.EqualValues(t, previousChainParamsList.ChainParams[0], newChainParamsList.ChainParams[0]) - require.EqualValues(t, previousChainParamsList.ChainParams[3], newChainParamsList.ChainParams[3]) - - // changed values - require.EqualValues(t, dec42, newChainParamsList.ChainParams[1].BallotThreshold) - require.EqualValues(t, dec1000, newChainParamsList.ChainParams[1].MinObserverDelegation) - require.EqualValues(t, dec43, newChainParamsList.ChainParams[2].BallotThreshold) - require.EqualValues(t, dec1001, newChainParamsList.ChainParams[2].MinObserverDelegation) - require.True(t, newChainParamsList.ChainParams[1].IsSupported) - require.True(t, newChainParamsList.ChainParams[2].IsSupported) - - // check remaining values are unchanged - previousChainParamsList.ChainParams[1].BallotThreshold = dec42 - previousChainParamsList.ChainParams[2].BallotThreshold = dec43 - previousChainParamsList.ChainParams[1].MinObserverDelegation = dec1000 - previousChainParamsList.ChainParams[2].MinObserverDelegation = dec1001 - previousChainParamsList.ChainParams[1].IsSupported = true - previousChainParamsList.ChainParams[2].IsSupported = true - require.EqualValues(t, previousChainParamsList.ChainParams[1], newChainParamsList.ChainParams[1]) - require.EqualValues(t, previousChainParamsList.ChainParams[2], newChainParamsList.ChainParams[2]) -} diff --git a/x/observer/migrations/v5/migrate.go b/x/observer/migrations/v5/migrate.go index a5666ff43b..a626ce192b 100644 --- a/x/observer/migrations/v5/migrate.go +++ b/x/observer/migrations/v5/migrate.go @@ -8,7 +8,24 @@ import ( "github.com/zeta-chain/zetacore/x/observer/types" ) -func MigrateStore(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { +// observerKeeper prevents circular dependency +type observerKeeper interface { + GetParams(ctx sdk.Context) types.Params + SetParams(ctx sdk.Context, params types.Params) + GetChainParamsList(ctx sdk.Context) (params types.ChainParamsList, found bool) + SetChainParamsList(ctx sdk.Context, params types.ChainParamsList) + StoreKey() storetypes.StoreKey + Codec() codec.BinaryCodec +} + +func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error { + if err := MigrateObserverMapper(ctx, observerKeeper.StoreKey(), observerKeeper.Codec()); err != nil { + return err + } + return MigrateObserverParams(ctx, observerKeeper) +} + +func MigrateObserverMapper(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc codec.BinaryCodec) error { var legacyObserverMappers []*types.ObserverMapper legacyObserverMapperStore := prefix.NewStore(ctx.KVStore(observerStoreKey), types.KeyPrefix(types.ObserverMapperKey)) iterator := sdk.KVStorePrefixIterator(legacyObserverMapperStore, []byte{}) @@ -35,3 +52,31 @@ func MigrateStore(ctx sdk.Context, observerStoreKey storetypes.StoreKey, cdc cod } return nil } + +// MigrateObserverParams migrates the observer params to the chain params +// the function assumes that each observer params entry has a corresponding chain params entry +// if the chain is not found, the observer params entry is ignored because it is considered as not supported +func MigrateObserverParams(ctx sdk.Context, observerKeeper observerKeeper) error { + chainParamsList, found := observerKeeper.GetChainParamsList(ctx) + if !found { + // no chain params found, nothing to migrate + return nil + } + + // search for the observer params with chain params entry + observerParams := observerKeeper.GetParams(ctx).ObserverParams + for _, observerParam := range observerParams { + for i := range chainParamsList.ChainParams { + // if the chain is found, update the chain params with the observer params + if chainParamsList.ChainParams[i].ChainId == observerParam.Chain.ChainId { + chainParamsList.ChainParams[i].MinObserverDelegation = observerParam.MinObserverDelegation + chainParamsList.ChainParams[i].BallotThreshold = observerParam.BallotThreshold + chainParamsList.ChainParams[i].IsSupported = observerParam.IsSupported + break + } + } + } + + observerKeeper.SetChainParamsList(ctx, chainParamsList) + return nil +} diff --git a/x/observer/migrations/v5/migrate_test.go b/x/observer/migrations/v5/migrate_test.go index 61e2c86739..d97b3dde69 100644 --- a/x/observer/migrations/v5/migrate_test.go +++ b/x/observer/migrations/v5/migrate_test.go @@ -6,13 +6,15 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" v5 "github.com/zeta-chain/zetacore/x/observer/migrations/v5" "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestMigrateStore(t *testing.T) { +func TestMigrateObserverMapper(t *testing.T) { t.Run("TestMigrateStore", func(t *testing.T) { k, ctx := keepertest.ObserverKeeper(t) legacyObserverMapperStore := prefix.NewStore(ctx.KVStore(k.StoreKey()), types.KeyPrefix(types.ObserverMapperKey)) @@ -20,7 +22,7 @@ func TestMigrateStore(t *testing.T) { for _, legacyObserverMapper := range legacyObserverMapperList { legacyObserverMapperStore.Set(types.KeyPrefix(legacyObserverMapper.Index), k.Codec().MustMarshal(legacyObserverMapper)) } - err := v5.MigrateStore(ctx, k.StoreKey(), k.Codec()) + err := v5.MigrateObserverMapper(ctx, k.StoreKey(), k.Codec()) assert.NoError(t, err) observerSet, found := k.GetObserverSet(ctx) assert.True(t, found) @@ -40,3 +42,75 @@ func TestMigrateStore(t *testing.T) { assert.Equal(t, 0, len(observerMappers)) }) } + +func TestMigrateObserverParams(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + + // set chain params + previousChainParamsList := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + sample.ChainParams(1), + sample.ChainParams(2), + sample.ChainParams(3), + sample.ChainParams(4), + }, + } + k.SetChainParamsList(ctx, previousChainParamsList) + + // set observer params + dec42, err := sdk.NewDecFromStr("0.42") + require.NoError(t, err) + dec43, err := sdk.NewDecFromStr("0.43") + require.NoError(t, err) + dec1000, err := sdk.NewDecFromStr("1000.0") + require.NoError(t, err) + dec1001, err := sdk.NewDecFromStr("1001.0") + require.NoError(t, err) + params := types.Params{ + ObserverParams: []*types.ObserverParams{ + { + Chain: &common.Chain{ChainId: 2}, + BallotThreshold: dec42, + MinObserverDelegation: dec1000, + IsSupported: true, + }, + { + Chain: &common.Chain{ChainId: 3}, + BallotThreshold: dec43, + MinObserverDelegation: dec1001, + IsSupported: true, + }, + }, + } + k.SetParams(ctx, params) + + // perform migration + err = v5.MigrateObserverParams(ctx, *k) + require.NoError(t, err) + + // check chain params + newChainParamsList, found := k.GetChainParamsList(ctx) + require.True(t, found) + + // unchanged values + require.EqualValues(t, previousChainParamsList.ChainParams[0], newChainParamsList.ChainParams[0]) + require.EqualValues(t, previousChainParamsList.ChainParams[3], newChainParamsList.ChainParams[3]) + + // changed values + require.EqualValues(t, dec42, newChainParamsList.ChainParams[1].BallotThreshold) + require.EqualValues(t, dec1000, newChainParamsList.ChainParams[1].MinObserverDelegation) + require.EqualValues(t, dec43, newChainParamsList.ChainParams[2].BallotThreshold) + require.EqualValues(t, dec1001, newChainParamsList.ChainParams[2].MinObserverDelegation) + require.True(t, newChainParamsList.ChainParams[1].IsSupported) + require.True(t, newChainParamsList.ChainParams[2].IsSupported) + + // check remaining values are unchanged + previousChainParamsList.ChainParams[1].BallotThreshold = dec42 + previousChainParamsList.ChainParams[2].BallotThreshold = dec43 + previousChainParamsList.ChainParams[1].MinObserverDelegation = dec1000 + previousChainParamsList.ChainParams[2].MinObserverDelegation = dec1001 + previousChainParamsList.ChainParams[1].IsSupported = true + previousChainParamsList.ChainParams[2].IsSupported = true + require.EqualValues(t, previousChainParamsList.ChainParams[1], newChainParamsList.ChainParams[1]) + require.EqualValues(t, previousChainParamsList.ChainParams[2], newChainParamsList.ChainParams[2]) +} diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 39649a0307..a316e3b4ac 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -451,9 +451,9 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 } else if inMempool { // still in mempool (should avoid unnecessary Tss keysign) ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: outTx %s is still in mempool", outTxID) return true, false, nil - } else { // included - ob.setIncludedTx(nonce, txResult) } + // included + ob.setIncludedTx(nonce, txResult) // Get tx result again in case it is just included res = ob.getIncludedTx(nonce) diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index f9faf1d9a2..f015f2df85 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -6,18 +6,17 @@ import ( "strconv" "strings" - "github.com/zeta-chain/zetacore/cmd/zetacored/config" - - "github.com/zeta-chain/zetacore/common/cosmos" - "github.com/zeta-chain/zetacore/zetaclient/hsm" - "github.com/cosmos/cosmos-sdk/client" clienttx "github.com/cosmos/cosmos-sdk/client/tx" sdktypes "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" flag "github.com/spf13/pflag" rpchttp "github.com/tendermint/tendermint/rpc/client/http" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/zeta-chain/zetacore/common/cosmos" + "github.com/zeta-chain/zetacore/zetaclient/hsm" ) const ( @@ -182,3 +181,12 @@ func (b *ZetaCoreBridge) SignTx( } return clienttx.Sign(txf, name, txBuilder, overwriteSig) } + +// QueryTxResult query the result of a tx +func (b *ZetaCoreBridge) QueryTxResult(hash string) (*sdktypes.TxResponse, error) { + ctx, err := b.GetContext() + if err != nil { + return nil, err + } + return authtx.QueryTx(ctx, hash) +} diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 218ac9d9a6..38a02052ed 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -3,6 +3,7 @@ package zetaclient import ( "fmt" "math/big" + "strings" "time" "cosmossdk.io/math" @@ -144,6 +145,9 @@ func (b *ZetaCoreBridge) PostSend(zetaGasLimit uint64, msg *types.MsgVoteOnObser for i := 0; i < DefaultRetryCount; i++ { zetaTxHash, err := b.Broadcast(zetaGasLimit, authzMsg, authzSigner) if err == nil { + // monitor the result of the transaction + go b.MonitorTxResult(zetaTxHash, true) + return zetaTxHash, ballotIndex, nil } b.logger.Debug().Err(err).Msgf("PostSend broadcast fail | Retry count : %d", i+1) @@ -205,6 +209,9 @@ func (b *ZetaCoreBridge) PostReceiveConfirmation( for i := 0; i < DefaultRetryCount; i++ { zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) if err == nil { + // monitor the result of the transaction + go b.MonitorTxResult(zetaTxHash, true) + return zetaTxHash, ballotIndex, nil } b.logger.Debug().Err(err).Msgf("PostReceive broadcast fail | Retry count : %d", i+1) @@ -301,3 +308,40 @@ func (b *ZetaCoreBridge) PostAddBlockHeader(chainID int64, blockHash []byte, hei } return "", fmt.Errorf("post add block header failed after %d retries", DefaultRetryCount) } + +// MonitorTxResult monitors the result of a tx (used for inbound and outbound vote txs) +func (b *ZetaCoreBridge) MonitorTxResult(zetaTxHash string, isInbound bool) { + var lastErr error + ticker := 5 * time.Second + retry := 10 + prefix := "MonitorOutboundTxResult" + if isInbound { + prefix = "MonitorInboundTxResult" + } + + for i := 0; i < retry; i++ { + time.Sleep(ticker) + txResult, err := b.QueryTxResult(zetaTxHash) + if err == nil { + // the inbound vote tx shouldn't fail to execute + if strings.Contains(txResult.RawLog, "failed to execute message") { + b.logger.Error().Msgf( + "%s: failed to execute vote, txHash: %s, txResult %s", + prefix, + zetaTxHash, + txResult.String(), + ) + } + return + } + lastErr = err + } + + b.logger.Error().Err(lastErr).Msgf( + "%s: unable to query tx result for txHash %s, err %s", + prefix, + zetaTxHash, + lastErr.Error(), + ) + return +} From ebcdafc1883b391faca3ba680f36c667903b59f1 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Fri, 12 Jan 2024 17:10:20 -0800 Subject: [PATCH 34/67] fix(`crosschain`): remove `decreaseAllowance` and `increaseAllowance` checks (#1557) * remove check * changelog * fix goimport --- changelog.md | 1 + x/crosschain/keeper/evm_hooks.go | 25 ------------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index 860a46e6db..b1f1596e69 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses +* [1557](https://github.com/zeta-chain/node/pull/1557) - remove decreaseAllowance and increaseAllowance checks * [1536](https://github.com/zeta-chain/node/pull/1536) - add index to check previously finalized inbounds * [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing * [1546](https://github.com/zeta-chain/node/pull/1546) - fix reset of pending nonces on genesis import diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index f2b9f6bc8d..5b896473a8 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -1,17 +1,14 @@ package keeper import ( - "bytes" "encoding/hex" "fmt" "math/big" - "strings" errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" "github.com/btcsuite/btcutil" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -21,7 +18,6 @@ import ( zrc20 "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types" @@ -49,27 +45,6 @@ func (k Keeper) PostTxProcessing( msg core.Message, receipt *ethtypes.Receipt, ) error { - abiStr := "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"}," + - "{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"chainid_\",\"type\":\"uint256\"},{\"internalType\":\"enumCoinType\",\"name\":\"coinType_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit_\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"systemContractAddress_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerIsNotFungibleModule\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasFeeTransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LowBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasCoin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroGasPrice\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"UpdatedGasLimit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedProtocolFlatFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"systemContract\",\"type\":\"address\"}],\"name\":\"UpdatedSystemContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasfee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CHAIN_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"COIN_TYPE\",\"outputs\":[{\"internalType\":\"enumCoinType\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FUNGIBLE_MODULE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GAS_LIMIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PROTOCOL_FLAT_FEE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONTRACT_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"}],\"name\":\"updateGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"protocolFlatFee\",\"type\":\"uint256\"}],\"name\":\"updateProtocolFlatFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"updateSystemContractAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawGasFee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" - - inputData := msg.Data() - if len(inputData) >= 4 { - // Check if method exist in ABI - methodID := inputData[:4] - parsedABI, err := abi.JSON(strings.NewReader(abiStr)) - if err != nil { - return err - } - for _, method := range parsedABI.Methods { - if bytes.Equal(methodID, method.ID) { - // Check if deactivated method - if method.Name == "increaseAllowance" || method.Name == "decreaseAllowance" { - return fmt.Errorf("%s not allowed", method.Name) - } - } - } - } - var emittingContract ethcommon.Address if msg.To() != nil { emittingContract = *msg.To() From 6dc68a52977a9abc53ebfe72dd9ce1b718368285 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Mon, 15 Jan 2024 11:31:44 -0800 Subject: [PATCH 35/67] chore: v12.0.0 changelog (#1578) --- changelog.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index b1f1596e69..3c8acacc3c 100644 --- a/changelog.md +++ b/changelog.md @@ -2,12 +2,14 @@ ## Unreleased +## Version: v12.0.0 + ### Breaking Changes TSS and chain validation related queries have been moved from `crosschain` module to `observer` module: * `PendingNonces` :Changed from `/zeta-chain/crosschain/pendingNonces/{chain_id}/{address}` to `/zeta-chain/observer/pendingNonces/{chain_id}/{address}` . It returns all the pending nonces for a chain id and address. This returns the current pending nonces for the chain. -* `ChainNonces` : Changed from `/zeta-chain/crosschain/chainNonces/{chain_id}` to`/zeta-chain/observer/chainNonces/{chain_id}` . It returns all the chain nonces for a chain id. This returns the current nonce oof the TSS address for the chain. -* `ChainNoncesAll` :Changed from `/zeta-chain/observer/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. +* `ChainNonces` : Changed from `/zeta-chain/crosschain/chainNonces/{chain_id}` to`/zeta-chain/observer/chainNonces/{chain_id}` . It returns all the chain nonces for a chain id. This returns the current nonce of the TSS address for the chain. +* `ChainNoncesAll` :Changed from `/zeta-chain/crosschain/chainNonces` to `/zeta-chain/observer/chainNonces` . It returns all the chain nonces for all chains. This returns the current nonce of the TSS address for all chains. All chains now have the same observer set: * `ObserversByChain`: `/zeta-chain/observer/observers_by_chain/{observation_chain}` has been removed and replaced with `/zeta-chain/observer/observer_set`. All chains have the same observer set. @@ -19,7 +21,7 @@ Observer params and core params have been merged into chain params: * `GetCoreParamsByChain`: Renamed into `GetChainParamsForChain`. `/zeta-chain/observer/get_core_params_by_chain` moved to `/zeta-chain/observer/get_chain_params_by_chain`. Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin chain id: -* `GetTssAddress` : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoing chain id can now now passed as a parameter to fetch the correct tss for required BTC chain.This parameter only affects the BTC tss address in the response. +* `GetTssAddress` : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoin chain id can now be passed as a parameter to fetch the correct tss for required BTC chain. This parameter only affects the BTC tss address in the response. ### Features From a0e4f6269176f02a6f83ff49bf04a3cc6146e913 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:49:25 -0600 Subject: [PATCH 36/67] fix: skip unsupported chain parameters (#1581) Co-authored-by: Lucas Bertrand --- changelog.md | 1 + zetaclient/zetacore_bridge.go | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index 3c8acacc3c..56dd363d05 100644 --- a/changelog.md +++ b/changelog.md @@ -35,6 +35,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c ### Fixes +* [1575](https://github.com/zeta-chain/node/issues/1575) - Skip unsupported chain parameters by IsSupported flag * [1554](https://github.com/zeta-chain/node/pull/1554) - Screen out unconfirmed UTXOs that are not created by TSS itself * [1560](https://github.com/zeta-chain/node/issues/1560) - Zetaclient post evm-chain outtx hashes only when receipt is available * [1516](https://github.com/zeta-chain/node/issues/1516) - Unprivileged outtx tracker removal diff --git a/zetaclient/zetacore_bridge.go b/zetaclient/zetacore_bridge.go index 0a2b3b08c4..bf4466565c 100644 --- a/zetaclient/zetacore_bridge.go +++ b/zetaclient/zetacore_bridge.go @@ -196,7 +196,8 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err return err } if plan != nil && bn == plan.Height-1 { // stop zetaclients; notify operator to upgrade and restart - b.logger.Warn().Msgf("Active upgrade plan detected and upgrade height reached: %s at height %d; ZetaClient is stopped; please kill this process, replace zetaclientd binary with upgraded version, and restart zetaclientd", plan.Name, plan.Height) + b.logger.Warn().Msgf("Active upgrade plan detected and upgrade height reached: %s at height %d; ZetaClient is stopped;"+ + "please kill this process, replace zetaclientd binary with upgraded version, and restart zetaclientd", plan.Name, plan.Height) b.pause <- struct{}{} // notify CoreObserver to stop ChainClients, Signers, and CoreObservder itself } @@ -212,14 +213,16 @@ func (b *ZetaCoreBridge) UpdateConfigFromCore(cfg *config.Config, init bool) err for _, chainParam := range chainParams { err := config.ValidateChainParams(chainParam) if err != nil { - b.logger.Debug().Err(err).Msgf( - "Invalid core params for chain %s", - common.GetChainFromChainID(chainParam.ChainId).ChainName, - ) + b.logger.Warn().Err(err).Msgf("Invalid chain params for chain %d", chainParam.ChainId) + continue + } + if !chainParam.GetIsSupported() { + b.logger.Info().Msgf("Chain %d is not supported yet", chainParam.ChainId) + continue } if common.IsBitcoinChain(chainParam.ChainId) { newBTCParams = chainParam - } else { + } else if common.IsEVMChain(chainParam.ChainId) { newEVMParams[chainParam.ChainId] = chainParam } } From 9a4608094448b8391a48226fcf14266c31a17709 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 16 Jan 2024 21:35:19 -0600 Subject: [PATCH 37/67] fix: avoid voting on wrong ballots due to false blockNumber in EVM tx receipt (#1570) * avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * update changelog --- changelog.md | 6 ++++++ zetaclient/evm_client.go | 39 +++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/changelog.md b/changelog.md index 56dd363d05..c943df84bf 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,12 @@ ## Unreleased +### Features + +### Fixes + +* [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt + ## Version: v12.0.0 ### Breaking Changes diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 8a68ac121e..d88ee980f9 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -59,7 +59,7 @@ type EVMLog struct { const ( DonationMessage = "I am rich!" TopicsZetaSent = 3 // [signature, zetaTxSenderAddress, destinationChainId] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L34 - TopicsZetaReceived = 4 // [signature, sourceChainId, destinationAddress] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L45 + TopicsZetaReceived = 4 // [signature, sourceChainId, destinationAddress, internalSendHash] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L45 TopicsZetaReverted = 3 // [signature, destinationChainId, internalSendHash] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ZetaConnector.base.sol#L54 TopicsWithdrawn = 3 // [signature, recipient, asset] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L43 TopicsDeposited = 2 // [signature, asset] https://github.com/zeta-chain/protocol-contracts/blob/d65814debf17648a6c67d757ba03646415842790/contracts/evm/ERC20Custody.sol#L42 @@ -721,14 +721,29 @@ func (ob *EVMChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtyp return nil, nil, false } - // check confirmations - confHeight := receipt.BlockNumber.Uint64() + ob.GetChainParams().ConfirmationCount - if confHeight >= math.MaxInt64 { - log.Error().Msgf("confirmTxByHash: confHeight is too large for txHash %s nonce %d", txHash, nonce) + // cross-check receipt against the block + block, err := ob.GetBlockByNumberCached(receipt.BlockNumber.Uint64()) + if err != nil { + log.Error().Err(err).Msgf("confirmTxByHash: GetBlockByNumberCached error, txHash %s nonce %d block %d", + txHash, nonce, receipt.BlockNumber) + return nil, nil, false + } + // #nosec G701 non negative value + if receipt.TransactionIndex >= uint(len(block.Transactions())) { + log.Error().Msgf("confirmTxByHash: transaction index %d out of range [0, %d), txHash %s nonce %d block %d", + receipt.TransactionIndex, len(block.Transactions()), txHash, nonce, receipt.BlockNumber) return nil, nil, false } - if confHeight > ob.GetLastBlockHeight() { - log.Info().Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", + txAtIndex := block.Transactions()[receipt.TransactionIndex] + if txAtIndex.Hash() != transaction.Hash() { + log.Error().Msgf("confirmTxByHash: transaction at index %d has different hash %s, txHash %s nonce %d block %d", + receipt.TransactionIndex, txAtIndex.Hash().Hex(), txHash, nonce, receipt.BlockNumber) + 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 } @@ -848,11 +863,11 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { } // get and update latest block height - header, err := ob.evmClient.HeaderByNumber(context.Background(), nil) + blockNumber, err := ob.evmClient.BlockNumber(context.Background()) if err != nil { return err } - ob.SetLastBlockHeight(header.Number.Uint64()) + ob.SetLastBlockHeight(blockNumber) // increment prom counter counter, err := ob.GetPromCounter("rpc_getBlockByNumber_count") @@ -862,10 +877,10 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { counter.Inc() // skip if current height is too low - if header.Number.Uint64() < ob.GetChainParams().ConfirmationCount { - return fmt.Errorf("observeInTX: skipping observer, current block number %d is too low", header.Number.Uint64()) + if blockNumber < ob.GetChainParams().ConfirmationCount { + return fmt.Errorf("observeInTX: skipping observer, current block number %d is too low", blockNumber) } - confirmedBlockNum := header.Number.Uint64() - ob.GetChainParams().ConfirmationCount + confirmedBlockNum := blockNumber - ob.GetChainParams().ConfirmationCount // skip if no new block is confirmed lastScanned := ob.GetLastBlockHeightScanned() From b7867ec2bd74c484bfde2a6027d170a83c81618d Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Tue, 16 Jan 2024 20:19:46 -0800 Subject: [PATCH 38/67] fix: zetaclient crash due to out of bound int conversion (#1576) * fix crash due to out of bound * use GetLastBlockHeightScanned() instead * fixed ChainParams equality check and added changelog entry --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Co-authored-by: Charlie Chen --- changelog.md | 1 + zetaclient/bitcoin_client.go | 2 +- zetaclient/zetacore_observer.go | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index c943df84bf..120b77cfd3 100644 --- a/changelog.md +++ b/changelog.md @@ -41,6 +41,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c ### Fixes +* [1576](https://github.com/zeta-chain/node/pull/1576) - Fix zetaclient crash due to out of bound integer conversion and log prints. * [1575](https://github.com/zeta-chain/node/issues/1575) - Skip unsupported chain parameters by IsSupported flag * [1554](https://github.com/zeta-chain/node/pull/1554) - Screen out unconfirmed UTXOs that are not created by TSS itself * [1560](https://github.com/zeta-chain/node/issues/1560) - Zetaclient post evm-chain outtx hashes only when receipt is available diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index a316e3b4ac..a82e3a44cb 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -1326,7 +1326,7 @@ func (ob *BitcoinChainClient) LoadLastBlock() error { if ob.chain.ChainId == 18444 { // bitcoin regtest: start from block 100 ob.SetLastBlockHeightScanned(100) } - ob.logger.ChainLogger.Info().Msgf("%s: start scanning from block %d", ob.chain.String(), ob.lastBlock) + ob.logger.ChainLogger.Info().Msgf("%s: start scanning from block %d", ob.chain.String(), ob.GetLastBlockHeightScanned()) return nil } diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 51078aefd2..aff055c74f 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -2,6 +2,7 @@ package zetaclient import ( "fmt" + "math" "strings" "time" @@ -158,7 +159,7 @@ func (co *CoreObserver) startCctxScheduler() { co.logger.ZetaChainWatcher.Error().Err(err).Msgf("couldn't get operator balance") } else { diff := co.lastOperatorBalance.Sub(balance) - if diff.GT(sdkmath.NewInt(0)) { + if diff.GT(sdkmath.NewInt(0)) && diff.LT(sdkmath.NewInt(math.MaxInt64)) { co.ts.AddFeeEntry(bn, diff.Int64()) co.lastOperatorBalance = balance } @@ -355,7 +356,7 @@ func (co *CoreObserver) getUpdatedChainOb(chainID int64) (ChainClient, error) { curParams := chainOb.GetChainParams() if common.IsEVMChain(chainID) { evmCfg, found := co.cfg.GetEVMConfig(chainID) - if found && curParams != evmCfg.ChainParams { + if found && curParams.String() != evmCfg.ChainParams.String() { chainOb.SetChainParams(evmCfg.ChainParams) co.logger.ZetaChainWatcher.Info().Msgf( "updated chain params for chainID %d, new params: %v", @@ -365,7 +366,7 @@ func (co *CoreObserver) getUpdatedChainOb(chainID int64) (ChainClient, error) { } } else if common.IsBitcoinChain(chainID) { _, btcCfg, found := co.cfg.GetBTCConfig() - if found && curParams != btcCfg.ChainParams { + if found && curParams.String() != btcCfg.ChainParams.String() { chainOb.SetChainParams(btcCfg.ChainParams) co.logger.ZetaChainWatcher.Info().Msgf( "updated chain params for Bitcoin, new params: %v", From 84502dcfca3c95efe0d1e978f868d04a5de7244f Mon Sep 17 00:00:00 2001 From: Charlie <31941002+CharlieMc0@users.noreply.github.com> Date: Tue, 16 Jan 2024 23:31:19 -0700 Subject: [PATCH 39/67] chore: update ledger dependencies(#1590) --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 942af7d565..aff1f815c3 100644 --- a/go.mod +++ b/go.mod @@ -147,7 +147,7 @@ require ( github.com/cosmos/gogoproto v1.4.7 github.com/cosmos/iavl v0.19.6 // indirect github.com/cosmos/ibc-go/v6 v6.1.0 - github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 @@ -293,8 +293,8 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect gitlab.com/thorchain/binance-sdk v1.2.3-0.20210117202539-d569b6b9ba5d // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.11.0 // indirect diff --git a/go.sum b/go.sum index 6d1e76aba3..96ac6b81eb 100644 --- a/go.sum +++ b/go.sum @@ -1043,8 +1043,8 @@ github.com/cosmos/iavl v0.19.6/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONAp github.com/cosmos/ibc-go/v6 v6.1.0 h1:o7oXws2vKkKfOFzJI+oNylRn44PCNt5wzHd/zKQKbvQ= github.com/cosmos/ibc-go/v6 v6.1.0/go.mod h1:CY3zh2HLfetRiW8LY6kVHMATe90Wj/UOoY8T6cuB0is= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= -github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= -github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= +github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= +github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -3037,11 +3037,11 @@ github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2/go.mod h1 github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b h1:aZRt5BtXdoDdyrUKwcv3B7mS30m/B854cjKjmnXBE5A= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b/go.mod h1:v79f+eY6PMpmLv188FAubst4XV2Mm8mUmx1OgmdFG3c= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.12.1/go.mod h1:KatxXrVDzgWwbssUWsF5+cOJHXPvzQ09YSlzGNuhOEo= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= gitlab.com/thorchain/binance-sdk v1.2.3-0.20210117202539-d569b6b9ba5d h1:GGPSI9gU22zW75m1YO7ZEMFtVEI5NgyK4g17CIXFjqI= gitlab.com/thorchain/binance-sdk v1.2.3-0.20210117202539-d569b6b9ba5d/go.mod h1:SW01IZMpqlPNPdhHnn99qnJNvg8ll/agyyW7p85npwY= From bd413ec69b32ee565015a1c0facd38f2d8a7af2a Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Tue, 16 Jan 2024 22:54:18 -0800 Subject: [PATCH 40/67] fix(`zetaclient`): fix chain params comparison logic (#1588) * add chain params equal functions * fix param change check * goimport * changelog --- changelog.md | 1 + x/observer/types/chain_params.go | 18 ++++++++++++++++++ x/observer/types/chain_params_test.go | 6 ++++++ zetaclient/zetacore_observer.go | 6 ++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 120b77cfd3..f7049e9a7d 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ ### Fixes * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt +* [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic ## Version: v12.0.0 diff --git a/x/observer/types/chain_params.go b/x/observer/types/chain_params.go index 78b66af17d..d76557584d 100644 --- a/x/observer/types/chain_params.go +++ b/x/observer/types/chain_params.go @@ -319,3 +319,21 @@ func GetDefaultZetaPrivnetChainParams() *ChainParams { IsSupported: false, } } + +// ChainParamsEqual returns true if two chain params are equal +func ChainParamsEqual(params1, params2 ChainParams) bool { + return params1.ChainId == params2.ChainId && + params1.ConfirmationCount == params2.ConfirmationCount && + params1.ZetaTokenContractAddress == params2.ZetaTokenContractAddress && + params1.ConnectorContractAddress == params2.ConnectorContractAddress && + params1.Erc20CustodyContractAddress == params2.Erc20CustodyContractAddress && + params1.InTxTicker == params2.InTxTicker && + params1.OutTxTicker == params2.OutTxTicker && + params1.WatchUtxoTicker == params2.WatchUtxoTicker && + params1.GasPriceTicker == params2.GasPriceTicker && + params1.OutboundTxScheduleInterval == params2.OutboundTxScheduleInterval && + params1.OutboundTxScheduleLookahead == params2.OutboundTxScheduleLookahead && + params1.BallotThreshold.Equal(params2.BallotThreshold) && + params1.MinObserverDelegation.Equal(params2.MinObserverDelegation) && + params1.IsSupported == params2.IsSupported +} diff --git a/x/observer/types/chain_params_test.go b/x/observer/types/chain_params_test.go index 5852f1f661..0bdc9d814d 100644 --- a/x/observer/types/chain_params_test.go +++ b/x/observer/types/chain_params_test.go @@ -44,6 +44,12 @@ func TestUpdateChainParamsSuiteSuite(t *testing.T) { suite.Run(t, new(UpdateChainParamsSuite)) } +func TestChainParamsEqual(t *testing.T) { + params := types.GetDefaultChainParams() + require.True(t, types.ChainParamsEqual(*params.ChainParams[0], *params.ChainParams[0])) + require.False(t, types.ChainParamsEqual(*params.ChainParams[0], *params.ChainParams[1])) +} + func (s *UpdateChainParamsSuite) SetupTest() { s.evmParams = &types.ChainParams{ ConfirmationCount: 1, diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index aff055c74f..8d8d426a39 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -6,6 +6,8 @@ import ( "strings" "time" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" + sdkmath "cosmossdk.io/math" "github.com/pkg/errors" @@ -356,7 +358,7 @@ func (co *CoreObserver) getUpdatedChainOb(chainID int64) (ChainClient, error) { curParams := chainOb.GetChainParams() if common.IsEVMChain(chainID) { evmCfg, found := co.cfg.GetEVMConfig(chainID) - if found && curParams.String() != evmCfg.ChainParams.String() { + if found && !observertypes.ChainParamsEqual(curParams, evmCfg.ChainParams) { chainOb.SetChainParams(evmCfg.ChainParams) co.logger.ZetaChainWatcher.Info().Msgf( "updated chain params for chainID %d, new params: %v", @@ -366,7 +368,7 @@ func (co *CoreObserver) getUpdatedChainOb(chainID int64) (ChainClient, error) { } } else if common.IsBitcoinChain(chainID) { _, btcCfg, found := co.cfg.GetBTCConfig() - if found && curParams.String() != btcCfg.ChainParams.String() { + if found && !observertypes.ChainParamsEqual(curParams, btcCfg.ChainParams) { chainOb.SetChainParams(btcCfg.ChainParams) co.logger.ZetaChainWatcher.Info().Msgf( "updated chain params for Bitcoin, new params: %v", From d7cd5f86d6f216b7d40d6ae6020f7c868ca9411f Mon Sep 17 00:00:00 2001 From: Charlie <31941002+CharlieMc0@users.noreply.github.com> Date: Sat, 20 Jan 2024 12:13:52 -0700 Subject: [PATCH 41/67] docs: updated release instructions (#1585) * updated readme * updated readme * updated readme * Update changelog.md Co-authored-by: Lucas Bertrand * Update readme.md Co-authored-by: Lucas Bertrand * Update readme.md Co-authored-by: Lucas Bertrand --------- Co-authored-by: Lucas Bertrand --- changelog.md | 5 +++++ readme.md | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index f7049e9a7d..26932679a2 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,10 @@ ## Unreleased +### Chores + +* [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions + ### Features ### Fixes @@ -11,6 +15,7 @@ ## Version: v12.0.0 + ### Breaking Changes TSS and chain validation related queries have been moved from `crosschain` module to `observer` module: diff --git a/readme.md b/readme.md index b9db6be3c2..a3a931f7fa 100644 --- a/readme.md +++ b/readme.md @@ -81,27 +81,27 @@ to [run the smoke test](./contrib/localnet/README.md). [Discord](https://discord.com/invite/zetachain) | [Telegram](https://t.me/zetachainofficial) | [Website](https://zetachain.com) -## Creating a Release for Mainnet -Creating a release for mainnet is a straightforward process. Here are the steps to follow: -### Steps - - Step 1. Open a Pull Request (PR): Begin by opening a PR from the release candidate branch (e.g., vx.x.x-rc) to the main branch. - - Step 2. Testing and Validation: Allow the automated tests, including smoke tests, linting, and upgrade path testing, to run. Ensure that these tests pass successfully. - - Step 3. Approval Process: Obtain the necessary approvals from relevant stakeholders or team members. - - Step 4. Merging PR: Once all requirements have been met and the PR has received the required approvals, merge the PR. The automation will then be triggered to proceed with the release. - -By following these steps, you can efficiently create a release for Mainnet, ensuring that the code has been thoroughly tested and validated before deployment. - -## Creating a Release for Testnet -Creating a release for testnet is a straightforward process. Here are the steps to follow: +## Creating a Release Candidate +Creating a release candidate for testing is a straightforward process. Here are the steps to follow: ### 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. -By following these steps, you can efficiently create a release candidate for testnet for QA and validation. In the future we will make this automatically deploy to testnet when a -rc branch is created. -Currently, raising the proposal to deploy to testnet is a manual process via GitHub Action pipeline located in the infrastructure repo. +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 +After the Release Candidate has been fully tested, creating a final release for use on public networks is a straightforward process. Here are the steps to follow: + +### Steps + - Step 1. Open a Pull Request (PR): Begin by opening a PR from the release candidate branch (e.g., vx.x.x-rc) to the main branch. + - Step 2. Testing and Validation: Allow the automated tests, including E2E tests, linting, and upgrade path testing, to run. Ensure that these tests pass successfully. + - Step 3. Approval Process: Obtain the necessary approvals from relevant stakeholders or team members. + - Step 4. Merging PR: Once all requirements have been met and the PR has received the required approvals, merge the PR. The automation will then be triggered to proceed with the release. +By following these steps, you can efficiently create a release, ensuring that the code has been thoroughly tested and validated before deployment to public networks. ## Creating a Hotfix Release Creating a hotfix release is a straightforward process. Here are the steps to follow: From da6f9e38b4ae5384fcbb3dd25e8fe13f314993d8 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Sat, 20 Jan 2024 11:46:13 -0800 Subject: [PATCH 42/67] test(`e2e`): add chain header tests back and fix admin tests (#1577) * add header test back * fix admin tests * update changelogs --- changelog.md | 9 ++++++--- cmd/zetae2e/local/admin.go | 2 +- cmd/zetae2e/local/bitcoin.go | 2 +- cmd/zetae2e/local/ethereum.go | 2 +- cmd/zetae2e/local/local.go | 6 +++++- .../smoketest/smoketests/test_pause_zrc20.go | 12 ++++++------ 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/changelog.md b/changelog.md index 26932679a2..01b77c5681 100644 --- a/changelog.md +++ b/changelog.md @@ -2,9 +2,9 @@ ## Unreleased -### Chores +### Tests -* [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions +* [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests ### Features @@ -13,8 +13,11 @@ * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic -## Version: v12.0.0 +### Chores + +* [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions +## Version: v12.0.0 ### Breaking Changes diff --git a/cmd/zetae2e/local/admin.go b/cmd/zetae2e/local/admin.go index 01e5d3ae8f..34900fbaf4 100644 --- a/cmd/zetae2e/local/admin.go +++ b/cmd/zetae2e/local/admin.go @@ -66,7 +66,7 @@ func adminTestRoutine( smoketests.TestUpdateBytecodeName, smoketests.TestDepositEtherLiquidityCapName, ); err != nil { - return fmt.Errorf("admim tests failed: %v", err) + return fmt.Errorf("admin tests failed: %v", err) } adminRunner.Logger.Print("🍾 admin tests completed in %s", time.Since(startTime).String()) diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index a27d619138..eaf700465e 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -59,7 +59,7 @@ func bitcoinTestRoutine( bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) bitcoinRunner.SetupBitcoinAccount(initBitcoinNetwork) - bitcoinRunner.DepositBTC(false) + bitcoinRunner.DepositBTC(true) // run bitcoin test // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first diff --git a/cmd/zetae2e/local/ethereum.go b/cmd/zetae2e/local/ethereum.go index 74a57a6470..90d6a35dfb 100644 --- a/cmd/zetae2e/local/ethereum.go +++ b/cmd/zetae2e/local/ethereum.go @@ -47,7 +47,7 @@ func ethereumTestRoutine( startTime := time.Now() // depositing the necessary tokens on ZetaChain - txEtherDeposit := ethereumRunner.DepositEther(false) + txEtherDeposit := ethereumRunner.DepositEther(true) ethereumRunner.WaitForMinedCCTX(txEtherDeposit) // run ethereum test diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index f1a723f26e..b31c6869d4 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -135,7 +135,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } testStartTime := time.Now() - logger.Print("starting tests") + logger.Print("starting E2E tests") + + if testAdmin { + logger.Print("⚠️ admin tests enabled") + } // start timer go func() { diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_pause_zrc20.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_pause_zrc20.go index 5b6a9700b1..f3579990f2 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_pause_zrc20.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_pause_zrc20.go @@ -28,7 +28,7 @@ func TestPauseZRC20(sm *runner.SmokeTestRunner) { if receipt.Status == 0 { panic("Vault approval should succeed") } - tx, err = sm.BTCZRC20.Approve(sm.ZevmAuth, vaultAddr, big.NewInt(1e18)) + tx, err = sm.USDTZRC20.Approve(sm.ZevmAuth, vaultAddr, big.NewInt(1e18)) if err != nil { panic(err) } @@ -93,23 +93,23 @@ func TestPauseZRC20(sm *runner.SmokeTestRunner) { } sm.Logger.Info("Operations all failed") - // Check we can still interact with BTC ZRC20 + // Check we can still interact with USDT ZRC20 sm.Logger.Info("Check other ZRC20 can still be operated") - tx, err = sm.BTCZRC20.Transfer(sm.ZevmAuth, sample.EthAddress(), big.NewInt(1e3)) + tx, err = sm.USDTZRC20.Transfer(sm.ZevmAuth, sample.EthAddress(), big.NewInt(1e3)) if err != nil { panic(err) } receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) if receipt.Status == 0 { - panic("BTC transfer should succeed") + panic("USDT transfer should succeed") } - tx, err = vaultContract.Deposit(sm.ZevmAuth, sm.BTCZRC20Addr, big.NewInt(1e3)) + tx, err = vaultContract.Deposit(sm.ZevmAuth, sm.USDTZRC20Addr, big.NewInt(1e3)) if err != nil { panic(err) } receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) if receipt.Status == 0 { - panic("BTC vault deposit should succeed") + panic("USDT vault deposit should succeed") } // Check deposit revert when paused From e06711b63e7cc71e5999e4ba6674e7f27147478b Mon Sep 17 00:00:00 2001 From: Grant Zukel <80433392+gzukel@users.noreply.github.com> Date: Sat, 20 Jan 2024 22:49:04 -0700 Subject: [PATCH 43/67] ci: fix the cleanup step in the rc-release and publish-release pipelines (#1580) * fix: fix the cleanup step in the rc-release and publish-release pipelines * fix: fix the cleanup step in the rc-release and publish-release pipelines * Update rc-release.yml Co-authored-by: Lucas Bertrand --------- Co-authored-by: Charlie <31941002+CharlieMc0@users.noreply.github.com> Co-authored-by: Lucas Bertrand --- .github/workflows/publish-release.yml | 2 +- .github/workflows/rc-release.yml | 2 +- changelog.md | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 951f7a2888..fa01e0d4e4 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -133,4 +133,4 @@ jobs: - name: Clean Up Workspace if: always() shell: bash - run: rm -rf * \ No newline at end of file + run: sudo rm -rf * || echo "failed to cleanup workspace please investigate" \ No newline at end of file diff --git a/.github/workflows/rc-release.yml b/.github/workflows/rc-release.yml index fcd8faff9c..2e4fbfd194 100644 --- a/.github/workflows/rc-release.yml +++ b/.github/workflows/rc-release.yml @@ -85,4 +85,4 @@ jobs: - name: Clean Up Workspace if: always() shell: bash - run: rm -rf * \ No newline at end of file + run: sudo rm -rf * || echo "failed to clean workspace please investigate" \ No newline at end of file diff --git a/changelog.md b/changelog.md index 01b77c5681..0fd90f83af 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,10 @@ * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic +### CI + +* [1580](https://github.com/zeta-chain/node/pull/1580) - Fix release pipelines cleanup step. + ### Chores * [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions From d1abe7b8dced067e218b95ff4ee478b9fe8f5785 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 21 Jan 2024 12:18:54 -0500 Subject: [PATCH 44/67] fix: get tss address cli (#1589) * add btc chain id to get tss address cli * add btc chain id to get tss address historical cli * use maximum args instead of exact args * add changelog * generate docs * lint issue --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + ...ery_observer_get-historical-tss-address.md | 2 +- ...etacored_query_observer_get-tss-address.md | 2 +- .../client/cli/query_get_tss_address.go | 23 +++++++++++++++---- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 0fd90f83af..832f006123 100644 --- a/changelog.md +++ b/changelog.md @@ -80,6 +80,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1546](https://github.com/zeta-chain/node/pull/1546) - fix reset of pending nonces on genesis import * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB * [1567](https://github.com/zeta-chain/node/pull/1567) - add bitcoin chain id to fetch the tss address rpc endpoint +* [1589](https://github.com/zeta-chain/node/pull/1589) - add bitcoin chain id to `get tss address` and `get tss address historical` cli query ### Refactoring diff --git a/docs/cli/zetacored/zetacored_query_observer_get-historical-tss-address.md b/docs/cli/zetacored/zetacored_query_observer_get-historical-tss-address.md index 83de26b9dd..d56798a084 100644 --- a/docs/cli/zetacored/zetacored_query_observer_get-historical-tss-address.md +++ b/docs/cli/zetacored/zetacored_query_observer_get-historical-tss-address.md @@ -3,7 +3,7 @@ Query tss address by finalized zeta height (for historical tss addresses) ``` -zetacored query observer get-historical-tss-address [finalizedZetaHeight] [flags] +zetacored query observer get-historical-tss-address [finalizedZetaHeight] [bitcoinChainId] [flags] ``` ### Options diff --git a/docs/cli/zetacored/zetacored_query_observer_get-tss-address.md b/docs/cli/zetacored/zetacored_query_observer_get-tss-address.md index cb763f8510..5c5e68bd14 100644 --- a/docs/cli/zetacored/zetacored_query_observer_get-tss-address.md +++ b/docs/cli/zetacored/zetacored_query_observer_get-tss-address.md @@ -3,7 +3,7 @@ Query current tss address ``` -zetacored query observer get-tss-address [flags] +zetacored query observer get-tss-address [bitcoinChainId]] [flags] ``` ### Options diff --git a/x/observer/client/cli/query_get_tss_address.go b/x/observer/client/cli/query_get_tss_address.go index 8bfac0e10f..d37fb95f0c 100644 --- a/x/observer/client/cli/query_get_tss_address.go +++ b/x/observer/client/cli/query_get_tss_address.go @@ -11,9 +11,9 @@ import ( func CmdGetTssAddress() *cobra.Command { cmd := &cobra.Command{ - Use: "get-tss-address", + Use: "get-tss-address [bitcoinChainId]]", Short: "Query current tss address", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { clientCtx, err := client.GetClientTxContext(cmd) @@ -21,8 +21,14 @@ func CmdGetTssAddress() *cobra.Command { return err } queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryGetTssAddressRequest{} + if len(args) == 1 { + bitcoinChainID, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + params.BitcoinChainId = bitcoinChainID + } res, err := queryClient.GetTssAddress(cmd.Context(), params) if err != nil { @@ -40,9 +46,9 @@ func CmdGetTssAddress() *cobra.Command { func CmdGetTssAddressByFinalizedZetaHeight() *cobra.Command { cmd := &cobra.Command{ - Use: "get-historical-tss-address [finalizedZetaHeight]", + Use: "get-historical-tss-address [finalizedZetaHeight] [bitcoinChainId]", Short: "Query tss address by finalized zeta height (for historical tss addresses)", - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) (err error) { clientCtx, err := client.GetClientTxContext(cmd) @@ -58,6 +64,13 @@ func CmdGetTssAddressByFinalizedZetaHeight() *cobra.Command { params := &types.QueryGetTssAddressByFinalizedHeightRequest{ FinalizedZetaHeight: finalizedZetaHeight, } + if len(args) == 2 { + bitcoinChainID, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + params.BitcoinChainId = bitcoinChainID + } res, err := queryClient.GetTssAddressByFinalizedHeight(cmd.Context(), params) if err != nil { From dfc2314e0253293622e1da9cee8b6340b7f9b445 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:03:03 -0800 Subject: [PATCH 45/67] fix: exempt system txs from min gas check and fee deduction (#1605) * exempt system txs from min gas check and fee deduction in antehandlers. System txs are 7 zetaclient txs from observers. * update changelog * sort imports * simplify conditional branches in ante.go * add back fee deductor; allow system tx so set 1% min gas price * update changelog * update broadcast func to adjust gas price * refactor per review * factor out the reduction rate in to common variable * factor out the system tx determinator * separate out MsgCreateValidator * refactor per review comments * clean up * add unit tests * add one unit test * fix unit tests by using higher gas limits for inbound and outbound voters --------- Co-authored-by: Tanmay --- app/ante/ante.go | 94 +++++--- app/ante/ante_test.go | 216 +++++++++++++++++- app/ante/fees.go | 11 +- app/ante/handler_options.go | 34 ++- app/app.go | 3 +- changelog.md | 1 + .../client/integrationtests/cli_helpers.go | 16 +- .../integrationtests/inbound_voter_test.go | 7 +- .../cli/tx_deploy_fungible_coin_zrc_4.go | 2 - .../cli/tx_update_zrc20_liquidity_cap.go | 3 - zetaclient/broadcast.go | 6 +- 11 files changed, 344 insertions(+), 49 deletions(-) diff --git a/app/ante/ante.go b/app/ante/ante.go index 7d9586edfb..e1077339b4 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -19,19 +19,18 @@ import ( "fmt" "runtime/debug" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ethante "github.com/evmos/ethermint/app/ante" - cctxtypes "github.com/zeta-chain/zetacore/x/crosschain/types" - - tmlog "github.com/tendermint/tendermint/libs/log" - errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/authz" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + tmlog "github.com/tendermint/tendermint/libs/log" + cctxtypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func ValidateHandlerOptions(options ethante.HandlerOptions) error { +func ValidateHandlerOptions(options HandlerOptions) error { if options.AccountKeeper == nil { return errorsmod.Wrap(errortypes.ErrLogic, "account keeper is required for AnteHandler") } @@ -47,6 +46,9 @@ func ValidateHandlerOptions(options ethante.HandlerOptions) error { if options.EvmKeeper == nil { return errorsmod.Wrap(errortypes.ErrLogic, "evm keeper is required for AnteHandler") } + if options.ObserverKeeper == nil { + return errorsmod.Wrap(errortypes.ErrLogic, "observer keeper is required for AnteHandler") + } return nil } @@ -54,7 +56,7 @@ func ValidateHandlerOptions(options ethante.HandlerOptions) error { // Ethereum or SDK transaction to an internal ante handler for performing // transaction-level processing (e.g. fee payment, signature verification) before // being passed onto it's respective handler. -func NewAnteHandler(options ethante.HandlerOptions) (sdk.AnteHandler, error) { +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if err := ValidateHandlerOptions(options); err != nil { return nil, err } @@ -94,28 +96,26 @@ func NewAnteHandler(options ethante.HandlerOptions) (sdk.AnteHandler, error) { // handle as totally normal Cosmos SDK tx switch tx.(type) { case sdk.Tx: - found := false - for _, msg := range tx.GetMsgs() { - switch msg.(type) { - // treat these three msg types differently because they might call EVM which results in massive gas consumption - // For these two msg types, we don't check gas limit by using a different ante handler - case *cctxtypes.MsgGasPriceVoter, *cctxtypes.MsgVoteOnObservedInboundTx: - found = true - break - case *stakingtypes.MsgCreateValidator: - if ctx.BlockHeight() == 0 { - found = true - break - } - } + // default: handle as normal Cosmos SDK tx + anteHandler = newCosmosAnteHandler(options) + + // if tx is a system tx, and singer is authorized, use system tx handler + + isAuthorized := func(creator string) bool { + return options.ObserverKeeper.IsAuthorized(ctx, creator) } - if len(tx.GetMsgs()) == 1 && found { - // this differs newCosmosAnteHandler only in that it doesn't check gas limit - // by using an Infinite Gas Meter. - anteHandler = newCosmosAnteHandlerNoGasLimit(options) - } else { - anteHandler = newCosmosAnteHandler(options) + if IsSystemTx(tx, isAuthorized) { + anteHandler = newCosmosAnteHandlerForSystemTx(options) } + + // if tx is MsgCreatorValidator, use the newCosmosAnteHandlerForSystemTx handler to + // exempt gas fee requirement in genesis because it's not possible to pay gas fee in genesis + if len(tx.GetMsgs()) == 1 { + if _, ok := tx.GetMsgs()[0].(*stakingtypes.MsgCreateValidator); ok && ctx.BlockHeight() == 0 { + anteHandler = newCosmosAnteHandlerForSystemTx(options) + } + } + default: return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid transaction type: %T", tx) } @@ -145,3 +145,41 @@ func Recover(logger tmlog.Logger, err *error) { } } } + +// IsSystemTx determines whether tx is a system tx that's signed by an authorized signer +// system tx are special types of txs (see in the switch below), or such txs wrapped inside a MsgExec +// the parameter isAuthorizedSigner is a caller specified function that determines whether the signer of +// the tx is authorized. +func IsSystemTx(tx sdk.Tx, isAuthorizedSigner func(string) bool) bool { + // the following determines whether the tx is a system tx which will uses different handler + // System txs are always single Msg txs, optionally wrapped by one level of MsgExec + if len(tx.GetMsgs()) != 1 { // this is not a system tx + return false + } + msg := tx.GetMsgs()[0] + + // if wrapped inside a MsgExec, unwrap it and reveal the innerMsg. + var innerMsg sdk.Msg + innerMsg = msg + if mm, ok := msg.(*authz.MsgExec); ok { // authz tx; look inside it + msgs, err := mm.GetMessages() + if err == nil && len(msgs) == 1 { + innerMsg = msgs[0] + } + } + switch innerMsg.(type) { + case *cctxtypes.MsgGasPriceVoter, + *cctxtypes.MsgVoteOnObservedInboundTx, + *cctxtypes.MsgVoteOnObservedOutboundTx, + *cctxtypes.MsgAddToOutTxTracker, + *cctxtypes.MsgCreateTSSVoter, + *observertypes.MsgAddBlockHeader, + *observertypes.MsgAddBlameVote: + signers := innerMsg.GetSigners() + if len(signers) == 1 { + return isAuthorizedSigner(signers[0].String()) + } + } + + return false +} diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index 53a7d95c85..146e50c6ae 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -1,6 +1,19 @@ package ante_test -import sdk "github.com/cosmos/cosmos-sdk/types" +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/app" + "github.com/zeta-chain/zetacore/app/ante" + "github.com/zeta-chain/zetacore/testutil/sample" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) var _ sdk.AnteHandler = (&MockAnteHandler{}).AnteHandle @@ -16,3 +29,204 @@ func (mah *MockAnteHandler) AnteHandle(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.C mah.CalledCtx = ctx return ctx, nil } + +func TestIsSystemTx(t *testing.T) { + // system tx types: + // *cctxtypes.MsgGasPriceVoter, + // *cctxtypes.MsgVoteOnObservedInboundTx, + // *cctxtypes.MsgVoteOnObservedOutboundTx, + // *cctxtypes.MsgAddToOutTxTracker, + // *cctxtypes.MsgCreateTSSVoter, + // *observertypes.MsgAddBlockHeader, + // *observertypes.MsgAddBlameVote: + buildTxFromMsg := func(msg sdk.Msg) sdk.Tx { + txBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() + txBuilder.SetMsgs(msg) + return txBuilder.GetTx() + } + buildAuthzTxFromMsg := func(msg sdk.Msg) sdk.Tx { + txBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() + msgExec := authz.NewMsgExec(sample.Bech32AccAddress(), []sdk.Msg{msg}) + txBuilder.SetMsgs(&msgExec) + return txBuilder.GetTx() + } + isAuthorized := func(_ string) bool { + return true + } + isAuthorizedFalse := func(_ string) bool { + return false + } + + tests := []struct { + name string + tx sdk.Tx + isAuthorized func(string) bool + wantIs bool + }{ + { + "MsgCreateTSSVoter", + buildTxFromMsg(&crosschaintypes.MsgCreateTSSVoter{ + Creator: sample.AccAddress(), + TssPubkey: "pubkey1234", + }), + isAuthorizedFalse, + false, + }, + { + "MsgCreateTSSVoter", + buildTxFromMsg(&crosschaintypes.MsgCreateTSSVoter{ + Creator: sample.AccAddress(), + TssPubkey: "pubkey1234", + }), + isAuthorized, + true, + }, + { + "MsgExec{MsgCreateTSSVoter}", + buildAuthzTxFromMsg(&crosschaintypes.MsgCreateTSSVoter{ + Creator: sample.AccAddress(), + TssPubkey: "pubkey1234", + }), + isAuthorized, + + true, + }, + { + "MsgSend", + buildTxFromMsg(&banktypes.MsgSend{}), + isAuthorized, + + false, + }, + { + "MsgExec{MsgSend}", + buildAuthzTxFromMsg(&banktypes.MsgSend{}), + isAuthorized, + + false, + }, + { + "MsgCreateValidator", + buildTxFromMsg(&stakingtypes.MsgCreateValidator{}), + isAuthorized, + + false, + }, + + { + "MsgVoteOnObservedInboundTx", + buildTxFromMsg(&crosschaintypes.MsgVoteOnObservedInboundTx{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgVoteOnObservedInboundTx}", + buildAuthzTxFromMsg(&crosschaintypes.MsgVoteOnObservedInboundTx{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + + { + "MsgVoteOnObservedOutboundTx", + buildTxFromMsg(&crosschaintypes.MsgVoteOnObservedOutboundTx{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgVoteOnObservedOutboundTx}", + buildAuthzTxFromMsg(&crosschaintypes.MsgVoteOnObservedOutboundTx{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgAddToOutTxTracker", + buildTxFromMsg(&crosschaintypes.MsgAddToOutTxTracker{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgAddToOutTxTracker}", + buildAuthzTxFromMsg(&crosschaintypes.MsgAddToOutTxTracker{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgCreateTSSVoter", + buildTxFromMsg(&crosschaintypes.MsgCreateTSSVoter{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgCreateTSSVoter}", + buildAuthzTxFromMsg(&crosschaintypes.MsgCreateTSSVoter{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgAddBlockHeader", + buildTxFromMsg(&observertypes.MsgAddBlockHeader{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgAddBlockHeader}", + buildAuthzTxFromMsg(&observertypes.MsgAddBlockHeader{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgAddBlameVote", + buildTxFromMsg(&observertypes.MsgAddBlameVote{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + { + "MsgExec{MsgAddBlameVote}", + buildAuthzTxFromMsg(&observertypes.MsgAddBlameVote{ + Creator: sample.AccAddress(), + }), + isAuthorized, + + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + is := ante.IsSystemTx(tt.tx, tt.isAuthorized) + require.Equal(t, tt.wantIs, is) + }) + } +} diff --git a/app/ante/fees.go b/app/ante/fees.go index adb0fef13d..912ed8e0e2 100644 --- a/app/ante/fees.go +++ b/app/ante/fees.go @@ -29,6 +29,10 @@ import ( evmtypes "github.com/evmos/ethermint/x/evm/types" ) +var ( + GasPriceReductionRate = "0.01" // 1% of regular tx gas price for system txs +) + // MinGasPriceDecorator will check if the transaction's fee is at least as large // as the MinGasPrices param. If fee is too low, decorator returns error and tx // is rejected. This applies for both CheckTx and DeliverTx @@ -92,13 +96,16 @@ func (mpd MinGasPriceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate return next(ctx, tx, simulate) } - // Short-circuit genesis txs gentx + // Short-circuit genesis txs gentx at block 0 (there is no way to pay fee in genesis file) if len(tx.GetMsgs()) == 1 { - if _, ok := tx.GetMsgs()[0].(*stakingtypes.MsgCreateValidator); ok { + if _, ok := tx.GetMsgs()[0].(*stakingtypes.MsgCreateValidator); ok && ctx.BlockHeight() == 0 { return next(ctx, tx, simulate) } } + reductionRate := sdk.MustNewDecFromStr(GasPriceReductionRate) + minGasPrice = minGasPrice.Mul(reductionRate) // discounts min gas price for system tx + evmParams := mpd.evmKeeper.GetParams(ctx) evmDenom := evmParams.GetEvmDenom() minGasPrices := sdk.DecCoins{ diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 5fe40847e9..e46f7b728e 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -19,16 +19,39 @@ package ante import ( "fmt" + observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ibcante "github.com/cosmos/ibc-go/v6/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" ethante "github.com/evmos/ethermint/app/ante" ethermint "github.com/evmos/ethermint/types" + evmtypes "github.com/evmos/ethermint/x/evm/types" ) -func NewLegacyCosmosAnteHandlerEip712(options ethante.HandlerOptions) sdk.AnteHandler { +type HandlerOptions struct { + AccountKeeper evmtypes.AccountKeeper + BankKeeper evmtypes.BankKeeper + IBCKeeper *ibckeeper.Keeper + FeeMarketKeeper FeeMarketKeeper + EvmKeeper EVMKeeper + FeegrantKeeper ante.FeegrantKeeper + SignModeHandler authsigning.SignModeHandler + SigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error + MaxTxGasWanted uint64 + ExtensionOptionChecker ante.ExtensionOptionChecker + TxFeeChecker ante.TxFeeChecker + DisabledAuthzMsgs []string + ObserverKeeper *observerkeeper.Keeper +} + +func NewLegacyCosmosAnteHandlerEip712(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), @@ -52,7 +75,7 @@ func NewLegacyCosmosAnteHandlerEip712(options ethante.HandlerOptions) sdk.AnteHa ) } -func newEthAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { +func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first ethante.NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices @@ -68,7 +91,7 @@ func newEthAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { ) } -func newCosmosAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { +func newCosmosAnteHandler(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), @@ -92,15 +115,16 @@ func newCosmosAnteHandler(options ethante.HandlerOptions) sdk.AnteHandler { } // this applies to special cosmos tx that calls EVM, in which case the EVM overrides the gas limit -func newCosmosAnteHandlerNoGasLimit(options ethante.HandlerOptions) sdk.AnteHandler { +func newCosmosAnteHandlerForSystemTx(options HandlerOptions) sdk.AnteHandler { return sdk.ChainAnteDecorators( ethante.RejectMessagesDecorator{}, // reject MsgEthereumTxs NewAuthzLimiterDecorator(options.DisabledAuthzMsgs...), NewVestingAccountDecorator(), - NewSetUpContextDecorator(), + ante.NewSetUpContextDecorator(), ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), + // system txs pay less gas fee NewMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), diff --git a/app/app.go b/app/app.go index d78ef88643..a87abb240b 100644 --- a/app/app.go +++ b/app/app.go @@ -575,7 +575,7 @@ func New( app.SetBeginBlocker(app.BeginBlocker) maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted)) - options := evmante.HandlerOptions{ + options := ante.HandlerOptions{ AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper, EvmKeeper: app.EvmKeeper, @@ -589,6 +589,7 @@ func New( sdk.MsgTypeURL(&vestingtypes.MsgCreatePermanentLockedAccount{}), sdk.MsgTypeURL(&vestingtypes.MsgCreatePeriodicVestingAccount{}), }, + ObserverKeeper: app.ZetaObserverKeeper, } anteHandler, err := ante.NewAnteHandler(options) diff --git a/changelog.md b/changelog.md index 832f006123..5f1d3abbce 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic +* [1650](https://github.com/zeta-chain/node/pull/1605) - exempt (discounted) *system txs* from min gas price check and gas fee deduction ### CI diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index 626706a627..3195782031 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -165,7 +165,9 @@ func BuildSignedGasPriceVote(t testing.TB, val *network.Validator, denom string, fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagGas, "400000"), + fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fmt.Sprintf("%s%s", "10", denom)), } args := append(inboundVoterArgs, txArgs...) out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) @@ -188,7 +190,9 @@ func BuildSignedTssVote(t testing.TB, val *network.Validator, denom string, acco fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagGas, "400000"), + fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fmt.Sprintf("%s%s", "10", denom)), } args := append(inboundVoterArgs, txArgs...) out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) @@ -229,7 +233,9 @@ func BuildSignedOutboundVote( fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagGas, "400000"), + fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fmt.Sprintf("%s%s", "10", denom)), } args := append(outboundVoterArgs, txArgs...) out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) @@ -262,7 +268,9 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagGas, "4000000"), + fmt.Sprintf("--%s=%s", flags.FlagGasAdjustment, "1.5"), + fmt.Sprintf("--%s=%s", flags.FlagGasPrices, fmt.Sprintf("%s%s", "10", denom)), } args := append(inboundVoterArgs, txArgs...) out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) diff --git a/x/crosschain/client/integrationtests/inbound_voter_test.go b/x/crosschain/client/integrationtests/inbound_voter_test.go index 424a7e68eb..b838250745 100644 --- a/x/crosschain/client/integrationtests/inbound_voter_test.go +++ b/x/crosschain/client/integrationtests/inbound_voter_test.go @@ -241,10 +241,13 @@ func (s *IntegrationTestSuite) TestCCTXInboundVoter() { s.Require().NoError(s.network.WaitForNBlocks(2)) out, err := clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdListPendingNonces(), []string{"--output", "json"}) s.Require().NoError(err) - fmt.Println(out.String()) + //fmt.Println(out.String()) out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, observercli.CmdGetSupportedChains(), []string{"--output", "json"}) s.Require().NoError(err) - fmt.Println(out.String()) + //fmt.Println(out.String()) + out, err = clitestutil.ExecTestCLICmd(broadcaster.ClientCtx, crosschaincli.CmdListGasPrice(), []string{"--output", "json"}) + s.Require().NoError(err) + //fmt.Println(out.String()) // Vote the inbound tx for _, val := range s.network.Validators { diff --git a/x/fungible/client/cli/tx_deploy_fungible_coin_zrc_4.go b/x/fungible/client/cli/tx_deploy_fungible_coin_zrc_4.go index adc638e69f..2be8037801 100644 --- a/x/fungible/client/cli/tx_deploy_fungible_coin_zrc_4.go +++ b/x/fungible/client/cli/tx_deploy_fungible_coin_zrc_4.go @@ -1,7 +1,6 @@ package cli import ( - "fmt" "strconv" "github.com/zeta-chain/zetacore/common" @@ -43,7 +42,6 @@ func CmdDeployFungibleCoinZRC4() *cobra.Command { if err != nil { return err } - fmt.Printf("CLI address: %s\n", clientCtx.GetFromAddress().String()) msg := types.NewMsgDeployFungibleCoinZRC20( clientCtx.GetFromAddress().String(), argERC20, diff --git a/x/fungible/client/cli/tx_update_zrc20_liquidity_cap.go b/x/fungible/client/cli/tx_update_zrc20_liquidity_cap.go index 4944e12d81..4c84c38527 100644 --- a/x/fungible/client/cli/tx_update_zrc20_liquidity_cap.go +++ b/x/fungible/client/cli/tx_update_zrc20_liquidity_cap.go @@ -1,8 +1,6 @@ package cli import ( - "fmt" - "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -23,7 +21,6 @@ func CmdUpdateZRC20LiquidityCap() *cobra.Command { if err != nil { return err } - fmt.Printf("CLI address: %s\n", clientCtx.GetFromAddress().String()) msg := types.NewMsgUpdateZRC20LiquidityCap( clientCtx.GetFromAddress().String(), args[0], diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index f015f2df85..8c1a86e70d 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -14,6 +14,7 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" flag "github.com/spf13/pflag" rpchttp "github.com/tendermint/tendermint/rpc/client/http" + "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/common/cosmos" "github.com/zeta-chain/zetacore/zetaclient/hsm" @@ -41,6 +42,9 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg if baseGasPrice == 0 { baseGasPrice = DefaultBaseGasPrice // shoudn't happen, but just in case } + reductionRate := sdktypes.MustNewDecFromStr(ante.GasPriceReductionRate) + // multiply gas price by the system tx reduction rate + adjustedBaseGasPrice := sdktypes.NewDec(baseGasPrice).Mul(reductionRate) if blockHeight > b.blockHeight { b.blockHeight = blockHeight @@ -72,7 +76,7 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg builder.SetGasLimit(gaslimit) // #nosec G701 always in range fee := sdktypes.NewCoins(sdktypes.NewCoin(config.BaseDenom, - cosmos.NewInt(int64(gaslimit)).Mul(cosmos.NewInt(baseGasPrice)))) + cosmos.NewInt(int64(gaslimit)).Mul(adjustedBaseGasPrice.Ceil().RoundInt()))) builder.SetFeeAmount(fee) //fmt.Printf("signing from name: %s\n", ctx.GetFromName()) err = b.SignTx(factory, ctx.GetFromName(), builder, true, ctx.TxConfig) From 04e0129fcc45dff5e6d4459fed521c55f13798c5 Mon Sep 17 00:00:00 2001 From: kevinssgh <79858682+kevinssgh@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:35:34 -0500 Subject: [PATCH 46/67] fix: Stress test refactor (#1501) * fixed local stress test * added new cmd to initialize config file. * cleaned up stress test cmd by using config file * add changelog * ran make generate * fix gosec error * update refactor, can remove the cmd from orchestrator later. * update refactor --- changelog.md | 1 + cmd/zetae2e/init.go | 39 ++ cmd/zetae2e/local/local.go | 6 +- cmd/zetae2e/local/utils.go | 6 +- cmd/zetae2e/root.go | 2 + cmd/zetae2e/stress.go | 635 +++++++++--------- .../smoketest/cmd/smoketest/local/local.go | 2 +- .../smoketest/cmd/smoketest/local/utils.go | 4 +- .../smoketest/cmd/smoketest/stress.go | 321 --------- 9 files changed, 367 insertions(+), 649 deletions(-) create mode 100644 cmd/zetae2e/init.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/stress.go diff --git a/changelog.md b/changelog.md index 5f1d3abbce..c6396ae86f 100644 --- a/changelog.md +++ b/changelog.md @@ -81,6 +81,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1546](https://github.com/zeta-chain/node/pull/1546) - fix reset of pending nonces on genesis import * [1555](https://github.com/zeta-chain/node/pull/1555) - Reduce websocket message limit to 10MB * [1567](https://github.com/zeta-chain/node/pull/1567) - add bitcoin chain id to fetch the tss address rpc endpoint +* [1501](https://github.com/zeta-chain/node/pull/1501) - fix stress test - use new refactored config file and smoketest runner * [1589](https://github.com/zeta-chain/node/pull/1589) - add bitcoin chain id to `get tss address` and `get tss address historical` cli query ### Refactoring diff --git a/cmd/zetae2e/init.go b/cmd/zetae2e/init.go new file mode 100644 index 0000000000..66d7e4fd3f --- /dev/null +++ b/cmd/zetae2e/init.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + + "github.com/zeta-chain/zetacore/cmd/zetae2e/local" + + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" +) + +var initConf = config.Config{} +var configFile = "" + +func NewInitCmd() *cobra.Command { + var InitCmd = &cobra.Command{ + Use: "init", + Short: "initialize config file for e2e tests", + Run: initConfig, + } + + InitCmd.Flags().StringVar(&initConf.RPCs.EVM, "ethURL", "http://eth:8545", "--ethURL http://eth:8545") + InitCmd.Flags().StringVar(&initConf.RPCs.ZetaCoreGRPC, "grpcURL", "zetacore0:9090", "--grpcURL zetacore0:9090") + InitCmd.Flags().StringVar(&initConf.RPCs.ZetaCoreRPC, "rpcURL", "http://zetacore0:26657", "--rpcURL http://zetacore0:26657") + InitCmd.Flags().StringVar(&initConf.RPCs.Zevm, "zevmURL", "http://zetacore0:8545", "--zevmURL http://zetacore0:8545") + InitCmd.Flags().StringVar(&initConf.RPCs.Bitcoin, "btcURL", "bitcoin:18443", "--grpcURL bitcoin:18443") + + InitCmd.Flags().StringVar(&initConf.ZetaChainID, "chainID", "athens_101-1", "--chainID athens_101-1") + InitCmd.Flags().StringVar(&configFile, local.FlagConfigFile, "smoketest.config", "--cfg ./smoketest.config") + + return InitCmd +} + +func initConfig(_ *cobra.Command, _ []string) { + err := config.WriteConfig(configFile, initConf) + if err != nil { + fmt.Printf("error writing config file: %s", err.Error()) + } +} diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index b31c6869d4..92b16526f3 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -18,7 +18,7 @@ import ( const ( flagContractsDeployed = "deployed" flagWaitForHeight = "wait-for" - flagConfigFile = "config" + FlagConfigFile = "config" flagVerbose = "verbose" flagTestAdmin = "test-admin" flagTestCustom = "test-custom" @@ -51,7 +51,7 @@ func NewLocalCmd() *cobra.Command { "block height for tests to begin, ex. --wait-for 100", ) cmd.Flags().String( - flagConfigFile, + FlagConfigFile, "", "config file to use for the tests", ) @@ -149,7 +149,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { }() // initialize tests config - conf, err := getConfig(cmd) + conf, err := GetConfig(cmd) if err != nil { panic(err) } diff --git a/cmd/zetae2e/local/utils.go b/cmd/zetae2e/local/utils.go index 8e1ab210c1..e190b45df1 100644 --- a/cmd/zetae2e/local/utils.go +++ b/cmd/zetae2e/local/utils.go @@ -16,9 +16,9 @@ import ( crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) -// getConfig returns config from file from the command line flag -func getConfig(cmd *cobra.Command) (config.Config, error) { - configFile, err := cmd.Flags().GetString(flagConfigFile) +// GetConfig returns config from file from the command line flag +func GetConfig(cmd *cobra.Command) (config.Config, error) { + configFile, err := cmd.Flags().GetString(FlagConfigFile) if err != nil { return config.Config{}, err } diff --git a/cmd/zetae2e/root.go b/cmd/zetae2e/root.go index 8f514a6584..fb93caa131 100644 --- a/cmd/zetae2e/root.go +++ b/cmd/zetae2e/root.go @@ -13,6 +13,8 @@ func NewRootCmd() *cobra.Command { cmd.AddCommand( NewRunCmd(), local.NewLocalCmd(), + NewStressTestCmd(), + NewInitCmd(), ) return cmd diff --git a/cmd/zetae2e/stress.go b/cmd/zetae2e/stress.go index 670922056f..26a2169b95 100644 --- a/cmd/zetae2e/stress.go +++ b/cmd/zetae2e/stress.go @@ -1,321 +1,318 @@ package main -//import ( -// "context" -// "errors" -// "fmt" -// "math/big" -// "os" -// "sort" -// "time" -// -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// "github.com/ethereum/go-ethereum/accounts/abi/bind" -// ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ethereum/go-ethereum/crypto" -// "github.com/ethereum/go-ethereum/ethclient" -// "github.com/spf13/cobra" -// "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" -// crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" -// fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" -// observertypes "github.com/zeta-chain/zetacore/x/observer/types" -// "google.golang.org/grpc" -//) -// -//const ( -// StatInterval = 5 -// StressTestTimeout = 100 * time.Minute -//) -// -//var ( -// zevmNonce = big.NewInt(1) -//) -// -//var StressCmd = &cobra.Command{ -// Use: "stress", -// Short: "Run Local Stress Test", -// Run: StressTest, -//} -// -//type stressArguments struct { -// ethURL string -// grpcURL string -// zevmURL string -// deployerAddress string -// deployerPrivateKey string -// network string -// txnInterval int64 -//} -// -//var stressTestArgs = stressArguments{} -// -//func init() { -// RootCmd.AddCommand(StressCmd) -// StressCmd.Flags().StringVar(&stressTestArgs.ethURL, "ethURL", "http://eth:8545", "--ethURL http://eth:8545") -// StressCmd.Flags().StringVar(&stressTestArgs.grpcURL, "grpcURL", "zetacore0:9090", "--grpcURL zetacore0:9090") -// StressCmd.Flags().StringVar(&stressTestArgs.zevmURL, "zevmURL", zevmRPC, "--zevmURL http://zetacore0:8545") -// StressCmd.Flags().StringVar(&stressTestArgs.deployerAddress, "addr", "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", "--addr ") -// StressCmd.Flags().StringVar(&stressTestArgs.deployerPrivateKey, "privKey", "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263", "--privKey ") -// StressCmd.Flags().StringVar(&stressTestArgs.network, "network", "PRIVNET", "--network PRIVNET") -// StressCmd.Flags().Int64Var(&stressTestArgs.txnInterval, "tx-interval", 500, "--tx-interval [TIME_INTERVAL_MILLISECONDS]") -// -// DeployerAddress = ethcommon.HexToAddress(stressTestArgs.deployerAddress) -//} -// -//func StressTest(_ *cobra.Command, _ []string) { -// testStartTime := time.Now() -// defer func() { -// fmt.Println("Smoke test took", time.Since(testStartTime)) -// }() -// go func() { -// time.Sleep(StressTestTimeout) -// fmt.Println("Smoke test timed out after", StressTestTimeout) -// os.Exit(1) -// }() -// -// goerliClient, err := ethclient.Dial(stressTestArgs.ethURL) -// if err != nil { -// panic(err) -// } -// -// bal, err := goerliClient.BalanceAt(context.TODO(), DeployerAddress, nil) -// if err != nil { -// panic(err) -// } -// fmt.Printf("Deployer address: %s, balance: %d Wei\n", DeployerAddress.Hex(), bal) -// -// chainid, err := goerliClient.ChainID(context.Background()) -// if err != nil { -// panic(err) -// } -// deployerPrivkey, err := crypto.HexToECDSA(stressTestArgs.deployerPrivateKey) -// if err != nil { -// panic(err) -// } -// goerliAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) -// if err != nil { -// panic(err) -// } -// -// grpcConn, err := grpc.Dial(stressTestArgs.grpcURL, grpc.WithInsecure()) -// if err != nil { -// panic(err) -// } -// -// cctxClient := crosschaintypes.NewQueryClient(grpcConn) -// fungibleClient := fungibletypes.NewQueryClient(grpcConn) -// bankClient := banktypes.NewQueryClient(grpcConn) -// authClient := authtypes.NewQueryClient(grpcConn) -// observerClient := observertypes.NewQueryClient(grpcConn) -// -// // Wait for Genesis and keygen to be completed. ~ height 30 -// time.Sleep(20 * time.Second) -// for { -// time.Sleep(5 * time.Second) -// response, err := cctxClient.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) -// if err != nil { -// fmt.Printf("cctxClient.LastZetaHeight error: %s", err) -// continue -// } -// if response.Height >= 30 { -// break -// } -// fmt.Printf("Last ZetaHeight: %d\n", response.Height) -// } -// -// // get the clients for tests -// var zevmClient *ethclient.Client -// for { -// time.Sleep(5 * time.Second) -// fmt.Printf("dialing zevm client: %s\n", stressTestArgs.zevmURL) -// zevmClient, err = ethclient.Dial(stressTestArgs.zevmURL) -// if err != nil { -// continue -// } -// break -// } -// chainid, err = zevmClient.ChainID(context.Background()) -// if err != nil { -// panic(err) -// } -// zevmAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) -// if err != nil { -// panic(err) -// } -// -// smokeTest := NewSmokeTest( -// goerliClient, -// zevmClient, -// cctxClient, -// ZetaTxServer{}, // not used in stress test -// fungibleClient, -// authClient, -// bankClient, -// observerClient, -// goerliAuth, -// zevmAuth, -// nil, -// ) -// -// // If stress test is running on local docker environment -// if stressTestArgs.network == "PRIVNET" { -// smokeTest.TestSetupZetaTokenAndConnectorAndZEVMContracts() -// smokeTest.TestDepositEtherIntoZRC20() -// smokeTest.TestSendZetaIn() -// } else if stressTestArgs.network == "TESTNET" { -// ethZRC20Addr, err := smokeTest.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(5)) -// if err != nil { -// panic(err) -// } -// smokeTest.ETHZRC20Addr = ethZRC20Addr -// smokeTest.ETHZRC20, err = zrc20.NewZRC20(smokeTest.ETHZRC20Addr, smokeTest.zevmClient) -// if err != nil { -// panic(err) -// } -// } else { -// err := errors.New("invalid network argument: " + stressTestArgs.network) -// panic(err) -// } -// -// // Check zrc20 balance of Deployer address -// ethZRC20Balance, err := smokeTest.ETHZRC20.BalanceOf(nil, DeployerAddress) -// if err != nil { -// panic(err) -// } -// fmt.Printf("eth zrc20 balance: %s Wei \n", ethZRC20Balance.String()) -// -// //Pre-approve ETH withdraw on ZEVM -// fmt.Printf("approving ETH ZRC20...\n") -// ethZRC20 := smokeTest.ETHZRC20 -// tx, err := ethZRC20.Approve(smokeTest.zevmAuth, smokeTest.ETHZRC20Addr, big.NewInt(1e18)) -// if err != nil { -// panic(err) -// } -// receipt := MustWaitForTxReceipt(smokeTest.zevmClient, tx) -// fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) -// -// // Get current nonce on zevm for DeployerAddress - Need to keep track of nonce at client level -// blockNum, err := smokeTest.zevmClient.BlockNumber(context.Background()) -// if err != nil { -// panic(err) -// } -// -// // #nosec G701 smoketest - always in range -// nonce, err := smokeTest.zevmClient.NonceAt(context.Background(), DeployerAddress, big.NewInt(int64(blockNum))) -// if err != nil { -// panic(err) -// } -// -// // #nosec G701 smoketest - always in range -// zevmNonce = big.NewInt(int64(nonce)) -// -// // -------------- TEST BEGINS ------------------ -// -// fmt.Println("**** STRESS TEST BEGINS ****") -// fmt.Println(" 1. Periodically Withdraw ETH from ZEVM to EVM - goerli") -// fmt.Println(" 2. Display Network metrics to monitor performance [Num Pending outbound tx], [Num Trackers]") -// -// smokeTest.wg.Add(2) -// go smokeTest.WithdrawCCtx() // Withdraw USDT from ZEVM to EVM - goerli -// go smokeTest.EchoNetworkMetrics() // Display Network metrics periodically to monitor performance -// -// smokeTest.wg.Wait() -//} -// -//// WithdrawCCtx withdraw USDT from ZEVM to EVM -//func (sm *SmokeTest) WithdrawCCtx() { -// ticker := time.NewTicker(time.Millisecond * time.Duration(stressTestArgs.txnInterval)) -// for { -// select { -// case <-ticker.C: -// sm.WithdrawETHZRC20() -// } -// } -//} -// -//func (sm *SmokeTest) EchoNetworkMetrics() { -// ticker := time.NewTicker(time.Second * StatInterval) -// var queue = make([]uint64, 0) -// var numTicks = 0 -// var totalMinedTxns = uint64(0) -// var previousMinedTxns = uint64(0) -// -// for { -// select { -// case <-ticker.C: -// numTicks++ -// // Get all pending outbound transactions -// cctxResp, err := sm.cctxClient.CctxListPending(context.Background(), &crosschaintypes.QueryListCctxPendingRequest{ -// ChainId: getChainID(), -// }) -// if err != nil { -// continue -// } -// sends := cctxResp.CrossChainTx -// sort.Slice(sends, func(i, j int) bool { -// return sends[i].GetCurrentOutTxParam().OutboundTxTssNonce < sends[j].GetCurrentOutTxParam().OutboundTxTssNonce -// }) -// if len(sends) > 0 { -// fmt.Printf("pending nonces %d to %d\n", sends[0].GetCurrentOutTxParam().OutboundTxTssNonce, sends[len(sends)-1].GetCurrentOutTxParam().OutboundTxTssNonce) -// } else { -// continue -// } -// // -// // Get all trackers -// trackerResp, err := sm.cctxClient.OutTxTrackerAll(context.Background(), &crosschaintypes.QueryAllOutTxTrackerRequest{}) -// if err != nil { -// continue -// } -// -// currentMinedTxns := sends[0].GetCurrentOutTxParam().OutboundTxTssNonce -// newMinedTxCnt := currentMinedTxns - previousMinedTxns -// previousMinedTxns = currentMinedTxns -// -// // Add new mined txn count to queue and remove the oldest entry -// queue = append(queue, newMinedTxCnt) -// if numTicks > 60/StatInterval { -// totalMinedTxns -= queue[0] -// queue = queue[1:] -// numTicks = 60/StatInterval + 1 //prevent overflow -// } -// -// //Calculate rate -> tx/min -// totalMinedTxns += queue[len(queue)-1] -// rate := totalMinedTxns -// -// numPending := len(cctxResp.CrossChainTx) -// numTrackers := len(trackerResp.OutTxTracker) -// -// fmt.Println("Network Stat => Num of Pending cctx: ", numPending, "Num active trackers: ", numTrackers, "Tx Rate: ", rate, " tx/min") -// } -// } -//} -// -//func (sm *SmokeTest) WithdrawETHZRC20() { -// defer func() { -// zevmNonce.Add(zevmNonce, big.NewInt(1)) -// }() -// -// ethZRC20 := sm.ETHZRC20 -// -// sm.zevmAuth.Nonce = zevmNonce -// _, err := ethZRC20.Withdraw(sm.zevmAuth, DeployerAddress.Bytes(), big.NewInt(100)) -// if err != nil { -// panic(err) -// } -//} -// -//// Get ETH based chain ID - Build flags are conflicting with current lib, need to do this manually -//func getChainID() int64 { -// switch stressTestArgs.network { -// case "PRIVNET": -// return 1337 -// case "TESTNET": -// return 5 -// case "MAINNET": -// return 1 -// default: -// return 1337 -// } -//} +import ( + "context" + "errors" + "fmt" + "math/big" + "os" + "sort" + "time" + + "github.com/fatih/color" + zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" + "github.com/zeta-chain/zetacore/cmd/zetae2e/local" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/app" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "google.golang.org/grpc" +) + +const ( + StatInterval = 5 + StressTestTimeout = 100 * time.Minute +) + +var ( + zevmNonce = big.NewInt(1) +) + +type stressArguments struct { + deployerAddress string + deployerPrivateKey string + network string + txnInterval int64 + contractsDeployed bool + config string +} + +var stressTestArgs = stressArguments{} + +func NewStressTestCmd() *cobra.Command { + var StressCmd = &cobra.Command{ + Use: "stress", + Short: "Run Stress Test", + Run: StressTest, + } + + StressCmd.Flags().StringVar(&stressTestArgs.deployerAddress, "addr", "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", "--addr ") + StressCmd.Flags().StringVar(&stressTestArgs.deployerPrivateKey, "privKey", "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263", "--privKey ") + StressCmd.Flags().StringVar(&stressTestArgs.network, "network", "LOCAL", "--network TESTNET") + StressCmd.Flags().Int64Var(&stressTestArgs.txnInterval, "tx-interval", 500, "--tx-interval [TIME_INTERVAL_MILLISECONDS]") + StressCmd.Flags().BoolVar(&stressTestArgs.contractsDeployed, "contracts-deployed", false, "--contracts-deployed=false") + StressCmd.Flags().StringVar(&stressTestArgs.config, local.FlagConfigFile, "", "config file to use for the smoketest") + StressCmd.Flags().Bool(flagVerbose, false, "set to true to enable verbose logging") + + local.DeployerAddress = ethcommon.HexToAddress(stressTestArgs.deployerAddress) + + return StressCmd +} + +func StressTest(cmd *cobra.Command, _ []string) { + testStartTime := time.Now() + defer func() { + fmt.Println("Smoke test took", time.Since(testStartTime)) + }() + go func() { + time.Sleep(StressTestTimeout) + fmt.Println("Smoke test timed out after", StressTestTimeout) + os.Exit(1) + }() + + // set account prefix to zeta + cosmosConf := sdk.GetConfig() + cosmosConf.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) + cosmosConf.Seal() + + // initialize smoke tests config + conf, err := local.GetConfig(cmd) + if err != nil { + panic(err) + } + + // Initialize clients ---------------------------------------------------------------- + goerliClient, err := ethclient.Dial(conf.RPCs.EVM) + if err != nil { + panic(err) + } + + bal, err := goerliClient.BalanceAt(context.TODO(), local.DeployerAddress, nil) + if err != nil { + panic(err) + } + fmt.Printf("Deployer address: %s, balance: %d Wei\n", local.DeployerAddress.Hex(), bal) + + grpcConn, err := grpc.Dial(conf.RPCs.ZetaCoreGRPC, grpc.WithInsecure()) + if err != nil { + panic(err) + } + + cctxClient := crosschaintypes.NewQueryClient(grpcConn) + // ----------------------------------------------------------------------------------- + + // Wait for Genesis and keygen to be completed if network is local. ~ height 30 + if stressTestArgs.network == "LOCAL" { + time.Sleep(20 * time.Second) + for { + time.Sleep(5 * time.Second) + response, err := cctxClient.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) + if err != nil { + fmt.Printf("cctxClient.LastZetaHeight error: %s", err) + continue + } + if response.Height >= 30 { + break + } + fmt.Printf("Last ZetaHeight: %d\n", response.Height) + } + } + + // initialize context + ctx, cancel := context.WithCancel(context.Background()) + + verbose, err := cmd.Flags().GetBool(flagVerbose) + if err != nil { + panic(err) + } + logger := runner.NewLogger(verbose, color.FgWhite, "setup") + + // initialize smoke test runner + smokeTest, err := zetae2econfig.RunnerFromConfig( + ctx, + "deployer", + cancel, + conf, + local.DeployerAddress, + local.DeployerPrivateKey, + utils.FungibleAdminName, + FungibleAdminMnemonic, + logger, + ) + if err != nil { + panic(err) + } + + // setup TSS addresses + smokeTest.SetTSSAddresses() + + smokeTest.SetupEVM(stressTestArgs.contractsDeployed) + + // If stress test is running on local docker environment + if stressTestArgs.network == "LOCAL" { + // deploy and set zevm contract + smokeTest.SetZEVMContracts() + + // deposit on ZetaChain + smokeTest.DepositEther(false) + smokeTest.DepositZeta() + } else if stressTestArgs.network == "TESTNET" { + ethZRC20Addr, err := smokeTest.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(5)) + if err != nil { + panic(err) + } + smokeTest.ETHZRC20Addr = ethZRC20Addr + smokeTest.ETHZRC20, err = zrc20.NewZRC20(smokeTest.ETHZRC20Addr, smokeTest.ZevmClient) + if err != nil { + panic(err) + } + } else { + err := errors.New("invalid network argument: " + stressTestArgs.network) + panic(err) + } + + // Check zrc20 balance of Deployer address + ethZRC20Balance, err := smokeTest.ETHZRC20.BalanceOf(nil, local.DeployerAddress) + if err != nil { + panic(err) + } + fmt.Printf("eth zrc20 balance: %s Wei \n", ethZRC20Balance.String()) + + //Pre-approve ETH withdraw on ZEVM + fmt.Printf("approving ETH ZRC20...\n") + ethZRC20 := smokeTest.ETHZRC20 + tx, err := ethZRC20.Approve(smokeTest.ZevmAuth, smokeTest.ETHZRC20Addr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt := utils.MustWaitForTxReceipt(ctx, smokeTest.ZevmClient, tx, logger, smokeTest.ReceiptTimeout) + fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) + + // Get current nonce on zevm for DeployerAddress - Need to keep track of nonce at client level + blockNum, err := smokeTest.ZevmClient.BlockNumber(context.Background()) + if err != nil { + panic(err) + } + + // #nosec G701 smoketest - always in range + nonce, err := smokeTest.ZevmClient.NonceAt(context.Background(), local.DeployerAddress, big.NewInt(int64(blockNum))) + if err != nil { + panic(err) + } + + // #nosec G701 smoketest - always in range + zevmNonce = big.NewInt(int64(nonce)) + + // -------------- TEST BEGINS ------------------ + + fmt.Println("**** STRESS TEST BEGINS ****") + fmt.Println(" 1. Periodically Withdraw ETH from ZEVM to EVM - goerli") + fmt.Println(" 2. Display Network metrics to monitor performance [Num Pending outbound tx], [Num Trackers]") + + smokeTest.WG.Add(2) + go WithdrawCCtx(smokeTest) // Withdraw USDT from ZEVM to EVM - goerli + go EchoNetworkMetrics(smokeTest) // Display Network metrics periodically to monitor performance + + smokeTest.WG.Wait() +} + +// WithdrawCCtx withdraw USDT from ZEVM to EVM +func WithdrawCCtx(sm *runner.SmokeTestRunner) { + ticker := time.NewTicker(time.Millisecond * time.Duration(stressTestArgs.txnInterval)) + for { + select { + case <-ticker.C: + WithdrawETHZRC20(sm) + } + } +} + +func EchoNetworkMetrics(sm *runner.SmokeTestRunner) { + ticker := time.NewTicker(time.Second * StatInterval) + var queue = make([]uint64, 0) + var numTicks = 0 + var totalMinedTxns = uint64(0) + var previousMinedTxns = uint64(0) + chainID, err := getChainID(sm.GoerliClient) + + if err != nil { + panic(err) + } + + for { + select { + case <-ticker.C: + numTicks++ + // Get all pending outbound transactions + cctxResp, err := sm.CctxClient.CctxListPending(context.Background(), &crosschaintypes.QueryListCctxPendingRequest{ + ChainId: chainID.Int64(), + }) + if err != nil { + continue + } + sends := cctxResp.CrossChainTx + sort.Slice(sends, func(i, j int) bool { + return sends[i].GetCurrentOutTxParam().OutboundTxTssNonce < sends[j].GetCurrentOutTxParam().OutboundTxTssNonce + }) + if len(sends) > 0 { + fmt.Printf("pending nonces %d to %d\n", sends[0].GetCurrentOutTxParam().OutboundTxTssNonce, sends[len(sends)-1].GetCurrentOutTxParam().OutboundTxTssNonce) + } else { + continue + } + // + // Get all trackers + trackerResp, err := sm.CctxClient.OutTxTrackerAll(context.Background(), &crosschaintypes.QueryAllOutTxTrackerRequest{}) + if err != nil { + continue + } + + currentMinedTxns := sends[0].GetCurrentOutTxParam().OutboundTxTssNonce + newMinedTxCnt := currentMinedTxns - previousMinedTxns + previousMinedTxns = currentMinedTxns + + // Add new mined txn count to queue and remove the oldest entry + queue = append(queue, newMinedTxCnt) + if numTicks > 60/StatInterval { + totalMinedTxns -= queue[0] + queue = queue[1:] + numTicks = 60/StatInterval + 1 //prevent overflow + } + + //Calculate rate -> tx/min + totalMinedTxns += queue[len(queue)-1] + rate := totalMinedTxns + + numPending := len(cctxResp.CrossChainTx) + numTrackers := len(trackerResp.OutTxTracker) + + fmt.Println("Network Stat => Num of Pending cctx: ", numPending, "Num active trackers: ", numTrackers, "Tx Rate: ", rate, " tx/min") + } + } +} + +func WithdrawETHZRC20(sm *runner.SmokeTestRunner) { + defer func() { + zevmNonce.Add(zevmNonce, big.NewInt(1)) + }() + + ethZRC20 := sm.ETHZRC20 + + sm.ZevmAuth.Nonce = zevmNonce + _, err := ethZRC20.Withdraw(sm.ZevmAuth, local.DeployerAddress.Bytes(), big.NewInt(100)) + if err != nil { + panic(err) + } +} + +// Get ETH based chain ID +func getChainID(client *ethclient.Client) (*big.Int, error) { + return client.ChainID(context.Background()) +} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go index f4aabbcf8b..170e8a644c 100644 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go +++ b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go @@ -112,7 +112,7 @@ func localSmokeTest(cmd *cobra.Command, _ []string) { }() // initialize smoke tests config - conf, err := getConfig(cmd) + conf, err := GetConfig(cmd) if err != nil { panic(err) } diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go index 4ca541a406..3cc27582dc 100644 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go +++ b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go @@ -24,8 +24,8 @@ import ( "google.golang.org/grpc" ) -// getConfig returns config from file from the command line flag -func getConfig(cmd *cobra.Command) (config.Config, error) { +// GetConfig returns config from file from the command line flag +func GetConfig(cmd *cobra.Command) (config.Config, error) { configFile, err := cmd.Flags().GetString(flagConfigFile) if err != nil { return config.Config{}, err diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/stress.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/stress.go deleted file mode 100644 index 670922056f..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/stress.go +++ /dev/null @@ -1,321 +0,0 @@ -package main - -//import ( -// "context" -// "errors" -// "fmt" -// "math/big" -// "os" -// "sort" -// "time" -// -// authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -// banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -// "github.com/ethereum/go-ethereum/accounts/abi/bind" -// ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ethereum/go-ethereum/crypto" -// "github.com/ethereum/go-ethereum/ethclient" -// "github.com/spf13/cobra" -// "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" -// crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" -// fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" -// observertypes "github.com/zeta-chain/zetacore/x/observer/types" -// "google.golang.org/grpc" -//) -// -//const ( -// StatInterval = 5 -// StressTestTimeout = 100 * time.Minute -//) -// -//var ( -// zevmNonce = big.NewInt(1) -//) -// -//var StressCmd = &cobra.Command{ -// Use: "stress", -// Short: "Run Local Stress Test", -// Run: StressTest, -//} -// -//type stressArguments struct { -// ethURL string -// grpcURL string -// zevmURL string -// deployerAddress string -// deployerPrivateKey string -// network string -// txnInterval int64 -//} -// -//var stressTestArgs = stressArguments{} -// -//func init() { -// RootCmd.AddCommand(StressCmd) -// StressCmd.Flags().StringVar(&stressTestArgs.ethURL, "ethURL", "http://eth:8545", "--ethURL http://eth:8545") -// StressCmd.Flags().StringVar(&stressTestArgs.grpcURL, "grpcURL", "zetacore0:9090", "--grpcURL zetacore0:9090") -// StressCmd.Flags().StringVar(&stressTestArgs.zevmURL, "zevmURL", zevmRPC, "--zevmURL http://zetacore0:8545") -// StressCmd.Flags().StringVar(&stressTestArgs.deployerAddress, "addr", "0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC", "--addr ") -// StressCmd.Flags().StringVar(&stressTestArgs.deployerPrivateKey, "privKey", "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263", "--privKey ") -// StressCmd.Flags().StringVar(&stressTestArgs.network, "network", "PRIVNET", "--network PRIVNET") -// StressCmd.Flags().Int64Var(&stressTestArgs.txnInterval, "tx-interval", 500, "--tx-interval [TIME_INTERVAL_MILLISECONDS]") -// -// DeployerAddress = ethcommon.HexToAddress(stressTestArgs.deployerAddress) -//} -// -//func StressTest(_ *cobra.Command, _ []string) { -// testStartTime := time.Now() -// defer func() { -// fmt.Println("Smoke test took", time.Since(testStartTime)) -// }() -// go func() { -// time.Sleep(StressTestTimeout) -// fmt.Println("Smoke test timed out after", StressTestTimeout) -// os.Exit(1) -// }() -// -// goerliClient, err := ethclient.Dial(stressTestArgs.ethURL) -// if err != nil { -// panic(err) -// } -// -// bal, err := goerliClient.BalanceAt(context.TODO(), DeployerAddress, nil) -// if err != nil { -// panic(err) -// } -// fmt.Printf("Deployer address: %s, balance: %d Wei\n", DeployerAddress.Hex(), bal) -// -// chainid, err := goerliClient.ChainID(context.Background()) -// if err != nil { -// panic(err) -// } -// deployerPrivkey, err := crypto.HexToECDSA(stressTestArgs.deployerPrivateKey) -// if err != nil { -// panic(err) -// } -// goerliAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) -// if err != nil { -// panic(err) -// } -// -// grpcConn, err := grpc.Dial(stressTestArgs.grpcURL, grpc.WithInsecure()) -// if err != nil { -// panic(err) -// } -// -// cctxClient := crosschaintypes.NewQueryClient(grpcConn) -// fungibleClient := fungibletypes.NewQueryClient(grpcConn) -// bankClient := banktypes.NewQueryClient(grpcConn) -// authClient := authtypes.NewQueryClient(grpcConn) -// observerClient := observertypes.NewQueryClient(grpcConn) -// -// // Wait for Genesis and keygen to be completed. ~ height 30 -// time.Sleep(20 * time.Second) -// for { -// time.Sleep(5 * time.Second) -// response, err := cctxClient.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) -// if err != nil { -// fmt.Printf("cctxClient.LastZetaHeight error: %s", err) -// continue -// } -// if response.Height >= 30 { -// break -// } -// fmt.Printf("Last ZetaHeight: %d\n", response.Height) -// } -// -// // get the clients for tests -// var zevmClient *ethclient.Client -// for { -// time.Sleep(5 * time.Second) -// fmt.Printf("dialing zevm client: %s\n", stressTestArgs.zevmURL) -// zevmClient, err = ethclient.Dial(stressTestArgs.zevmURL) -// if err != nil { -// continue -// } -// break -// } -// chainid, err = zevmClient.ChainID(context.Background()) -// if err != nil { -// panic(err) -// } -// zevmAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) -// if err != nil { -// panic(err) -// } -// -// smokeTest := NewSmokeTest( -// goerliClient, -// zevmClient, -// cctxClient, -// ZetaTxServer{}, // not used in stress test -// fungibleClient, -// authClient, -// bankClient, -// observerClient, -// goerliAuth, -// zevmAuth, -// nil, -// ) -// -// // If stress test is running on local docker environment -// if stressTestArgs.network == "PRIVNET" { -// smokeTest.TestSetupZetaTokenAndConnectorAndZEVMContracts() -// smokeTest.TestDepositEtherIntoZRC20() -// smokeTest.TestSendZetaIn() -// } else if stressTestArgs.network == "TESTNET" { -// ethZRC20Addr, err := smokeTest.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(5)) -// if err != nil { -// panic(err) -// } -// smokeTest.ETHZRC20Addr = ethZRC20Addr -// smokeTest.ETHZRC20, err = zrc20.NewZRC20(smokeTest.ETHZRC20Addr, smokeTest.zevmClient) -// if err != nil { -// panic(err) -// } -// } else { -// err := errors.New("invalid network argument: " + stressTestArgs.network) -// panic(err) -// } -// -// // Check zrc20 balance of Deployer address -// ethZRC20Balance, err := smokeTest.ETHZRC20.BalanceOf(nil, DeployerAddress) -// if err != nil { -// panic(err) -// } -// fmt.Printf("eth zrc20 balance: %s Wei \n", ethZRC20Balance.String()) -// -// //Pre-approve ETH withdraw on ZEVM -// fmt.Printf("approving ETH ZRC20...\n") -// ethZRC20 := smokeTest.ETHZRC20 -// tx, err := ethZRC20.Approve(smokeTest.zevmAuth, smokeTest.ETHZRC20Addr, big.NewInt(1e18)) -// if err != nil { -// panic(err) -// } -// receipt := MustWaitForTxReceipt(smokeTest.zevmClient, tx) -// fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) -// -// // Get current nonce on zevm for DeployerAddress - Need to keep track of nonce at client level -// blockNum, err := smokeTest.zevmClient.BlockNumber(context.Background()) -// if err != nil { -// panic(err) -// } -// -// // #nosec G701 smoketest - always in range -// nonce, err := smokeTest.zevmClient.NonceAt(context.Background(), DeployerAddress, big.NewInt(int64(blockNum))) -// if err != nil { -// panic(err) -// } -// -// // #nosec G701 smoketest - always in range -// zevmNonce = big.NewInt(int64(nonce)) -// -// // -------------- TEST BEGINS ------------------ -// -// fmt.Println("**** STRESS TEST BEGINS ****") -// fmt.Println(" 1. Periodically Withdraw ETH from ZEVM to EVM - goerli") -// fmt.Println(" 2. Display Network metrics to monitor performance [Num Pending outbound tx], [Num Trackers]") -// -// smokeTest.wg.Add(2) -// go smokeTest.WithdrawCCtx() // Withdraw USDT from ZEVM to EVM - goerli -// go smokeTest.EchoNetworkMetrics() // Display Network metrics periodically to monitor performance -// -// smokeTest.wg.Wait() -//} -// -//// WithdrawCCtx withdraw USDT from ZEVM to EVM -//func (sm *SmokeTest) WithdrawCCtx() { -// ticker := time.NewTicker(time.Millisecond * time.Duration(stressTestArgs.txnInterval)) -// for { -// select { -// case <-ticker.C: -// sm.WithdrawETHZRC20() -// } -// } -//} -// -//func (sm *SmokeTest) EchoNetworkMetrics() { -// ticker := time.NewTicker(time.Second * StatInterval) -// var queue = make([]uint64, 0) -// var numTicks = 0 -// var totalMinedTxns = uint64(0) -// var previousMinedTxns = uint64(0) -// -// for { -// select { -// case <-ticker.C: -// numTicks++ -// // Get all pending outbound transactions -// cctxResp, err := sm.cctxClient.CctxListPending(context.Background(), &crosschaintypes.QueryListCctxPendingRequest{ -// ChainId: getChainID(), -// }) -// if err != nil { -// continue -// } -// sends := cctxResp.CrossChainTx -// sort.Slice(sends, func(i, j int) bool { -// return sends[i].GetCurrentOutTxParam().OutboundTxTssNonce < sends[j].GetCurrentOutTxParam().OutboundTxTssNonce -// }) -// if len(sends) > 0 { -// fmt.Printf("pending nonces %d to %d\n", sends[0].GetCurrentOutTxParam().OutboundTxTssNonce, sends[len(sends)-1].GetCurrentOutTxParam().OutboundTxTssNonce) -// } else { -// continue -// } -// // -// // Get all trackers -// trackerResp, err := sm.cctxClient.OutTxTrackerAll(context.Background(), &crosschaintypes.QueryAllOutTxTrackerRequest{}) -// if err != nil { -// continue -// } -// -// currentMinedTxns := sends[0].GetCurrentOutTxParam().OutboundTxTssNonce -// newMinedTxCnt := currentMinedTxns - previousMinedTxns -// previousMinedTxns = currentMinedTxns -// -// // Add new mined txn count to queue and remove the oldest entry -// queue = append(queue, newMinedTxCnt) -// if numTicks > 60/StatInterval { -// totalMinedTxns -= queue[0] -// queue = queue[1:] -// numTicks = 60/StatInterval + 1 //prevent overflow -// } -// -// //Calculate rate -> tx/min -// totalMinedTxns += queue[len(queue)-1] -// rate := totalMinedTxns -// -// numPending := len(cctxResp.CrossChainTx) -// numTrackers := len(trackerResp.OutTxTracker) -// -// fmt.Println("Network Stat => Num of Pending cctx: ", numPending, "Num active trackers: ", numTrackers, "Tx Rate: ", rate, " tx/min") -// } -// } -//} -// -//func (sm *SmokeTest) WithdrawETHZRC20() { -// defer func() { -// zevmNonce.Add(zevmNonce, big.NewInt(1)) -// }() -// -// ethZRC20 := sm.ETHZRC20 -// -// sm.zevmAuth.Nonce = zevmNonce -// _, err := ethZRC20.Withdraw(sm.zevmAuth, DeployerAddress.Bytes(), big.NewInt(100)) -// if err != nil { -// panic(err) -// } -//} -// -//// Get ETH based chain ID - Build flags are conflicting with current lib, need to do this manually -//func getChainID() int64 { -// switch stressTestArgs.network { -// case "PRIVNET": -// return 1337 -// case "TESTNET": -// return 5 -// case "MAINNET": -// return 1 -// default: -// return 1337 -// } -//} From b2826b7d31cd6a15d89f32f7390943bdd9a9a1cb Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 23 Jan 2024 13:34:24 -0500 Subject: [PATCH 47/67] chore: increment hanlder to v12.1.0 (#1615) * increment hanlder to v12.1.0 * fix upgrade test * add changelog entry --------- Co-authored-by: lumtis --- Dockerfile-versioned-source | 2 +- Makefile | 2 +- app/setup_handlers.go | 6 +----- changelog.md | 5 +++++ 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Dockerfile-versioned-source b/Dockerfile-versioned-source index f6b90d5126..67c4ac4273 100644 --- a/Dockerfile-versioned-source +++ b/Dockerfile-versioned-source @@ -17,7 +17,7 @@ WORKDIR /go/delivery/zeta-node RUN mkdir -p $GOPATH/bin/old RUN mkdir -p $GOPATH/bin/new -ENV NEW_VERSION=v12.0.0 +ENV NEW_VERSION=v12.1.0 # Build new release from the current source COPY go.mod /go/delivery/zeta-node/ diff --git a/Makefile b/Makefile index 34862f40e3..2fe0da31cd 100644 --- a/Makefile +++ b/Makefile @@ -240,7 +240,7 @@ stateful-upgrade: stateful-upgrade-source: @echo "--> Starting stateful smoketest" - $(DOCKER) build --build-arg old_version=v11.0.0-patch-core-params -t zetanode -f ./Dockerfile-versioned-source . + $(DOCKER) build --build-arg old_version=v12.0.0 -t zetanode -f ./Dockerfile-versioned-source . $(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile-upgrade.fastbuild . cd contrib/localnet/ && $(DOCKER) compose -f docker-compose-stateful.yml up -d diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 533679f243..8619fa046f 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -5,11 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -const releaseVersion = "v12.0.0" +const releaseVersion = "v12.1.0" func SetupHandlers(app *App) { app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { @@ -18,8 +16,6 @@ func SetupHandlers(app *App) { for m, mb := range app.mm.Modules { vm[m] = mb.ConsensusVersion() } - vm[crosschaintypes.ModuleName] = 3 - vm[observertypes.ModuleName] = 4 return app.mm.RunMigrations(ctx, app.configurator, vm) }) diff --git a/changelog.md b/changelog.md index c6396ae86f..037accc506 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,9 @@ ## Unreleased + +## Version: v12.1.0 + ### Tests * [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests @@ -21,6 +24,8 @@ ### Chores * [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions +* [1615](https://github.com/zeta-chain/node/pull/1615) - Add upgrade handler for version v12.1.0 + ## Version: v12.0.0 From d940b9445413a8563115d537407218a65066435d Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 25 Jan 2024 09:03:05 -0800 Subject: [PATCH 48/67] fix: cherry-pick ZetaClient fixes from `12.0.4` (#1631) * refactor(`hotfix`): support retrying sending inbound vote with higher gas limit (#1601) * chore: v12.0.0 changelog (#1578) * fix: skip unsupported chain parameters (#1581) Co-authored-by: Lucas Bertrand * remove debug zetaclient1 * remove comments * tx resend * complete renaming * change log level and create constants * increase retry value * test change gas limit for outbound * refactor vote inbound outbound into separate files * add monitoring capability for outbound txs * changelog --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> * fix: some necessary code refactor for banned address and bug fix during refactor (#1603) * cherry picked: fixed ChainParams equality check and added changelog entry * respect isSupported in zetaclient observation * add some RPC diagnosis log * guard against multiple deposits * make cosmos go sec linter happy * update e2e tests * Update zetaclient/bitcoin_client.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --------- Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Co-authored-by: Charlie Chen Co-authored-by: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> --- changelog.md | 15 +- cmd/zetae2e/local/erc20.go | 1 - .../scripts/start-zetaclientd-genesis.sh | 2 +- contrib/localnet/scripts/start-zetaclientd.sh | 2 +- zetaclient/bitcoin_client.go | 55 ++++- zetaclient/broadcast.go | 8 +- zetaclient/btc_signer.go | 4 +- zetaclient/evm_client.go | 135 ++++++++---- zetaclient/inbound_tracker.go | 81 ++++--- zetaclient/interfaces.go | 4 +- zetaclient/telemetry.go | 1 + zetaclient/tx.go | 202 ++---------------- zetaclient/tx_vote_inbound.go | 153 +++++++++++++ zetaclient/tx_vote_outbound.go | 154 +++++++++++++ zetaclient/utils.go | 87 ++++---- zetaclient/voter_test.go | 12 +- zetaclient/zetacore_observer_test.go | 8 +- 17 files changed, 593 insertions(+), 331 deletions(-) create mode 100644 zetaclient/tx_vote_inbound.go create mode 100644 zetaclient/tx_vote_outbound.go diff --git a/changelog.md b/changelog.md index 037accc506..01cee846e4 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,6 @@ ## Unreleased - ## Version: v12.1.0 ### Tests @@ -16,6 +15,8 @@ * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic * [1650](https://github.com/zeta-chain/node/pull/1605) - exempt (discounted) *system txs* from min gas price check and gas fee deduction +* [1576](https://github.com/zeta-chain/node/pull/1576) - Fix zetaclient crash due to out of bound integer conversion and log prints. +* [1575](https://github.com/zeta-chain/node/issues/1575) - Skip unsupported chain parameters by IsSupported flag ### CI @@ -26,6 +27,10 @@ * [1585](https://github.com/zeta-chain/node/pull/1585) - Updated release instructions * [1615](https://github.com/zeta-chain/node/pull/1615) - Add upgrade handler for version v12.1.0 +### Features + +* [1591](https://github.com/zeta-chain/node/pull/1591) - support lower gas limit for voting on inbound and outbound transactions +* [1592](https://github.com/zeta-chain/node/issues/1592) - check inbound tracker tx hash against Tss address and some refactor on inTx observation ## Version: v12.0.0 @@ -49,8 +54,6 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * `GetTssAddress` : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoin chain id can now be passed as a parameter to fetch the correct tss for required BTC chain. This parameter only affects the BTC tss address in the response. ### Features - -* [1549](https://github.com/zeta-chain/node/pull/1549) - add monitoring for vote tx results in ZetaClient * [1498](https://github.com/zeta-chain/node/pull/1498) - Add monitoring(grafana, prometheus, ethbalance) for localnet testing * [1395](https://github.com/zeta-chain/node/pull/1395) - Add state variable to track aborted zeta amount * [1410](https://github.com/zeta-chain/node/pull/1410) - `snapshots` commands @@ -60,8 +63,6 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c ### Fixes -* [1576](https://github.com/zeta-chain/node/pull/1576) - Fix zetaclient crash due to out of bound integer conversion and log prints. -* [1575](https://github.com/zeta-chain/node/issues/1575) - Skip unsupported chain parameters by IsSupported flag * [1554](https://github.com/zeta-chain/node/pull/1554) - Screen out unconfirmed UTXOs that are not created by TSS itself * [1560](https://github.com/zeta-chain/node/issues/1560) - Zetaclient post evm-chain outtx hashes only when receipt is available * [1516](https://github.com/zeta-chain/node/issues/1516) - Unprivileged outtx tracker removal @@ -80,7 +81,6 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta * [1528](https://github.com/zeta-chain/node/pull/1528) - fix panic caused on decoding malformed BTC addresses -* [1557](https://github.com/zeta-chain/node/pull/1557) - remove decreaseAllowance and increaseAllowance checks * [1536](https://github.com/zeta-chain/node/pull/1536) - add index to check previously finalized inbounds * [1556](https://github.com/zeta-chain/node/pull/1556) - add emptiness check for topic array in event parsing * [1546](https://github.com/zeta-chain/node/pull/1546) - fix reset of pending nonces on genesis import @@ -109,7 +109,6 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * Update --ledger flag hint ### Chores - * [1446](https://github.com/zeta-chain/node/pull/1446) - renamed file `zetaclientd/aux.go` to `zetaclientd/utils.go` to avoid complaints from go package resolver. * [1499](https://github.com/zeta-chain/node/pull/1499) - Add scripts to localnet to help test gov proposals * [1442](https://github.com/zeta-chain/node/pull/1442) - remove build types in `.goreleaser.yaml` @@ -121,9 +120,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1538](https://github.com/zeta-chain/node/pull/1538) - improve stateful e2e testing ### CI - * Removed private runners and unused GitHub Action -* Adding typescript publishing pipeline. ## Version: v11.0.0 diff --git a/cmd/zetae2e/local/erc20.go b/cmd/zetae2e/local/erc20.go index 8e5a286fa8..66703121e8 100644 --- a/cmd/zetae2e/local/erc20.go +++ b/cmd/zetae2e/local/erc20.go @@ -62,7 +62,6 @@ func erc20TestRoutine( // run erc20 test if err := erc20Runner.RunSmokeTestsFromNames( smoketests.AllSmokeTests, - smoketests.TestMultipleERC20DepositName, smoketests.TestWithdrawERC20Name, smoketests.TestMultipleWithdrawsName, smoketests.TestERC20DepositAndCallRefundName, diff --git a/contrib/localnet/scripts/start-zetaclientd-genesis.sh b/contrib/localnet/scripts/start-zetaclientd-genesis.sh index 7c23cd0673..5f2cadceab 100755 --- a/contrib/localnet/scripts/start-zetaclientd-genesis.sh +++ b/contrib/localnet/scripts/start-zetaclientd-genesis.sh @@ -36,6 +36,6 @@ else SEED=$(curl --retry 10 --retry-delay 5 --retry-connrefused -s zetaclient0:8123/p2p) done rm ~/.tss/* - zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 0 --keyring-backend "$BACKEND" + zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" zetaclientd start fi diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index 14de0fada6..eecb8b8e5d 100644 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -23,6 +23,6 @@ else zetaclientd init \ --peer /ip4/172.20.0.21/tcp/6668/p2p/$SEED \ --pre-params ~/preParams.json --zetacore-url $node \ - --chain-id athens_101-1 --operator zeta1lz2fqwzjnk6qy48fgj753h48444fxtt7hekp52 --log-level 0 --hotkey=val_grantee_observer + --chain-id athens_101-1 --operator zeta1lz2fqwzjnk6qy48fgj753h48444fxtt7hekp52 --log-level 1 --hotkey=val_grantee_observer zetaclientd start fi diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index a82e3a44cb..d802d2b953 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -11,6 +11,7 @@ import ( "strconv" "sync" "sync/atomic" + "time" cosmosmath "cosmossdk.io/math" "github.com/btcsuite/btcd/btcjson" @@ -199,6 +200,54 @@ func (ob *BitcoinChainClient) Start() { go ob.WatchUTXOS() go ob.WatchGasPrice() go ob.ExternalChainWatcherForNewInboundTrackerSuggestions() + go ob.RPCStatus() +} + +func (ob *BitcoinChainClient) RPCStatus() { + ob.logger.ChainLogger.Info().Msgf("RPCStatus is starting") + ticker := time.NewTicker(60 * time.Second) + + for { + select { + case <-ticker.C: + //ob.logger.ChainLogger.Info().Msgf("RPCStatus is running") + bn, err := ob.rpcClient.GetBlockCount() + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC status check: RPC down? ") + continue + } + hash, err := ob.rpcClient.GetBlockHash(bn) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC status check: RPC down? ") + continue + } + header, err := ob.rpcClient.GetBlockHeader(hash) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC status check: RPC down? ") + continue + } + blockTime := header.Timestamp + elapsedSeconds := time.Since(blockTime).Seconds() + if elapsedSeconds > 1200 { + ob.logger.ChainLogger.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.ChainLogger.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.ChainLogger.Error().Err(err).Msg("RPC status check: TSS address has no utxos; TSS address is not imported? ") + continue + } + ob.logger.ChainLogger.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: + return + } + } } func (ob *BitcoinChainClient) Stop() { @@ -385,12 +434,12 @@ func (ob *BitcoinChainClient) observeInTx() error { // post inbound vote message to zetacore for _, inTx := range inTxs { msg := ob.GetInboundVoteMessageFromBtcEvent(inTx) - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.WatchInTx.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.WatchInTx.Info().Msgf("observeInTxBTC: BTC deposit detected and reported: PostSend zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.WatchInTx.Info().Msgf("observeInTxBTC: BTC deposit detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) } } @@ -470,7 +519,7 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 } logger.Debug().Msgf("Bitcoin outTx confirmed: txid %s, amount %s\n", res.TxID, amountInSat.String()) - zetaHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, res.TxID, // #nosec G701 always positive diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index 8c1a86e70d..97870d3791 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -57,7 +57,6 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg b.seqNumber[authzSigner.KeyType] = seqNumber } } - //b.logger.Info().Uint64("account_number", b.accountNumber).Uint64("sequence_number", b.seqNumber).Msg("account info") flags := flag.NewFlagSet("zetacore", 0) @@ -73,12 +72,13 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg if err != nil { return "", err } + builder.SetGasLimit(gaslimit) + // #nosec G701 always in range fee := sdktypes.NewCoins(sdktypes.NewCoin(config.BaseDenom, cosmos.NewInt(int64(gaslimit)).Mul(adjustedBaseGasPrice.Ceil().RoundInt()))) builder.SetFeeAmount(fee) - //fmt.Printf("signing from name: %s\n", ctx.GetFromName()) err = b.SignTx(factory, ctx.GetFromName(), builder, true, ctx.TxConfig) if err != nil { return "", err @@ -94,6 +94,7 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg b.logger.Error().Err(err).Msgf("fail to broadcast tx %s", err.Error()) return "", err } + // Code will be the tendermint ABICode , it start at 1 , so if it is an error , code will not be zero if commit.Code > 0 { if commit.Code == 32 { @@ -118,11 +119,8 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg } return commit.TxHash, fmt.Errorf("fail to broadcast to zetachain,code:%d, log:%s", commit.Code, commit.RawLog) } - //b.logger.Debug().Msgf("Received a TxHash of %v from the metachain, Code %d, log %s", commit.TxHash, commit.Code, commit.Logs) // increment seqNum - //seq := b.seqNumber[authzSigner.KeyType] - //atomic.AddUint64(&seq, 1) b.seqNumber[authzSigner.KeyType] = b.seqNumber[authzSigner.KeyType] + 1 return commit.TxHash, nil diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index d175c9af71..ba493a9fce 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -119,11 +119,11 @@ func (signer *BTCSigner) SignWithdrawTx( signer.logger.Info().Msgf("sizeLimit %d is less than txSize %d for nonce %d", sizeLimit, txSize, nonce) } if txSize < outTxBytesMin { // outbound shouldn't be blocked a low sizeLimit - signer.logger.Warn().Msgf("sizeLimit %d is less than outTxBytesMin %d; use outTxBytesMin", sizeLimit, outTxBytesMin) + signer.logger.Warn().Msgf("txSize %d is less than outTxBytesMin %d; use outTxBytesMin", txSize, outTxBytesMin) txSize = outTxBytesMin } if txSize > outTxBytesMax { // in case of accident - signer.logger.Warn().Msgf("sizeLimit %d is greater than outTxBytesMax %d; use outTxBytesMax", sizeLimit, outTxBytesMax) + signer.logger.Warn().Msgf("txSize %d is greater than outTxBytesMax %d; use outTxBytesMax", txSize, outTxBytesMax) txSize = outTxBytesMax } diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index d88ee980f9..36d5ee0570 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -1,7 +1,6 @@ package zetaclient import ( - "bytes" "context" "fmt" "math" @@ -283,6 +282,42 @@ func (ob *EVMChainClient) Start() { go ob.ExternalChainWatcher() // Observes external Chains for incoming trasnactions go ob.WatchGasPrice() // Observes external Chains for Gas prices and posts to core go ob.observeOutTx() // Populates receipts and confirmed outbound transactions + go ob.ExternalChainRPCStatus() +} + +func (ob *EVMChainClient) ExternalChainRPCStatus() { + ob.logger.ChainLogger.Info().Msgf("Starting RPC status check for chain %s", ob.chain.String()) + ticker := time.NewTicker(60 * time.Second) + for { + select { + case <-ticker.C: + bn, err := ob.evmClient.BlockNumber(context.Background()) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC Status Check error: RPC down?") + continue + } + gasPrice, err := ob.evmClient.SuggestGasPrice(context.Background()) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC Status Check error: RPC down?") + continue + } + header, err := ob.evmClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(bn)) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("RPC Status Check error: RPC down?") + continue + } + // #nosec G701 always in range + blockTime := time.Unix(int64(header.Time), 0).UTC() + elapsedSeconds := time.Since(blockTime).Seconds() + if elapsedSeconds > 100 { + ob.logger.ChainLogger.Warn().Msgf("RPC Status Check warning: RPC stale or chain stuck (check explorer)? Latest block %d timestamp is %.0fs ago", bn, elapsedSeconds) + continue + } + ob.logger.ChainLogger.Info().Msgf("[OK] RPC status: latest block num %d, timestamp %s ( %.0fs ago), suggested gas price %d", header.Number, blockTime.String(), elapsedSeconds, gasPrice.Uint64()) + case <-ob.stop: + return + } + } } func (ob *EVMChainClient) Stop() { @@ -318,7 +353,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co if receipt.Status == 1 { recvStatus = common.ReceiveStatus_Success } - zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, receipt.TxHash.Hex(), receipt.BlockNumber.Uint64(), @@ -340,7 +375,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } else if cointype == common.CoinType_Gas { // the outbound is a regular Ether/BNB/Matic transfer; no need to check events if receipt.Status == 1 { - zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, receipt.TxHash.Hex(), receipt.BlockNumber.Uint64(), @@ -361,7 +396,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co 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.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, receipt.TxHash.Hex(), receipt.BlockNumber.Uint64(), @@ -375,7 +410,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co common.CoinType_Gas, ) if err != nil { - logger.Error().Err(err).Msgf("PostReceiveConfirmation error in WatchTxHashWithTimeout; zeta tx hash %s cctx %s nonce %d", zetaTxHash, sendHash, nonce) + 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) } @@ -405,7 +440,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co sendhash := vLog.Topics[3].Hex() //var rxAddress string = ethcommon.HexToAddress(vLog.Topics[1].Hex()).Hex() mMint := receivedLog.ZetaValue - zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendhash, vLog.TxHash.Hex(), vLog.BlockNumber, @@ -442,7 +477,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } sendhash := vLog.Topics[2].Hex() mMint := revertedLog.RemainingZetaValue - zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendhash, vLog.TxHash.Hex(), vLog.BlockNumber, @@ -470,7 +505,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } 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.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, receipt.TxHash.Hex(), receipt.BlockNumber.Uint64(), @@ -510,7 +545,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } if confHeight <= ob.GetLastBlockHeight() { logger.Info().Msg("Confirmed! Sending PostConfirmation to zetacore...") - zetaTxHash, ballot, err := ob.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, vLog.TxHash.Hex(), vLog.BlockNumber, @@ -537,7 +572,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co } } 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.zetaClient.PostReceiveConfirmation( + zetaTxHash, ballot, err := ob.zetaClient.PostVoteOutbound( sendHash, receipt.TxHash.Hex(), receipt.BlockNumber.Uint64(), @@ -551,7 +586,7 @@ func (ob *EVMChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64, co common.CoinType_ERC20, ) if err != nil { - logger.Error().Err(err).Msgf("PostReceiveConfirmation error in WatchTxHashWithTimeout; zeta tx hash %s", zetaTxHash) + 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) } @@ -980,13 +1015,11 @@ func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { if event.Raw.BlockNumber > beingScanned { beingScanned = event.Raw.BlockNumber } - msg, err := ob.GetInboundVoteMsgForZetaSentEvent(event) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( - "observeZetaSent: error getting inbound vote msg for tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + msg := ob.GetInboundVoteMsgForZetaSentEvent(event) + if msg == nil { continue } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendNonEVMGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeZetaSent: error posting event to zeta core for tx %s at height %d for chain %d", @@ -994,7 +1027,7 @@ func (ob *EVMChainClient) observeZetaSent(startBlock, toBlock uint64) uint64 { return beingScanned - 1 // we have to re-scan from this block next time } else if zetaHash != "" { ob.logger.ExternalChainWatcher.Info().Msgf( - "observeZetaSent: event detected in tx %s at height %d for chain %d, PostSend zeta tx: %s ballot %s", + "observeZetaSent: event detected in tx %s at height %d for chain %d, PostVoteInbound zeta tx: %s ballot %s", event.Raw.TxHash.Hex(), event.Raw.BlockNumber, ob.chain.ChainId, zetaHash, ballot) } } @@ -1053,19 +1086,35 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint } // post to zetacore + guard := make(map[string]bool) // guard against multiple events in the same tx beingScanned := uint64(0) for _, event := range events { // remember which block we are scanning (there could be multiple events in the same block) if event.Raw.BlockNumber > beingScanned { beingScanned = event.Raw.BlockNumber } - msg, err := ob.GetInboundVoteMsgForDepositedEvent(event) + tx, _, err := ob.evmClient.TransactionByHash(context.Background(), event.Raw.TxHash) if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( - "observeERC20Deposited: error getting inbound vote msg for tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeERC20Deposited: TransactionByHash error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return beingScanned - 1 // we have to re-scan from this block next time + } + sender, err := ob.GetTransactionSender(tx, event.Raw.BlockHash, event.Raw.TxIndex) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeERC20Deposited: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return beingScanned - 1 // we have to re-scan from this block next time + } + if guard[event.Raw.TxHash.Hex()] { + ob.logger.ExternalChainWatcher.Warn().Msgf("more than one remote call event in a single tx %s; skip the rest", event.Raw.TxHash.Hex()) + continue + } + + msg := ob.GetInboundVoteMsgForDepositedEvent(event, sender) + if msg == nil { continue } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeERC20Deposited: error posting event to zeta core for tx %s at height %d for chain %d", @@ -1073,9 +1122,10 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint return beingScanned - 1 // we have to re-scan from this block next time } else if zetaHash != "" { ob.logger.ExternalChainWatcher.Info().Msgf( - "observeERC20Deposited: event detected in tx %s at height %d for chain %d, PostSend zeta tx: %s ballot %s", + "observeERC20Deposited: event detected in tx %s at height %d for chain %d, PostVoteInbound zeta tx: %s ballot %s", event.Raw.TxHash.Hex(), event.Raw.BlockNumber, ob.chain.ChainId, zetaHash, ballot) } + guard[event.Raw.TxHash.Hex()] = true } // successful processed all events in [startBlock, toBlock] return toBlock @@ -1084,6 +1134,10 @@ func (ob *EVMChainClient) observeERC20Deposited(startBlock, toBlock uint64) uint // observeTssRecvd queries the incoming gas asset to TSS address and posts to zetacore // returns the last block successfully scanned func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags observertypes.CrosschainFlags) uint64 { + if !ob.GetChainParams().IsSupported { + //ob.logger.ExternalChainWatcher.Warn().Msgf("observeTssRecvd: chain %d is not supported", ob.chain.ChainId) + return startBlock - 1 // lastScanned + } // check TSS address (after keygen, ob.Tss.pubkey will be updated) tssAddress := ob.Tss.EVMAddress() if tssAddress == (ethcommon.Address{}) { @@ -1108,54 +1162,44 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse block, err := ob.GetBlockByNumberCached(bn) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("observeTssRecvd: error getting block %d for chain %d", bn, ob.chain.ChainId) - return startBlock - 1 // we have to re-scan from this block next time + return bn - 1 // we have to re-scan from this block next time } for _, tx := range block.Transactions() { if tx.To() == nil { continue } - if bytes.Equal(tx.Data(), []byte(DonationMessage)) { - ob.logger.ExternalChainWatcher.Info().Msgf( - "observeTssRecvd: thank you rich folk for your donation!: %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - continue - } if *tx.To() == tssAddress { receipt, err := ob.evmClient.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { ob.logger.ExternalChainWatcher.Err(err).Msgf( "observeTssRecvd: TransactionReceipt error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - return startBlock - 1 // we have to re-scan this block next time + return bn - 1 // we have to re-scan this block next time } if receipt.Status != 1 { // 1: successful, 0: failed ob.logger.ExternalChainWatcher.Info().Msgf("observeTssRecvd: tx %s chain %d failed; don't act", tx.Hash().Hex(), ob.chain.ChainId) continue } - from, err := ob.evmClient.TransactionSender(context.Background(), tx, block.Hash(), receipt.TransactionIndex) + sender, err := ob.GetTransactionSender(tx, block.Hash(), receipt.TransactionIndex) if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf("observeTssRecvd: TransactionSender error for tx %s", tx.Hash().Hex()) - // trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - from, err = signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf( - "observeTssRecvd: local recovery of sender address failed for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - continue - } + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeTssRecvd: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return bn - 1 // we have to re-scan this block next time } - msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx.Hash(), tx.Value(), receipt, from, tx.Data()) + + msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, receipt.BlockNumber.Uint64()) if msg == nil { continue } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( "observeTssRecvd: error posting to zeta core for tx %s at height %d for chain %d", tx.Hash().Hex(), bn, ob.chain.ChainId) - return startBlock - 1 // we have to re-scan this block next time + return bn - 1 // we have to re-scan this block next time } else if zetaHash != "" { ob.logger.ExternalChainWatcher.Info().Msgf( - "observeTssRecvd: gas asset deposit detected in tx %s at height %d for chain %d, PostSend zeta tx: %s ballot %s", + "observeTssRecvd: gas asset deposit detected in tx %s at height %d for chain %d, PostVoteInbound zeta tx: %s ballot %s", tx.Hash().Hex(), bn, ob.chain.ChainId, zetaHash, ballot) } } @@ -1166,7 +1210,7 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse } func (ob *EVMChainClient) WatchGasPrice() { - + ob.logger.WatchGasPrice.Info().Msg("WatchGasPrice starting...") err := ob.PostGasPrice() if err != nil { height, err := ob.zetaClient.GetBlockHeight() @@ -1182,6 +1226,7 @@ func (ob *EVMChainClient) WatchGasPrice() { ob.logger.WatchGasPrice.Error().Err(err).Msg("NewDynamicTicker error") return } + ob.logger.WatchGasPrice.Info().Msgf("WatchGasPrice started with interval %d", ob.GetChainParams().GasPriceTicker) defer ticker.Stop() for { @@ -1205,6 +1250,7 @@ func (ob *EVMChainClient) WatchGasPrice() { } func (ob *EVMChainClient) PostGasPrice() error { + // GAS PRICE gasPrice, err := ob.evmClient.SuggestGasPrice(context.TODO()) if err != nil { @@ -1226,7 +1272,6 @@ func (ob *EVMChainClient) PostGasPrice() error { return err } _ = zetaHash - //ob.logger.WatchGasPrice.Debug().Msgf("PostGasPrice zeta tx: %s", zetaHash) return nil } diff --git a/zetaclient/inbound_tracker.go b/zetaclient/inbound_tracker.go index 8a7ebd1147..31ea30f06e 100644 --- a/zetaclient/inbound_tracker.go +++ b/zetaclient/inbound_tracker.go @@ -3,11 +3,9 @@ package zetaclient import ( "errors" "fmt" - "math/big" "github.com/btcsuite/btcd/chaincfg/chainhash" ethcommon "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" "golang.org/x/net/context" @@ -114,12 +112,12 @@ func (ob *BitcoinChainClient) CheckReceiptForBtcTxHash(txHash string, vote bool) if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.WatchInTx.Error().Err(err).Msg("error posting to zeta core") return "", err } else if ballot == "" { - ob.logger.WatchInTx.Info().Msgf("BTC deposit detected and reported: PostSend zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.WatchInTx.Info().Msgf("BTC deposit detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) } return msg.Digest(), nil } @@ -172,15 +170,15 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - var msg types.MsgVoteOnObservedInboundTx + var msg *types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { event, err := connector.ParseZetaSent(*log) if err == nil && event != nil { // sanity check tx event err = ob.CheckEvmTxLog(&event.Raw, addrConnector, txHash, TopicsZetaSent) if err == nil { - msg, err = ob.GetInboundVoteMsgForZetaSentEvent(event) - if err == nil { + msg = ob.GetInboundVoteMsgForZetaSentEvent(event) + if msg != nil { break } } else { @@ -188,16 +186,19 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeZeta(txHash string, vote bool) } } } + if msg == nil { + return "", errors.New("no ZetaSent event found") + } if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendNonEVMGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundMessagePassingExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") return "", err } else if zetaHash != "" { - ob.logger.ExternalChainWatcher.Info().Msgf("ZetaSent event detected and reported: PostSend zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.ExternalChainWatcher.Info().Msgf("ZetaSent event detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) } return msg.Digest(), nil @@ -208,11 +209,20 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) if err != nil { return "", err } + // get transaction, receipt and sender hash := ethcommon.HexToHash(txHash) + tx, _, err := ob.evmClient.TransactionByHash(context.Background(), hash) + if err != nil { + return "", err + } receipt, err := ob.evmClient.TransactionReceipt(context.Background(), hash) if err != nil { return "", err } + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, receipt.BlockHash, receipt.TransactionIndex) + if err != nil { + return "", err + } // check if the tx is confirmed lastHeight := ob.GetLastBlockHeight() @@ -220,38 +230,48 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeERC20(txHash string, vote bool) return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - var msg types.MsgVoteOnObservedInboundTx + var msg *types.MsgVoteOnObservedInboundTx for _, log := range receipt.Logs { zetaDeposited, err := custody.ParseDeposited(*log) if err == nil && zetaDeposited != nil { // sanity check tx event err = ob.CheckEvmTxLog(&zetaDeposited.Raw, addrCustory, txHash, TopicsDeposited) if err == nil { - msg, err = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited) + msg = ob.GetInboundVoteMsgForDepositedEvent(zetaDeposited, sender) if err == nil { break } } else { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on Deposited event") + ob.logger.ExternalChainWatcher.Error().Err(err).Msg("CheckEvmTxLog error on ERC20CustodyDeposited event") } } } + if msg == nil { + return "", errors.New("no ERC20CustodyDeposited event found") + } if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, &msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") return "", err } else if zetaHash != "" { - ob.logger.ExternalChainWatcher.Info().Msgf("ERC20 Deposit event detected and reported: PostSend zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.ExternalChainWatcher.Info().Msgf("ERC20 Deposit event detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) } return msg.Digest(), nil } func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) (string, error) { + // TSS address should be set + tssAddress := ob.Tss.EVMAddress() + if tssAddress == (ethcommon.Address{}) { + return "", errors.New("TSS address not set") + } + + // check transaction and receipt hash := ethcommon.HexToHash(txHash) tx, isPending, err := ob.evmClient.TransactionByHash(context.Background(), hash) if err != nil { @@ -260,6 +280,12 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) ( if isPending { return "", errors.New("tx is still pending") } + if tx.To() == nil { + return "", errors.New("tx.To() is nil") + } + if *tx.To() != tssAddress { + return "", fmt.Errorf("tx.To() %s is not TSS address", tssAddress.Hex()) + } receipt, err := ob.evmClient.TransactionReceipt(context.Background(), hash) if err != nil { @@ -270,39 +296,30 @@ func (ob *EVMChainClient) CheckReceiptForCoinTypeGas(txHash string, vote bool) ( ob.logger.ExternalChainWatcher.Info().Msgf("tx %s failed; don't act", tx.Hash().Hex()) return "", errors.New("tx not successful yet") } + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, receipt.BlockHash, receipt.TransactionIndex) + if err != nil { + return "", err + } // check if the tx is confirmed lastHeight := ob.GetLastBlockHeight() if !ob.HasEnoughConfirmations(receipt, lastHeight) { return "", fmt.Errorf("txHash %s has not been confirmed yet: receipt block %d current block %d", txHash, receipt.BlockNumber, lastHeight) } - - block, err := ob.evmClient.BlockByNumber(context.Background(), receipt.BlockNumber) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("BlockByNumber error") - return "", err - } - from, err := ob.evmClient.TransactionSender(context.Background(), tx, block.Hash(), receipt.TransactionIndex) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("TransactionSender error; trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address") - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - from, err = signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msg("local recovery of sender address failed") - return "", err - } + msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, receipt.BlockNumber.Uint64()) + if msg == nil { + return "", errors.New("no message built for token sent to TSS") } - msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx.Hash(), tx.Value(), receipt, from, tx.Data()) if !vote { return msg.Digest(), nil } - zetaHash, ballot, err := ob.zetaClient.PostSend(PostSendEVMGasLimit, msg) + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msg("error posting to zeta core") return "", err } else if zetaHash != "" { - ob.logger.ExternalChainWatcher.Info().Msgf("Gas deposit detected and reported: PostSend zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.ExternalChainWatcher.Info().Msgf("Gas deposit detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) } return msg.Digest(), nil diff --git a/zetaclient/interfaces.go b/zetaclient/interfaces.go index fe2d0824c1..6ca41f59fd 100644 --- a/zetaclient/interfaces.go +++ b/zetaclient/interfaces.go @@ -48,8 +48,8 @@ type ChainSigner interface { // ZetaCoreBridger is the interface to interact with ZetaCore type ZetaCoreBridger interface { - PostSend(zetaGasLimit uint64, msg *crosschaintypes.MsgVoteOnObservedInboundTx) (string, string, error) - PostReceiveConfirmation( + PostVoteInbound(gasLimit, retryGasLimit uint64, msg *crosschaintypes.MsgVoteOnObservedInboundTx) (string, string, error) + PostVoteOutbound( sendHash string, outTxHash string, outBlockHeight uint64, diff --git a/zetaclient/telemetry.go b/zetaclient/telemetry.go index 9255b54247..e43b0e6d99 100644 --- a/zetaclient/telemetry.go +++ b/zetaclient/telemetry.go @@ -133,6 +133,7 @@ func (t *TelemetryServer) Handlers() http.Handler { router.Handle("/status", http.HandlerFunc(t.statusHandler)).Methods(http.MethodGet) 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) diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 38a02052ed..15847c3f80 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -2,15 +2,10 @@ package zetaclient import ( "fmt" - "math/big" - "strings" "time" - "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/pkg/errors" - "github.com/zeta-chain/go-tss/blame" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -19,55 +14,27 @@ import ( ) const ( - PostGasPriceGasLimit = 1_500_000 + // DefaultGasLimit is the default gas limit used for broadcasting txs + DefaultGasLimit = 200_000 + + // PostGasPriceGasLimit is the gas limit for voting new gas price + PostGasPriceGasLimit = 1_500_000 + + // AddTxHashToOutTxTrackerGasLimit is the gas limit for adding tx hash to out tx tracker AddTxHashToOutTxTrackerGasLimit = 200_000 - PostNonceGasLimit = 200_000 - PostSendEVMGasLimit = 4_000_000 // likely emit a lot of logs, so costly - PostSendNonEVMGasLimit = 1_000_000 - PostReceiveConfirmationGasLimit = 400_000 - PostBlameDataGasLimit = 200_000 - DefaultGasLimit = 200_000 - PostProveOutboundTxGasLimit = 400_000 - DefaultRetryCount = 5 - ExtendedRetryCount = 15 - DefaultRetryInterval = 5 -) -// GetInBoundVoteMessage returns a new MsgVoteOnObservedInboundTx -func GetInBoundVoteMessage( - sender string, - senderChain int64, - txOrigin string, - receiver string, - receiverChain int64, - amount math.Uint, - message string, - inTxHash string, - inBlockHeight uint64, - gasLimit uint64, - coinType common.CoinType, - asset string, - signerAddress string, - eventIndex uint, -) *types.MsgVoteOnObservedInboundTx { - msg := types.NewMsgVoteOnObservedInboundTx( - signerAddress, - sender, - senderChain, - txOrigin, - receiver, - receiverChain, - amount, - message, - inTxHash, - inBlockHeight, - gasLimit, - coinType, - asset, - eventIndex, - ) - return msg -} + // PostBlameDataGasLimit is the gas limit for voting on blames + PostBlameDataGasLimit = 200_000 + + // DefaultRetryCount is the number of retries for broadcasting a tx + DefaultRetryCount = 5 + + // ExtendedRetryCount is an extended number of retries for broadcasting a tx, used in keygen operations + ExtendedRetryCount = 15 + + // DefaultRetryInterval is the interval between retries in seconds + DefaultRetryInterval = 5 +) func (b *ZetaCoreBridge) WrapMessageWithAuthz(msg sdk.Msg) (sdk.Msg, AuthZSigner, error) { msgURL := sdk.MsgTypeURL(msg) @@ -126,100 +93,6 @@ func (b *ZetaCoreBridge) AddTxHashToOutTxTracker( return zetaTxHash, nil } -func (b *ZetaCoreBridge) PostSend(zetaGasLimit uint64, msg *types.MsgVoteOnObservedInboundTx) (string, string, error) { - authzMsg, authzSigner, err := b.WrapMessageWithAuthz(msg) - if err != nil { - return "", "", err - } - - // don't post send if has already voted before - ballotIndex := msg.Digest() - hasVoted, err := b.HasVoted(ballotIndex, msg.Creator) - if err != nil { - return "", ballotIndex, errors.Wrapf(err, "PostSend: unable to check if already voted for ballot %s voter %s", ballotIndex, msg.Creator) - } - if hasVoted { - return "", ballotIndex, nil - } - - for i := 0; i < DefaultRetryCount; i++ { - zetaTxHash, err := b.Broadcast(zetaGasLimit, authzMsg, authzSigner) - if err == nil { - // monitor the result of the transaction - go b.MonitorTxResult(zetaTxHash, true) - - return zetaTxHash, ballotIndex, nil - } - b.logger.Debug().Err(err).Msgf("PostSend broadcast fail | Retry count : %d", i+1) - time.Sleep(DefaultRetryInterval * time.Second) - } - return "", ballotIndex, fmt.Errorf("post send failed after %d retries", DefaultRetryInterval) -} - -func (b *ZetaCoreBridge) PostReceiveConfirmation( - sendHash string, - outTxHash string, - outBlockHeight uint64, - outTxGasUsed uint64, - outTxEffectiveGasPrice *big.Int, - outTxEffectiveGasLimit uint64, - amount *big.Int, - status common.ReceiveStatus, - chain common.Chain, - nonce uint64, - coinType common.CoinType, -) (string, string, error) { - signerAddress := b.keys.GetOperatorAddress().String() - msg := types.NewMsgVoteOnObservedOutboundTx( - signerAddress, - sendHash, - outTxHash, - outBlockHeight, - outTxGasUsed, - math.NewIntFromBigInt(outTxEffectiveGasPrice), - outTxEffectiveGasLimit, - math.NewUintFromBigInt(amount), - status, - chain.ChainId, - nonce, - coinType, - ) - - authzMsg, authzSigner, err := b.WrapMessageWithAuthz(msg) - if err != nil { - return "", "", err - } - - // don't post confirmation if has already voted before - ballotIndex := msg.Digest() - hasVoted, err := b.HasVoted(ballotIndex, msg.Creator) - if err != nil { - return "", ballotIndex, errors.Wrapf(err, "PostReceiveConfirmation: unable to check if already voted for ballot %s voter %s", ballotIndex, msg.Creator) - } - if hasVoted { - return "", ballotIndex, nil - } - - // FIXME: remove this gas limit stuff; in the special ante handler with no gas limit, add - // NewMsgReceiveConfirmation to it. - var gasLimit uint64 = PostReceiveConfirmationGasLimit - if status == common.ReceiveStatus_Failed { - gasLimit = PostSendEVMGasLimit - } - for i := 0; i < DefaultRetryCount; i++ { - zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) - if err == nil { - // monitor the result of the transaction - go b.MonitorTxResult(zetaTxHash, true) - - return zetaTxHash, ballotIndex, nil - } - b.logger.Debug().Err(err).Msgf("PostReceive broadcast fail | Retry count : %d", i+1) - time.Sleep(DefaultRetryInterval * time.Second) - } - return "", ballotIndex, fmt.Errorf("post receive failed after %d retries", DefaultRetryCount) -} - func (b *ZetaCoreBridge) SetTSS(tssPubkey string, keyGenZetaHeight int64, status common.ReceiveStatus) (string, error) { signerAddress := b.keys.GetOperatorAddress().String() msg := types.NewMsgCreateTSSVoter(signerAddress, tssPubkey, keyGenZetaHeight, status) @@ -308,40 +181,3 @@ func (b *ZetaCoreBridge) PostAddBlockHeader(chainID int64, blockHash []byte, hei } return "", fmt.Errorf("post add block header failed after %d retries", DefaultRetryCount) } - -// MonitorTxResult monitors the result of a tx (used for inbound and outbound vote txs) -func (b *ZetaCoreBridge) MonitorTxResult(zetaTxHash string, isInbound bool) { - var lastErr error - ticker := 5 * time.Second - retry := 10 - prefix := "MonitorOutboundTxResult" - if isInbound { - prefix = "MonitorInboundTxResult" - } - - for i := 0; i < retry; i++ { - time.Sleep(ticker) - txResult, err := b.QueryTxResult(zetaTxHash) - if err == nil { - // the inbound vote tx shouldn't fail to execute - if strings.Contains(txResult.RawLog, "failed to execute message") { - b.logger.Error().Msgf( - "%s: failed to execute vote, txHash: %s, txResult %s", - prefix, - zetaTxHash, - txResult.String(), - ) - } - return - } - lastErr = err - } - - b.logger.Error().Err(lastErr).Msgf( - "%s: unable to query tx result for txHash %s, err %s", - prefix, - zetaTxHash, - lastErr.Error(), - ) - return -} diff --git a/zetaclient/tx_vote_inbound.go b/zetaclient/tx_vote_inbound.go new file mode 100644 index 0000000000..1e5807474f --- /dev/null +++ b/zetaclient/tx_vote_inbound.go @@ -0,0 +1,153 @@ +package zetaclient + +import ( + "fmt" + "strings" + "time" + + "cosmossdk.io/math" + "github.com/zeta-chain/zetacore/common" + + "github.com/pkg/errors" + + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +const ( + // PostVoteInboundGasLimit is the gas limit for voting on observed inbound tx + PostVoteInboundGasLimit = 400_000 + + // PostVoteInboundExecutionGasLimit is the gas limit for voting on observed inbound tx and executing it + PostVoteInboundExecutionGasLimit = 4_000_000 + + // PostVoteInboundMessagePassingExecutionGasLimit is the gas limit for voting on, and executing ,observed inbound tx related to message passing (coin_type == zeta) + PostVoteInboundMessagePassingExecutionGasLimit = 1_000_000 + + // MonitorVoteInboundTxResultInterval is the interval between retries for monitoring tx result in seconds + MonitorVoteInboundTxResultInterval = 5 + + // MonitorVoteInboundTxResultRetryCount is the number of retries to fetch monitoring tx result + MonitorVoteInboundTxResultRetryCount = 20 +) + +// GetInBoundVoteMessage returns a new MsgVoteOnObservedInboundTx +func GetInBoundVoteMessage( + sender string, + senderChain int64, + txOrigin string, + receiver string, + receiverChain int64, + amount math.Uint, + message string, + inTxHash string, + inBlockHeight uint64, + gasLimit uint64, + coinType common.CoinType, + asset string, + signerAddress string, + eventIndex uint, +) *types.MsgVoteOnObservedInboundTx { + msg := types.NewMsgVoteOnObservedInboundTx( + signerAddress, + sender, + senderChain, + txOrigin, + receiver, + receiverChain, + amount, + message, + inTxHash, + inBlockHeight, + gasLimit, + coinType, + asset, + eventIndex, + ) + return msg +} + +// PostVoteInbound posts a vote on an observed inbound tx +// retryGasLimit is the gas limit used to resend the tx if it fails because of insufficient gas +// it is used when the ballot is finalized and the inbound tx needs to be processed +func (b *ZetaCoreBridge) PostVoteInbound(gasLimit, retryGasLimit uint64, msg *types.MsgVoteOnObservedInboundTx) (string, string, error) { + authzMsg, authzSigner, err := b.WrapMessageWithAuthz(msg) + if err != nil { + return "", "", err + } + + // don't post send if has already voted before + ballotIndex := msg.Digest() + hasVoted, err := b.HasVoted(ballotIndex, msg.Creator) + if err != nil { + return "", ballotIndex, errors.Wrapf(err, "PostVoteInbound: unable to check if already voted for ballot %s voter %s", ballotIndex, msg.Creator) + } + if hasVoted { + return "", ballotIndex, nil + } + + for i := 0; i < DefaultRetryCount; i++ { + zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) + if err == nil { + // monitor the result of the transaction and resend if necessary + go b.MonitorVoteInboundTxResult(zetaTxHash, retryGasLimit, msg) + + return zetaTxHash, ballotIndex, nil + } + b.logger.Debug().Err(err).Msgf("PostVoteInbound broadcast fail | Retry count : %d", i+1) + time.Sleep(DefaultRetryInterval * time.Second) + } + return "", ballotIndex, fmt.Errorf("post send failed after %d retries", DefaultRetryInterval) +} + +// MonitorVoteInboundTxResult monitors the result of a vote inbound tx +// retryGasLimit is the gas limit used to resend the tx if it fails because of insufficient gas +// if retryGasLimit is 0, the tx is not resent +func (b *ZetaCoreBridge) MonitorVoteInboundTxResult(zetaTxHash string, retryGasLimit uint64, msg *types.MsgVoteOnObservedInboundTx) { + var lastErr error + + for i := 0; i < MonitorVoteInboundTxResultRetryCount; i++ { + time.Sleep(MonitorVoteInboundTxResultInterval * time.Second) + + // query tx result from ZetaChain + txResult, err := b.QueryTxResult(zetaTxHash) + + if err == nil { + if strings.Contains(txResult.RawLog, "failed to execute message") { + // the inbound vote tx shouldn't fail to execute + // this shouldn't happen + b.logger.Error().Msgf( + "MonitorInboundTxResult: failed to execute vote, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } else if strings.Contains(txResult.RawLog, "out of gas") { + // if the tx fails with an out of gas error, resend the tx with more gas if retryGasLimit > 0 + b.logger.Debug().Msgf( + "MonitorInboundTxResult: out of gas, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + if retryGasLimit > 0 { + // new retryGasLimit set to 0 to prevent reentering this function + _, _, err := b.PostVoteInbound(retryGasLimit, 0, msg) + if err != nil { + b.logger.Error().Err(err).Msgf( + "MonitorInboundTxResult: failed to resend tx, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } else { + b.logger.Info().Msgf( + "MonitorInboundTxResult: successfully resent tx, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } + } + } else { + b.logger.Debug().Msgf( + "MonitorInboundTxResult: successful txHash %s, log %s", zetaTxHash, txResult.RawLog, + ) + } + return + } + lastErr = err + } + + b.logger.Error().Err(lastErr).Msgf( + "MonitorInboundTxResult: unable to query tx result for txHash %s, err %s", zetaTxHash, lastErr.Error(), + ) + return +} diff --git a/zetaclient/tx_vote_outbound.go b/zetaclient/tx_vote_outbound.go new file mode 100644 index 0000000000..bcf79c69f6 --- /dev/null +++ b/zetaclient/tx_vote_outbound.go @@ -0,0 +1,154 @@ +package zetaclient + +import ( + "fmt" + "math/big" + "strings" + "time" + + "cosmossdk.io/math" + "github.com/pkg/errors" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +const ( + // PostVoteOutboundGasLimit is the gas limit for voting on observed outbound tx + PostVoteOutboundGasLimit = 400_000 + + // PostVoteOutboundRevertGasLimit is the gas limit for voting on observed outbound tx for revert (when outbound fails) + // The value needs to be higher because reverting implies interacting with the EVM to perform swaps for the gas token + PostVoteOutboundRevertGasLimit = 1_500_000 + + // MonitorVoteOutboundTxResultInterval is the interval between retries for monitoring tx result in seconds + MonitorVoteOutboundTxResultInterval = 5 + + // MonitorVoteOutboundTxResultRetryCount is the number of retries to fetch monitoring tx result + MonitorVoteOutboundTxResultRetryCount = 20 +) + +// PostVoteOutbound posts a vote on an observed outbound tx +func (b *ZetaCoreBridge) PostVoteOutbound( + sendHash string, + outTxHash string, + outBlockHeight uint64, + outTxGasUsed uint64, + outTxEffectiveGasPrice *big.Int, + outTxEffectiveGasLimit uint64, + amount *big.Int, + status common.ReceiveStatus, + chain common.Chain, + nonce uint64, + coinType common.CoinType, +) (string, string, error) { + signerAddress := b.keys.GetOperatorAddress().String() + msg := types.NewMsgVoteOnObservedOutboundTx( + signerAddress, + sendHash, + outTxHash, + outBlockHeight, + outTxGasUsed, + math.NewIntFromBigInt(outTxEffectiveGasPrice), + outTxEffectiveGasLimit, + math.NewUintFromBigInt(amount), + status, + chain.ChainId, + nonce, + coinType, + ) + + // when an outbound fails and a revert is required, the gas limit needs to be higher + // this is because the revert tx needs to interact with the EVM to perform swaps for the gas token + // 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 == common.ReceiveStatus_Failed { + retryGasLimit = PostVoteOutboundRevertGasLimit + } + + return b.PostVoteOutboundFromMsg(PostVoteOutboundGasLimit, retryGasLimit, msg) +} + +// PostVoteOutboundFromMsg posts a vote on an observed outbound tx from a MsgVoteOnObservedOutboundTx +func (b *ZetaCoreBridge) PostVoteOutboundFromMsg(gasLimit, retryGasLimit uint64, msg *types.MsgVoteOnObservedOutboundTx) (string, string, error) { + authzMsg, authzSigner, err := b.WrapMessageWithAuthz(msg) + if err != nil { + return "", "", err + } + + // don't post confirmation if has already voted before + ballotIndex := msg.Digest() + hasVoted, err := b.HasVoted(ballotIndex, msg.Creator) + if err != nil { + return "", ballotIndex, errors.Wrapf(err, "PostVoteOutbound: unable to check if already voted for ballot %s voter %s", ballotIndex, msg.Creator) + } + if hasVoted { + return "", ballotIndex, nil + } + for i := 0; i < DefaultRetryCount; i++ { + zetaTxHash, err := b.Broadcast(gasLimit, authzMsg, authzSigner) + if err == nil { + // monitor the result of the transaction and resend if necessary + go b.MonitorVoteOutboundTxResult(zetaTxHash, retryGasLimit, msg) + + return zetaTxHash, ballotIndex, nil + } + b.logger.Debug().Err(err).Msgf("PostVoteOutbound broadcast fail | Retry count : %d", i+1) + time.Sleep(DefaultRetryInterval * time.Second) + } + return "", ballotIndex, fmt.Errorf("post receive failed after %d retries", DefaultRetryCount) +} + +// MonitorVoteOutboundTxResult monitors the result of a vote outbound tx +// retryGasLimit is the gas limit used to resend the tx if it fails because of insufficient gas +// if retryGasLimit is 0, the tx is not resent +func (b *ZetaCoreBridge) MonitorVoteOutboundTxResult(zetaTxHash string, retryGasLimit uint64, msg *types.MsgVoteOnObservedOutboundTx) { + var lastErr error + + for i := 0; i < MonitorVoteOutboundTxResultRetryCount; i++ { + time.Sleep(MonitorVoteOutboundTxResultInterval * time.Second) + + // query tx result from ZetaChain + txResult, err := b.QueryTxResult(zetaTxHash) + + if err == nil { + if strings.Contains(txResult.RawLog, "failed to execute message") { + // the inbound vote tx shouldn't fail to execute + // this shouldn't happen + b.logger.Error().Msgf( + "MonitorVoteOutboundTxResult: failed to execute vote, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } else if strings.Contains(txResult.RawLog, "out of gas") { + // if the tx fails with an out of gas error, resend the tx with more gas if retryGasLimit > 0 + b.logger.Debug().Msgf( + "MonitorVoteOutboundTxResult: out of gas, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + if retryGasLimit > 0 { + // new retryGasLimit set to 0 to prevent reentering this function + _, _, err := b.PostVoteOutboundFromMsg(retryGasLimit, 0, msg) + + if err != nil { + b.logger.Error().Err(err).Msgf( + "MonitorVoteOutboundTxResult: failed to resend tx, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } else { + b.logger.Info().Msgf( + "MonitorVoteOutboundTxResult: successfully resent tx, txHash: %s, log %s", zetaTxHash, txResult.RawLog, + ) + } + } + } else { + b.logger.Debug().Msgf( + "MonitorVoteOutboundTxResult: successful txHash %s, log %s", zetaTxHash, txResult.RawLog, + ) + } + return + } + lastErr = err + } + + b.logger.Error().Err(lastErr).Msgf( + "MonitorVoteOutboundTxResult: unable to query tx result for txHash %s, err %s", zetaTxHash, lastErr.Error(), + ) + return +} diff --git a/zetaclient/utils.go b/zetaclient/utils.go index 0dfa5cb973..5a0fcd9ab2 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -196,26 +196,31 @@ func (ob *EVMChainClient) HasEnoughConfirmations(receipt *ethtypes.Receipt, last return lastHeight >= confHeight } -func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody.ERC20CustodyDeposited) (types.MsgVoteOnObservedInboundTx, error) { - ob.logger.ExternalChainWatcher.Info().Msgf("TxBlockNumber %d Transaction Hash: %s Message : %s", event.Raw.BlockNumber, event.Raw.TxHash, event.Message) - if bytes.Equal(event.Message, []byte(DonationMessage)) { - ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("thank you rich folk for your donation!: %s", event.Raw.TxHash.Hex()) - } - // get the sender of the event's transaction - tx, _, err := ob.evmClient.TransactionByHash(context.Background(), event.Raw.TxHash) +// GetTransactionSender returns the sender of the given transaction +func (ob *EVMChainClient) GetTransactionSender(tx *ethtypes.Transaction, blockHash ethcommon.Hash, txIndex uint) (ethcommon.Address, error) { + sender, err := ob.evmClient.TransactionSender(context.Background(), tx, blockHash, txIndex) if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) - return types.MsgVoteOnObservedInboundTx{}, errors.Wrap(err, fmt.Sprintf("failed to get transaction by hash: %s", event.Raw.TxHash.Hex())) + // trying local recovery (assuming LondonSigner dynamic fee tx type) of sender address + signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) + sender, err = signer.Sender(tx) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf("can't recover the sender from tx hash %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return ethcommon.Address{}, err + } } - signer := ethtypes.NewLondonSigner(big.NewInt(ob.chain.ChainId)) - sender, err := signer.Sender(tx) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msg(fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) - return types.MsgVoteOnObservedInboundTx{}, errors.Wrap(err, fmt.Sprintf("can't recover the sender from the tx hash: %s", event.Raw.TxHash.Hex())) + return sender, nil +} +func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody.ERC20CustodyDeposited, sender ethcommon.Address) *types.MsgVoteOnObservedInboundTx { + if bytes.Equal(event.Message, []byte(DonationMessage)) { + ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation! tx %s chain %d", event.Raw.TxHash.Hex(), ob.chain.ChainId) + return nil } - return *GetInBoundVoteMessage( + message := hex.EncodeToString(event.Message) + ob.logger.ExternalChainWatcher.Info().Msgf("ERC20CustodyDeposited inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, sender.Hex(), event.Amount.String(), message) + + return GetInBoundVoteMessage( sender.Hex(), ob.chain.ChainId, "", @@ -230,35 +235,39 @@ func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody event.Asset.String(), ob.zetaClient.GetKeys().GetOperatorAddress().String(), event.Raw.Index, - ), nil + ) } -func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector.ZetaConnectorNonEthZetaSent) (types.MsgVoteOnObservedInboundTx, error) { - ob.logger.ExternalChainWatcher.Info().Msgf("TxBlockNumber %d Transaction Hash: %s Message : %s", event.Raw.BlockNumber, event.Raw.TxHash, event.Message) +func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector.ZetaConnectorNonEthZetaSent) *types.MsgVoteOnObservedInboundTx { destChain := common.GetChainFromChainID(event.DestinationChainId.Int64()) if destChain == nil { ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not supported %d", event.DestinationChainId.Int64()) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("chain id not supported %d", event.DestinationChainId.Int64()) + return nil } destAddr := clienttypes.BytesToEthHex(event.DestinationAddress) if !destChain.IsZetaChain() { cfgDest, found := ob.cfg.GetEVMConfig(destChain.ChainId) if !found { - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) + ob.logger.ExternalChainWatcher.Warn().Msgf("chain id not present in EVMChainConfigs %d", event.DestinationChainId.Int64()) + return nil } if strings.EqualFold(destAddr, cfgDest.ZetaTokenContractAddress) { ob.logger.ExternalChainWatcher.Warn().Msgf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) - return types.MsgVoteOnObservedInboundTx{}, fmt.Errorf("potential attack attempt: %s destination address is ZETA token contract address %s", destChain, destAddr) + return nil } } - return *GetInBoundVoteMessage( + message := base64.StdEncoding.EncodeToString(event.Message) + ob.logger.ExternalChainWatcher.Info().Msgf("ZetaSent inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, event.ZetaTxSenderAddress.Hex(), event.ZetaValueAndGas.String(), message) + + return GetInBoundVoteMessage( event.ZetaTxSenderAddress.Hex(), ob.chain.ChainId, event.SourceTxOriginAddress.Hex(), clienttypes.BytesToEthHex(event.DestinationAddress), destChain.ChainId, sdkmath.NewUintFromBigInt(event.ZetaValueAndGas), - base64.StdEncoding.EncodeToString(event.Message), + message, event.Raw.TxHash.Hex(), event.Raw.BlockNumber, event.DestinationGasLimit.Uint64(), @@ -266,27 +275,31 @@ func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector "", ob.zetaClient.GetKeys().GetOperatorAddress().String(), event.Raw.Index, - ), nil + ) } -func (ob *EVMChainClient) GetInboundVoteMsgForTokenSentToTSS(txhash ethcommon.Hash, value *big.Int, receipt *ethtypes.Receipt, from ethcommon.Address, data []byte) *types.MsgVoteOnObservedInboundTx { - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx detected: %s, blocknum %d", txhash.Hex(), receipt.BlockNumber) - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx value: %s", value.String()) - ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx from: %s", from.Hex()) +func (ob *EVMChainClient) GetInboundVoteMsgForTokenSentToTSS(tx *ethtypes.Transaction, sender ethcommon.Address, blockNumber uint64) *types.MsgVoteOnObservedInboundTx { + if bytes.Equal(tx.Data(), []byte(DonationMessage)) { + ob.logger.ExternalChainWatcher.Info().Msgf("thank you rich folk for your donation! tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return nil + } message := "" - if len(data) != 0 { - message = hex.EncodeToString(data) + if len(tx.Data()) != 0 { + message = hex.EncodeToString(tx.Data()) } + ob.logger.ExternalChainWatcher.Info().Msgf("TSS inTx detected on chain %d tx %s block %d from %s value %s message %s", + ob.chain.ChainId, tx.Hash().Hex(), blockNumber, sender.Hex(), tx.Value().String(), hex.EncodeToString(tx.Data())) + return GetInBoundVoteMessage( - from.Hex(), + sender.Hex(), ob.chain.ChainId, - from.Hex(), - from.Hex(), + sender.Hex(), + sender.Hex(), ob.zetaClient.ZetaChain().ChainId, - sdkmath.NewUintFromBigInt(value), + sdkmath.NewUintFromBigInt(tx.Value()), message, - txhash.Hex(), - receipt.BlockNumber.Uint64(), + tx.Hash().Hex(), + blockNumber, 90_000, common.CoinType_Gas, "", diff --git a/zetaclient/voter_test.go b/zetaclient/voter_test.go index 5df01de806..853c17eea9 100644 --- a/zetaclient/voter_test.go +++ b/zetaclient/voter_test.go @@ -85,20 +85,20 @@ func (s *VoterSuite) SetUpTest(c *C) { func (s *VoterSuite) TestSendVoter(c *C) { b1 := s.bridge1 b2 := s.bridge2 - metaHash, err := b1.PostSend("0xfrom", "Ethereum", "0xfrom", "0xto", "BSC", "123456", "23245", "little message", + metaHash, err := b1.PostVoteInbound("0xfrom", "Ethereum", "0xfrom", "0xto", "BSC", "123456", "23245", "little message", "0xtxhash", 123123, "0xtoken") c.Assert(err, IsNil) - log.Info().Msgf("PostSend metaHash %s", metaHash) + log.Info().Msgf("PostVoteInbound metaHash %s", metaHash) // wait for the next block timer1 := time.NewTimer(2 * time.Second) <-timer1.C - metaHash, err = b2.PostSend("0xfrom", "Ethereum", "0xfrom", "0xto", "BSC", "123456", "23245", "little message", + metaHash, err = b2.PostVoteInbound("0xfrom", "Ethereum", "0xfrom", "0xto", "BSC", "123456", "23245", "little message", "0xtxhash", 123123, "0xtoken") c.Assert(err, IsNil) - log.Info().Msgf("Second PostSend metaHash %s", metaHash) + log.Info().Msgf("Second PostVoteInbound metaHash %s", metaHash) // wait for the next block timer2 := time.NewTimer(2 * time.Second) @@ -111,13 +111,13 @@ func (s *VoterSuite) TestSendVoter(c *C) { send := sends[0] - metaHash, err = b1.PostReceiveConfirmation(send.Index, "0xoutHash", 2123, "23245") + metaHash, err = b1.PostVoteOutbound(send.Index, "0xoutHash", 2123, "23245") c.Assert(err, IsNil) timer3 := time.NewTimer(2 * time.Second) <-timer3.C - metaHash, err = b2.PostReceiveConfirmation(send.Index, "0xoutHash", 2123, "23245") + metaHash, err = b2.PostVoteOutbound(send.Index, "0xoutHash", 2123, "23245") c.Assert(err, IsNil) receives, err := b2.GetAllReceive() diff --git a/zetaclient/zetacore_observer_test.go b/zetaclient/zetacore_observer_test.go index afa8114764..919450d1cb 100644 --- a/zetaclient/zetacore_observer_test.go +++ b/zetaclient/zetacore_observer_test.go @@ -117,18 +117,18 @@ func (s *COSuite) SetUpTest(c *C) { func (s *COSuite) TestSendFlow(c *C) { b1 := s.bridge1 b2 := s.bridge2 - metaHash, err := b1.PostSend(TEST_SENDER, "Ethereum", TEST_SENDER, TEST_RECEIVER, "BSC", "1337", "0", "treat or trick", + metaHash, err := b1.PostVoteInbound(TEST_SENDER, "Ethereum", TEST_SENDER, TEST_RECEIVER, "BSC", "1337", "0", "treat or trick", "0xtxhash", 123123, "0xtoken") c.Assert(err, IsNil) - c.Logf("PostSend metaHash %s", metaHash) + c.Logf("PostVoteInbound metaHash %s", metaHash) timer1 := time.NewTimer(2 * time.Second) <-timer1.C - metaHash, err = b2.PostSend(TEST_SENDER, "Ethereum", TEST_SENDER, TEST_RECEIVER, "BSC", "1337", "0", "treat or trick", + metaHash, err = b2.PostVoteInbound(TEST_SENDER, "Ethereum", TEST_SENDER, TEST_RECEIVER, "BSC", "1337", "0", "treat or trick", "0xtxhash", 123123, "0xtoken") c.Assert(err, IsNil) - c.Logf("Second PostSend metaHash %s", metaHash) + c.Logf("Second PostVoteInbound metaHash %s", metaHash) timer2 := time.NewTimer(2 * time.Second) <-timer2.C From 174a0cf6c0777b51dba55c56af06187013f3ed3c Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 25 Jan 2024 09:29:22 -0800 Subject: [PATCH 49/67] feat(`crosschain`): `MsgAbortStuckCCTX` message (#1635) * proto * implement message * tests * cli commands * generate doc * Update x/crosschain/keeper/msg_server_abort_stuck_cctx_test.go Co-authored-by: Tanmay --------- Co-authored-by: Tanmay --- docs/cli/zetacored/zetacored_tx_crosschain.md | 1 + ...etacored_tx_crosschain_abort-stuck-cctx.md | 52 ++ docs/openapi/openapi.swagger.yaml | 2 + docs/spec/crosschain/messages.md | 12 + proto/crosschain/tx.proto | 9 + typescript/crosschain/tx_pb.d.ts | 48 ++ x/crosschain/client/cli/cli_cctx.go | 22 + x/crosschain/client/cli/tx.go | 1 + .../keeper/msg_server_abort_stuck_cctx.go | 51 ++ .../msg_server_abort_stuck_cctx_test.go | 151 +++++ x/crosschain/types/codec.go | 2 + .../types/message_abort_stuck_cctx.go | 47 ++ .../types/message_abort_stuck_cctx_test.go | 45 ++ x/crosschain/types/tx.pb.go | 557 +++++++++++++++--- 14 files changed, 911 insertions(+), 89 deletions(-) create mode 100644 docs/cli/zetacored/zetacored_tx_crosschain_abort-stuck-cctx.md create mode 100644 x/crosschain/keeper/msg_server_abort_stuck_cctx.go create mode 100644 x/crosschain/keeper/msg_server_abort_stuck_cctx_test.go create mode 100644 x/crosschain/types/message_abort_stuck_cctx.go create mode 100644 x/crosschain/types/message_abort_stuck_cctx_test.go diff --git a/docs/cli/zetacored/zetacored_tx_crosschain.md b/docs/cli/zetacored/zetacored_tx_crosschain.md index a7e2465ab1..bb8a200308 100644 --- a/docs/cli/zetacored/zetacored_tx_crosschain.md +++ b/docs/cli/zetacored/zetacored_tx_crosschain.md @@ -25,6 +25,7 @@ zetacored tx crosschain [flags] ### SEE ALSO * [zetacored tx](zetacored_tx.md) - Transactions subcommands +* [zetacored tx crosschain abort-stuck-cctx](zetacored_tx_crosschain_abort-stuck-cctx.md) - abort a stuck CCTX * [zetacored tx crosschain add-to-in-tx-tracker](zetacored_tx_crosschain_add-to-in-tx-tracker.md) - Add a in-tx-tracker Use 0:Zeta,1:Gas,2:ERC20 * [zetacored tx crosschain add-to-out-tx-tracker](zetacored_tx_crosschain_add-to-out-tx-tracker.md) - Add a out-tx-tracker diff --git a/docs/cli/zetacored/zetacored_tx_crosschain_abort-stuck-cctx.md b/docs/cli/zetacored/zetacored_tx_crosschain_abort-stuck-cctx.md new file mode 100644 index 0000000000..206cda6442 --- /dev/null +++ b/docs/cli/zetacored/zetacored_tx_crosschain_abort-stuck-cctx.md @@ -0,0 +1,52 @@ +# tx crosschain abort-stuck-cctx + +abort a stuck CCTX + +``` +zetacored tx crosschain abort-stuck-cctx [index] [flags] +``` + +### Options + +``` + -a, --account-number uint The account number of the signing account (offline mode only) + --aux Generate aux signer data instead of sending a tx + -b, --broadcast-mode string Transaction broadcasting mode (sync|async|block) + --dry-run ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it (when enabled, the local Keybase is not accessible) + --fee-granter string Fee granter grants fees for the transaction + --fee-payer string Fee payer pays fees for the transaction instead of deducting from the signer + --fees string Fees to pay along with transaction; eg: 10uatom + --from string Name or address of private key with which to sign + --gas string gas limit to set per-transaction; set to "auto" to calculate sufficient gas automatically. Note: "auto" option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of "fees". (default 200000) + --gas-adjustment float adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored (default 1) + --gas-prices string Gas prices in decimal format to determine the transaction fee (e.g. 0.1uatom) + --generate-only Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase only accessed when providing a key name) + -h, --help help for abort-stuck-cctx + --keyring-backend string Select keyring's backend (os|file|kwallet|pass|test|memory) + --keyring-dir string The client Keyring directory; if omitted, the default 'home' directory will be used + --ledger Use a connected Ledger device + --node string [host]:[port] to tendermint rpc interface for this chain + --note string Note to add a description to the transaction (previously --memo) + --offline Offline mode (does not allow any online functionality) + -o, --output string Output format (text|json) + -s, --sequence uint The sequence number of the signing account (offline mode only) + --sign-mode string Choose sign mode (direct|amino-json|direct-aux), this is an advanced feature + --timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height + --tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator + -y, --yes Skip tx broadcasting prompt confirmation +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored tx crosschain](zetacored_tx_crosschain.md) - crosschain transactions subcommands + diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 2e2b7c54c3..1ba9d75fcb 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -50830,6 +50830,8 @@ definitions: lastReceiveHeight: type: string format: uint64 + crosschainMsgAbortStuckCCTXResponse: + type: object crosschainMsgAddToInTxTrackerResponse: type: object crosschainMsgAddToOutTxTrackerResponse: diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index c74e063ffd..1659a95bf0 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -258,3 +258,15 @@ message MsgCreateTSSVoter { } ``` +## MsgAbortStuckCCTX + +AbortStuckCCTX aborts a stuck CCTX +Authorized: admin policy group 2 + +```proto +message MsgAbortStuckCCTX { + string creator = 1; + string cctx_index = 2; +} +``` + diff --git a/proto/crosschain/tx.proto b/proto/crosschain/tx.proto index b660c38968..3ccfba1911 100644 --- a/proto/crosschain/tx.proto +++ b/proto/crosschain/tx.proto @@ -19,6 +19,8 @@ service Msg { rpc UpdateTssAddress(MsgUpdateTssAddress) returns (MsgUpdateTssAddressResponse); rpc MigrateTssFunds(MsgMigrateTssFunds) returns (MsgMigrateTssFundsResponse); rpc CreateTSSVoter(MsgCreateTSSVoter) returns (MsgCreateTSSVoterResponse); + + rpc AbortStuckCCTX(MsgAbortStuckCCTX) returns (MsgAbortStuckCCTXResponse); } message MsgCreateTSSVoter { @@ -153,3 +155,10 @@ message MsgVoteOnObservedInboundTx { } message MsgVoteOnObservedInboundTxResponse {} + +message MsgAbortStuckCCTX { + string creator = 1; + string cctx_index = 2; +} + +message MsgAbortStuckCCTXResponse {} diff --git a/typescript/crosschain/tx_pb.d.ts b/typescript/crosschain/tx_pb.d.ts index 6c425e3990..b96408964c 100644 --- a/typescript/crosschain/tx_pb.d.ts +++ b/typescript/crosschain/tx_pb.d.ts @@ -730,3 +730,51 @@ export declare class MsgVoteOnObservedInboundTxResponse extends Message | undefined, b: MsgVoteOnObservedInboundTxResponse | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.crosschain.MsgAbortStuckCCTX + */ +export declare class MsgAbortStuckCCTX extends Message { + /** + * @generated from field: string creator = 1; + */ + creator: string; + + /** + * @generated from field: string cctx_index = 2; + */ + cctxIndex: string; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.MsgAbortStuckCCTX"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgAbortStuckCCTX; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgAbortStuckCCTX; + + static fromJsonString(jsonString: string, options?: Partial): MsgAbortStuckCCTX; + + static equals(a: MsgAbortStuckCCTX | PlainMessage | undefined, b: MsgAbortStuckCCTX | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.crosschain.MsgAbortStuckCCTXResponse + */ +export declare class MsgAbortStuckCCTXResponse extends Message { + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.MsgAbortStuckCCTXResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): MsgAbortStuckCCTXResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): MsgAbortStuckCCTXResponse; + + static fromJsonString(jsonString: string, options?: Partial): MsgAbortStuckCCTXResponse; + + static equals(a: MsgAbortStuckCCTXResponse | PlainMessage | undefined, b: MsgAbortStuckCCTXResponse | PlainMessage | undefined): boolean; +} + diff --git a/x/crosschain/client/cli/cli_cctx.go b/x/crosschain/client/cli/cli_cctx.go index 8f38c4ebe1..e85712f50e 100644 --- a/x/crosschain/client/cli/cli_cctx.go +++ b/x/crosschain/client/cli/cli_cctx.go @@ -277,3 +277,25 @@ func CmdCCTXOutboundVoter() *cobra.Command { return cmd } + +func CmdAbortStuckCCTX() *cobra.Command { + cmd := &cobra.Command{ + Use: "abort-stuck-cctx [index]", + Short: "abort a stuck CCTX", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + msg := &types.MsgAbortStuckCCTX{ + Creator: clientCtx.GetFromAddress().String(), + CctxIndex: args[0], + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/crosschain/client/cli/tx.go b/x/crosschain/client/cli/tx.go index 0fc5e3c302..d8e6b3bc0e 100644 --- a/x/crosschain/client/cli/tx.go +++ b/x/crosschain/client/cli/tx.go @@ -30,6 +30,7 @@ func GetTxCmd() *cobra.Command { CmdUpdateTss(), CmdMigrateTssFunds(), CmdAddToInTxTracker(), + CmdAbortStuckCCTX(), ) return cmd diff --git a/x/crosschain/keeper/msg_server_abort_stuck_cctx.go b/x/crosschain/keeper/msg_server_abort_stuck_cctx.go new file mode 100644 index 0000000000..32c4bdf55f --- /dev/null +++ b/x/crosschain/keeper/msg_server_abort_stuck_cctx.go @@ -0,0 +1,51 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +const ( + // AbortMessage is the message to abort a stuck CCTX + AbortMessage = "CCTX aborted with admin cmd" +) + +// AbortStuckCCTX aborts a stuck CCTX +// Authorized: admin policy group 2 +func (k msgServer) AbortStuckCCTX( + goCtx context.Context, + msg *types.MsgAbortStuckCCTX, +) (*types.MsgAbortStuckCCTXResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // check if authorized + if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_group2) { + return nil, observertypes.ErrNotAuthorized + } + + // check if the cctx exists + cctx, found := k.GetCrossChainTx(ctx, msg.CctxIndex) + if !found { + return nil, types.ErrCannotFindCctx + } + + // check if the cctx is pending + isPending := cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound || + cctx.CctxStatus.Status == types.CctxStatus_PendingInbound || + cctx.CctxStatus.Status == types.CctxStatus_PendingRevert + if !isPending { + return nil, types.ErrStatusNotPending + } + + cctx.CctxStatus = &types.Status{ + Status: types.CctxStatus_Aborted, + StatusMessage: AbortMessage, + } + + k.SetCrossChainTx(ctx, cctx) + + return &types.MsgAbortStuckCCTXResponse{}, nil +} diff --git a/x/crosschain/keeper/msg_server_abort_stuck_cctx_test.go b/x/crosschain/keeper/msg_server_abort_stuck_cctx_test.go new file mode 100644 index 0000000000..f9b7c380e0 --- /dev/null +++ b/x/crosschain/keeper/msg_server_abort_stuck_cctx_test.go @@ -0,0 +1,151 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + crosschainkeeper "github.com/zeta-chain/zetacore/x/crosschain/keeper" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_AbortStuckCCTX(t *testing.T) { + t.Run("can abort a cctx in pending inbound", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + + // create a cctx + cctx := sample.CrossChainTx(t, "cctx_index") + cctx.CctxStatus = &crosschaintypes.Status{ + Status: crosschaintypes.CctxStatus_PendingInbound, + StatusMessage: "pending inbound", + } + k.SetCrossChainTx(ctx, *cctx) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: admin, + CctxIndex: "cctx_index", + }) + + require.NoError(t, err) + cctxFound, found := k.GetCrossChainTx(ctx, "cctx_index") + require.True(t, found) + require.Equal(t, crosschaintypes.CctxStatus_Aborted, cctxFound.CctxStatus.Status) + require.Equal(t, crosschainkeeper.AbortMessage, cctxFound.CctxStatus.StatusMessage) + }) + + t.Run("can abort a cctx in pending outbound", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + + // create a cctx + cctx := sample.CrossChainTx(t, "cctx_index") + cctx.CctxStatus = &crosschaintypes.Status{ + Status: crosschaintypes.CctxStatus_PendingOutbound, + StatusMessage: "pending outbound", + } + k.SetCrossChainTx(ctx, *cctx) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: admin, + CctxIndex: "cctx_index", + }) + + require.NoError(t, err) + cctxFound, found := k.GetCrossChainTx(ctx, "cctx_index") + require.True(t, found) + require.Equal(t, crosschaintypes.CctxStatus_Aborted, cctxFound.CctxStatus.Status) + require.Equal(t, crosschainkeeper.AbortMessage, cctxFound.CctxStatus.StatusMessage) + }) + + t.Run("can abort a cctx in pending revert", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + + // create a cctx + cctx := sample.CrossChainTx(t, "cctx_index") + cctx.CctxStatus = &crosschaintypes.Status{ + Status: crosschaintypes.CctxStatus_PendingRevert, + StatusMessage: "pending revert", + } + k.SetCrossChainTx(ctx, *cctx) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: admin, + CctxIndex: "cctx_index", + }) + + require.NoError(t, err) + cctxFound, found := k.GetCrossChainTx(ctx, "cctx_index") + require.True(t, found) + require.Equal(t, crosschaintypes.CctxStatus_Aborted, cctxFound.CctxStatus.Status) + require.Equal(t, crosschainkeeper.AbortMessage, cctxFound.CctxStatus.StatusMessage) + }) + + t.Run("cannot abort a cctx in pending outbound if not admin", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + + // create a cctx + cctx := sample.CrossChainTx(t, "cctx_index") + cctx.CctxStatus = &crosschaintypes.Status{ + Status: crosschaintypes.CctxStatus_PendingOutbound, + StatusMessage: "pending outbound", + } + k.SetCrossChainTx(ctx, *cctx) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: sample.AccAddress(), + CctxIndex: "cctx_index", + }) + require.ErrorIs(t, err, observertypes.ErrNotAuthorized) + }) + + t.Run("cannot abort a cctx if doesn't exist", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: admin, + CctxIndex: "cctx_index", + }) + require.ErrorIs(t, err, crosschaintypes.ErrCannotFindCctx) + }) + + t.Run("cannot abort a cctx if not pending", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := crosschainkeeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + + // create a cctx + cctx := sample.CrossChainTx(t, "cctx_index") + cctx.CctxStatus = &crosschaintypes.Status{ + Status: crosschaintypes.CctxStatus_OutboundMined, + StatusMessage: "outbound mined", + } + k.SetCrossChainTx(ctx, *cctx) + + // abort the cctx + _, err := msgServer.AbortStuckCCTX(ctx, &crosschaintypes.MsgAbortStuckCCTX{ + Creator: admin, + CctxIndex: "cctx_index", + }) + require.ErrorIs(t, err, crosschaintypes.ErrStatusNotPending) + }) +} diff --git a/x/crosschain/types/codec.go b/x/crosschain/types/codec.go index c85eb7f8ea..fb3d51db0a 100644 --- a/x/crosschain/types/codec.go +++ b/x/crosschain/types/codec.go @@ -18,6 +18,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgWhitelistERC20{}, "crosschain/WhitelistERC20", nil) cdc.RegisterConcrete(&MsgMigrateTssFunds{}, "crosschain/MigrateTssFunds", nil) cdc.RegisterConcrete(&MsgUpdateTssAddress{}, "crosschain/UpdateTssAddress", nil) + cdc.RegisterConcrete(&MsgAbortStuckCCTX{}, "crosschain/AbortStuckCCTX", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -32,6 +33,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgWhitelistERC20{}, &MsgMigrateTssFunds{}, &MsgUpdateTssAddress{}, + &MsgAbortStuckCCTX{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/crosschain/types/message_abort_stuck_cctx.go b/x/crosschain/types/message_abort_stuck_cctx.go new file mode 100644 index 0000000000..102290ab9b --- /dev/null +++ b/x/crosschain/types/message_abort_stuck_cctx.go @@ -0,0 +1,47 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgAbortStuckCCTX = "AbortStuckCCTX" + +var _ sdk.Msg = &MsgAbortStuckCCTX{} + +func NewMsgAbortStuckCCTX(creator string, cctxIndex string) *MsgAbortStuckCCTX { + return &MsgAbortStuckCCTX{ + Creator: creator, + CctxIndex: cctxIndex, + } +} + +func (msg *MsgAbortStuckCCTX) Route() string { + return RouterKey +} + +func (msg *MsgAbortStuckCCTX) Type() string { + return TypeMsgAbortStuckCCTX +} + +func (msg *MsgAbortStuckCCTX) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgAbortStuckCCTX) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgAbortStuckCCTX) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + return nil +} diff --git a/x/crosschain/types/message_abort_stuck_cctx_test.go b/x/crosschain/types/message_abort_stuck_cctx_test.go new file mode 100644 index 0000000000..40bdcf4794 --- /dev/null +++ b/x/crosschain/types/message_abort_stuck_cctx_test.go @@ -0,0 +1,45 @@ +package types_test + +import ( + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestMsgAbortStuckCCTX_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg types.MsgAbortStuckCCTX + err error + }{ + { + name: "invalid address", + msg: types.MsgAbortStuckCCTX{ + Creator: "invalid_address", + CctxIndex: "cctx_index", + }, + err: sdkerrors.ErrInvalidAddress, + }, + { + name: "valid", + msg: types.MsgAbortStuckCCTX{ + Creator: sample.AccAddress(), + CctxIndex: "cctx_index", + }, + err: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.msg.ValidateBasic() + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + require.NoError(t, err) + }) + } +} diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index 6745107685..c784912394 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -1262,6 +1262,94 @@ func (m *MsgVoteOnObservedInboundTxResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgVoteOnObservedInboundTxResponse proto.InternalMessageInfo +type MsgAbortStuckCCTX struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + CctxIndex string `protobuf:"bytes,2,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` +} + +func (m *MsgAbortStuckCCTX) Reset() { *m = MsgAbortStuckCCTX{} } +func (m *MsgAbortStuckCCTX) String() string { return proto.CompactTextString(m) } +func (*MsgAbortStuckCCTX) ProtoMessage() {} +func (*MsgAbortStuckCCTX) Descriptor() ([]byte, []int) { + return fileDescriptor_81d6d611190b7635, []int{20} +} +func (m *MsgAbortStuckCCTX) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAbortStuckCCTX) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAbortStuckCCTX.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAbortStuckCCTX) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAbortStuckCCTX.Merge(m, src) +} +func (m *MsgAbortStuckCCTX) XXX_Size() int { + return m.Size() +} +func (m *MsgAbortStuckCCTX) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAbortStuckCCTX.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAbortStuckCCTX proto.InternalMessageInfo + +func (m *MsgAbortStuckCCTX) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgAbortStuckCCTX) GetCctxIndex() string { + if m != nil { + return m.CctxIndex + } + return "" +} + +type MsgAbortStuckCCTXResponse struct { +} + +func (m *MsgAbortStuckCCTXResponse) Reset() { *m = MsgAbortStuckCCTXResponse{} } +func (m *MsgAbortStuckCCTXResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAbortStuckCCTXResponse) ProtoMessage() {} +func (*MsgAbortStuckCCTXResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_81d6d611190b7635, []int{21} +} +func (m *MsgAbortStuckCCTXResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAbortStuckCCTXResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAbortStuckCCTXResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAbortStuckCCTXResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAbortStuckCCTXResponse.Merge(m, src) +} +func (m *MsgAbortStuckCCTXResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAbortStuckCCTXResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAbortStuckCCTXResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAbortStuckCCTXResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgCreateTSSVoter)(nil), "zetachain.zetacore.crosschain.MsgCreateTSSVoter") proto.RegisterType((*MsgCreateTSSVoterResponse)(nil), "zetachain.zetacore.crosschain.MsgCreateTSSVoterResponse") @@ -1283,100 +1371,105 @@ func init() { proto.RegisterType((*MsgVoteOnObservedOutboundTxResponse)(nil), "zetachain.zetacore.crosschain.MsgVoteOnObservedOutboundTxResponse") proto.RegisterType((*MsgVoteOnObservedInboundTx)(nil), "zetachain.zetacore.crosschain.MsgVoteOnObservedInboundTx") proto.RegisterType((*MsgVoteOnObservedInboundTxResponse)(nil), "zetachain.zetacore.crosschain.MsgVoteOnObservedInboundTxResponse") + proto.RegisterType((*MsgAbortStuckCCTX)(nil), "zetachain.zetacore.crosschain.MsgAbortStuckCCTX") + proto.RegisterType((*MsgAbortStuckCCTXResponse)(nil), "zetachain.zetacore.crosschain.MsgAbortStuckCCTXResponse") } func init() { proto.RegisterFile("crosschain/tx.proto", fileDescriptor_81d6d611190b7635) } var fileDescriptor_81d6d611190b7635 = []byte{ - // 1407 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x6d, 0x4f, 0x1b, 0xc7, - 0x13, 0xe7, 0xfe, 0x80, 0xb1, 0x07, 0x0c, 0xe4, 0x20, 0x89, 0x73, 0x04, 0x43, 0x8e, 0x7f, 0x52, - 0x54, 0x09, 0x3b, 0x21, 0xaa, 0x9a, 0xa4, 0xad, 0xd4, 0x80, 0x12, 0x42, 0x5b, 0x42, 0x74, 0x71, - 0x5a, 0x29, 0x6f, 0x4e, 0xe7, 0xbb, 0xe5, 0x7c, 0xc2, 0xb7, 0x6b, 0xdd, 0xae, 0x91, 0x8d, 0x2a, - 0x55, 0x8a, 0xd4, 0xf7, 0x55, 0x55, 0xa9, 0x55, 0xbf, 0x40, 0xbf, 0x4a, 0x5e, 0x46, 0x7d, 0xd5, - 0x54, 0x6a, 0x54, 0x85, 0x4f, 0xd0, 0x7e, 0x82, 0x6a, 0x1f, 0xee, 0xf0, 0x19, 0xfc, 0x00, 0x51, - 0x5e, 0xdd, 0xce, 0xec, 0xce, 0xec, 0xcc, 0x6f, 0x66, 0x76, 0xf6, 0x16, 0xe6, 0xdc, 0x88, 0x50, - 0xea, 0xd6, 0x9c, 0x00, 0x97, 0x59, 0xab, 0xd4, 0x88, 0x08, 0x23, 0xfa, 0xe2, 0x21, 0x62, 0x8e, - 0xe0, 0x95, 0xc4, 0x88, 0x44, 0xa8, 0x74, 0xbc, 0xce, 0x98, 0x73, 0x49, 0x18, 0x12, 0x5c, 0x96, - 0x1f, 0x29, 0x63, 0xcc, 0xfb, 0xc4, 0x27, 0x62, 0x58, 0xe6, 0x23, 0xc9, 0x35, 0x7f, 0xd3, 0xe0, - 0xc2, 0x0e, 0xf5, 0x37, 0x23, 0xe4, 0x30, 0x54, 0x79, 0xfa, 0xf4, 0x6b, 0xc2, 0x50, 0xa4, 0x17, - 0x60, 0xc2, 0xe5, 0x1c, 0x12, 0x15, 0xb4, 0x65, 0x6d, 0x35, 0x67, 0xc5, 0xa4, 0xbe, 0x08, 0xc0, - 0x28, 0xb5, 0x1b, 0xcd, 0xea, 0x3e, 0x6a, 0x17, 0xfe, 0x27, 0x26, 0x73, 0x8c, 0xd2, 0x27, 0x82, - 0xa1, 0x7f, 0x08, 0xb3, 0xfb, 0xa8, 0xbd, 0x85, 0xf0, 0x73, 0xc4, 0x9c, 0x47, 0x28, 0xf0, 0x6b, - 0xac, 0x30, 0xba, 0xac, 0xad, 0x8e, 0x5a, 0x27, 0xf8, 0xfa, 0x1a, 0x64, 0x28, 0x73, 0x58, 0x93, - 0x16, 0xc6, 0x96, 0xb5, 0xd5, 0xe9, 0xf5, 0x8b, 0x25, 0x65, 0xaf, 0x85, 0x5c, 0x14, 0x1c, 0xa0, - 0xa7, 0x62, 0xd2, 0x52, 0x8b, 0xcc, 0x05, 0xb8, 0x72, 0xc2, 0x50, 0x0b, 0xd1, 0x06, 0xc1, 0x14, - 0x99, 0x3f, 0x6a, 0xa0, 0xef, 0x50, 0x7f, 0x27, 0xf0, 0x23, 0x3e, 0x4d, 0xe9, 0xc3, 0x26, 0xf6, - 0x68, 0x1f, 0x3f, 0xae, 0x40, 0x56, 0x60, 0x65, 0x07, 0x9e, 0xf0, 0x62, 0xd4, 0x9a, 0x10, 0xf4, - 0xb6, 0xa7, 0x6f, 0x41, 0xc6, 0x09, 0x49, 0x13, 0x4b, 0xcb, 0x73, 0x1b, 0xe5, 0x97, 0x6f, 0x96, - 0x46, 0xfe, 0x7c, 0xb3, 0xf4, 0x81, 0x1f, 0xb0, 0x5a, 0xb3, 0xca, 0xad, 0x2c, 0xbb, 0x84, 0x86, - 0x84, 0xaa, 0xcf, 0x1a, 0xf5, 0xf6, 0xcb, 0xac, 0xdd, 0x40, 0xb4, 0xf4, 0x2c, 0xc0, 0xcc, 0x52, - 0xe2, 0xe6, 0x55, 0x30, 0x4e, 0xda, 0x94, 0x98, 0xfc, 0x18, 0xe6, 0x76, 0xa8, 0xff, 0xac, 0xe1, - 0xc9, 0xc9, 0xfb, 0x9e, 0x17, 0x21, 0x4a, 0xcf, 0x0d, 0xbd, 0xb9, 0x08, 0x0b, 0xa7, 0xe8, 0x4b, - 0xb6, 0xfb, 0x47, 0x13, 0xfb, 0xdd, 0xf7, 0xbc, 0x0a, 0xd9, 0xc6, 0x95, 0x56, 0x25, 0x72, 0xdc, - 0xfd, 0xbe, 0xa1, 0xee, 0x03, 0xd1, 0x65, 0x98, 0x60, 0x2d, 0xbb, 0xe6, 0xd0, 0x9a, 0xc4, 0xc8, - 0xca, 0xb0, 0xd6, 0x23, 0x87, 0xd6, 0xf4, 0x35, 0xc8, 0xb9, 0x24, 0xc0, 0x36, 0x47, 0x43, 0x85, - 0x75, 0x36, 0x0e, 0xeb, 0x26, 0x09, 0x70, 0xa5, 0xdd, 0x40, 0x56, 0xd6, 0x55, 0x23, 0x7d, 0x05, - 0xc6, 0x1b, 0x11, 0x21, 0x7b, 0x85, 0xf1, 0x65, 0x6d, 0x75, 0x72, 0x3d, 0x1f, 0x2f, 0x7d, 0xc2, - 0x99, 0x96, 0x9c, 0xe3, 0x7e, 0x57, 0xeb, 0xc4, 0xdd, 0x97, 0xfb, 0x65, 0xa4, 0xdf, 0x82, 0x23, - 0xb6, 0xbc, 0x02, 0x59, 0xd6, 0xb2, 0x03, 0xec, 0xa1, 0x56, 0x61, 0x42, 0x9a, 0xc9, 0x5a, 0xdb, - 0x9c, 0x54, 0x90, 0x74, 0xbb, 0x9c, 0x40, 0xf2, 0xbb, 0xcc, 0xfd, 0x6f, 0x6a, 0x01, 0x43, 0xf5, - 0x80, 0xb2, 0x07, 0xd6, 0xe6, 0xfa, 0xcd, 0x3e, 0x80, 0xac, 0x40, 0x1e, 0x45, 0xee, 0xfa, 0x4d, - 0xdb, 0x91, 0xd8, 0xaa, 0x18, 0x4c, 0x09, 0x66, 0x1c, 0xbf, 0x4e, 0xd4, 0x46, 0xd3, 0xa8, 0xe9, - 0x30, 0x86, 0x9d, 0x50, 0xe2, 0x92, 0xb3, 0xc4, 0x58, 0xbf, 0x04, 0x19, 0xda, 0x0e, 0xab, 0xa4, - 0x2e, 0x20, 0xc8, 0x59, 0x8a, 0xd2, 0x0d, 0xc8, 0x7a, 0xc8, 0x0d, 0x42, 0xa7, 0x4e, 0x85, 0xcb, - 0x79, 0x2b, 0xa1, 0xf5, 0x05, 0xc8, 0xf9, 0x0e, 0xb5, 0xeb, 0x41, 0x18, 0x30, 0xe5, 0x72, 0xd6, - 0x77, 0xe8, 0x57, 0x9c, 0x36, 0x6d, 0x51, 0x26, 0x69, 0x9f, 0x62, 0x8f, 0xb9, 0x07, 0x87, 0x29, - 0x0f, 0xa4, 0x87, 0x53, 0x87, 0x9d, 0x1e, 0x2c, 0x02, 0xb8, 0x6e, 0x02, 0xa9, 0xca, 0x33, 0xce, - 0x91, 0xa0, 0xbe, 0xd6, 0x60, 0x3e, 0x46, 0x75, 0xb7, 0xc9, 0xde, 0x31, 0x93, 0xe6, 0x61, 0x1c, - 0x13, 0xec, 0x22, 0x81, 0xd5, 0x98, 0x25, 0x89, 0xce, 0xfc, 0x1a, 0x4b, 0xe5, 0xd7, 0x7b, 0x4e, - 0x98, 0xcf, 0xe0, 0xea, 0x69, 0xae, 0x25, 0xf8, 0x2d, 0x02, 0x04, 0xd4, 0x8e, 0x50, 0x48, 0x0e, - 0x90, 0x27, 0xbc, 0xcc, 0x5a, 0xb9, 0x80, 0x5a, 0x92, 0x61, 0xee, 0x09, 0xec, 0x25, 0xf5, 0x30, - 0x22, 0xe1, 0x7b, 0x82, 0xc7, 0x5c, 0x81, 0x6b, 0x3d, 0xf7, 0x49, 0xb2, 0xfb, 0x17, 0x0d, 0x66, - 0x77, 0xa8, 0xbf, 0xe5, 0xd0, 0x27, 0x51, 0xe0, 0xa2, 0x41, 0x07, 0x7b, 0x7f, 0x23, 0x1a, 0x5c, - 0x45, 0x6c, 0x84, 0x20, 0xf4, 0x6b, 0x30, 0x25, 0x51, 0xc6, 0xcd, 0xb0, 0x8a, 0x22, 0x11, 0xa8, - 0x31, 0x6b, 0x52, 0xf0, 0x1e, 0x0b, 0x96, 0x48, 0xee, 0x66, 0xa3, 0x51, 0x6f, 0x27, 0xc9, 0x2d, - 0x28, 0xd3, 0x80, 0x42, 0xb7, 0x65, 0x89, 0xd9, 0xaf, 0xc7, 0x45, 0xd1, 0x72, 0xe6, 0x2e, 0xde, - 0xad, 0x52, 0x14, 0x1d, 0x20, 0x6f, 0xb7, 0xc9, 0xaa, 0xa4, 0x89, 0xbd, 0x4a, 0xab, 0x8f, 0x07, - 0x0b, 0x20, 0xb2, 0x54, 0x46, 0x5d, 0xa6, 0x6d, 0x96, 0x33, 0x44, 0xd0, 0x4b, 0x30, 0x47, 0x94, - 0x32, 0x9b, 0x70, 0xb8, 0x3a, 0x4f, 0xaf, 0x0b, 0xe4, 0x78, 0x9f, 0x8a, 0x5c, 0xff, 0x29, 0x18, - 0x5d, 0xeb, 0x65, 0x02, 0xc9, 0x96, 0x26, 0x7d, 0x2d, 0xa4, 0xc4, 0x36, 0x8e, 0xe7, 0xf5, 0x8f, - 0xe0, 0x72, 0x97, 0x34, 0x2f, 0xd8, 0x26, 0x45, 0x5e, 0x01, 0x84, 0xe8, 0x7c, 0x4a, 0x74, 0xcb, - 0xa1, 0xcf, 0x28, 0xf2, 0xf4, 0x43, 0x30, 0xbb, 0xc4, 0xd0, 0xde, 0x1e, 0x72, 0x59, 0x70, 0x80, - 0x84, 0x02, 0x19, 0x85, 0x49, 0xd1, 0x95, 0x4a, 0xaa, 0x2b, 0xdd, 0x18, 0xa2, 0x2b, 0x6d, 0x63, - 0x66, 0x15, 0x53, 0x3b, 0x3e, 0x88, 0xf5, 0xc6, 0x41, 0xd0, 0xbf, 0x18, 0xb0, 0xb7, 0x3c, 0x6d, - 0xa6, 0x84, 0xf5, 0xbd, 0x75, 0x89, 0x33, 0x48, 0x27, 0x30, 0x7d, 0xe0, 0xd4, 0x9b, 0xc8, 0x8e, - 0x64, 0x27, 0xf7, 0x64, 0xfc, 0x37, 0x1e, 0x9d, 0xb1, 0x93, 0xfe, 0xfb, 0x66, 0xe9, 0x62, 0xdb, - 0x09, 0xeb, 0xf7, 0xcc, 0xb4, 0x3a, 0xd3, 0xca, 0x0b, 0x86, 0xba, 0x28, 0x78, 0x1d, 0x57, 0x89, - 0xcc, 0x10, 0x57, 0x09, 0x7d, 0x09, 0x26, 0xa5, 0x8b, 0x22, 0xc3, 0xd5, 0x21, 0x00, 0x82, 0xb5, - 0xc9, 0x39, 0xfa, 0x0d, 0x98, 0x91, 0x0b, 0x78, 0xc3, 0x95, 0x05, 0x98, 0x15, 0x9e, 0xe7, 0x05, - 0xbb, 0x42, 0xe9, 0x63, 0x71, 0x4e, 0xa5, 0xda, 0x5d, 0x6e, 0x50, 0xbb, 0x33, 0xaf, 0xc3, 0x4a, - 0x9f, 0xd4, 0x4e, 0x4a, 0xe0, 0xc5, 0x98, 0xb8, 0x38, 0xa4, 0xd7, 0x6d, 0xe3, 0xc1, 0x15, 0xc0, - 0xeb, 0x0d, 0x61, 0x0f, 0x45, 0x2a, 0xfd, 0x15, 0xc5, 0xdd, 0x91, 0x23, 0xbb, 0xab, 0x35, 0xe5, - 0x25, 0x7b, 0x53, 0x15, 0xba, 0x01, 0x59, 0x05, 0x71, 0xa4, 0xce, 0xdd, 0x84, 0xd6, 0xaf, 0xc3, - 0x74, 0x3c, 0x56, 0xb0, 0x8d, 0x4b, 0x15, 0x31, 0x57, 0x22, 0x77, 0x7c, 0x79, 0xca, 0xbc, 0xd3, - 0xe5, 0x89, 0x7b, 0x19, 0x22, 0x4a, 0x1d, 0x5f, 0x42, 0x9f, 0xb3, 0x62, 0x52, 0xbf, 0x0a, 0xc0, - 0x21, 0x57, 0x15, 0x9c, 0x93, 0x76, 0x06, 0x58, 0x15, 0xee, 0x0d, 0x98, 0x09, 0xb0, 0xad, 0xce, - 0x7f, 0x59, 0xad, 0xb2, 0xe4, 0xf2, 0x01, 0xee, 0x2c, 0xd1, 0x54, 0x13, 0x9d, 0x14, 0x2b, 0x92, - 0x26, 0x9a, 0x8e, 0xeb, 0xd4, 0xc0, 0x6b, 0xcc, 0x02, 0xe4, 0x58, 0xcb, 0x26, 0x51, 0xe0, 0x07, - 0xb8, 0x90, 0x97, 0x06, 0xb1, 0xd6, 0xae, 0xa0, 0xf9, 0xe9, 0xe9, 0x50, 0x8a, 0x58, 0x61, 0x5a, - 0x4c, 0x48, 0x82, 0xa7, 0x20, 0x3a, 0x40, 0x98, 0xa9, 0x3e, 0x34, 0x23, 0x0c, 0x00, 0xc1, 0x92, - 0xad, 0xe8, 0xff, 0x60, 0xf6, 0xce, 0x81, 0x38, 0x55, 0xd6, 0xff, 0x02, 0x18, 0xdd, 0xa1, 0xbe, - 0xfe, 0xbd, 0x06, 0x17, 0x4e, 0x76, 0xe4, 0xdb, 0xa5, 0xbe, 0xff, 0x09, 0xa5, 0xd3, 0x7a, 0x9d, - 0xf1, 0xc9, 0x39, 0x84, 0x92, 0x06, 0xf9, 0x42, 0x83, 0xd9, 0x13, 0x57, 0xcc, 0xf5, 0x21, 0x35, - 0x76, 0xc8, 0x18, 0xf7, 0xce, 0x2e, 0x93, 0x18, 0xf1, 0x93, 0x06, 0x97, 0x7a, 0x34, 0xe1, 0x3b, - 0x83, 0xd5, 0x9e, 0x2e, 0x69, 0x7c, 0x7e, 0x5e, 0xc9, 0xc4, 0xac, 0x36, 0xe4, 0xd3, 0xcd, 0xb8, - 0x3c, 0x58, 0x65, 0x4a, 0xc0, 0xf8, 0xf8, 0x8c, 0x02, 0xc9, 0xd6, 0xbf, 0x6a, 0x50, 0xe8, 0xd9, - 0x51, 0x87, 0x80, 0xba, 0x97, 0xac, 0xb1, 0x71, 0x7e, 0xd9, 0xc4, 0xb8, 0x9f, 0x35, 0xb8, 0xdc, - 0xeb, 0xac, 0xbb, 0x7b, 0x56, 0xfd, 0x89, 0xa8, 0x71, 0xff, 0xdc, 0xa2, 0x89, 0x65, 0xdf, 0xc2, - 0x74, 0xd7, 0xcf, 0xc1, 0xcd, 0xc1, 0x4a, 0xd3, 0x12, 0xc6, 0x9d, 0xb3, 0x4a, 0xa4, 0x6a, 0xe9, - 0xc4, 0xef, 0xe1, 0x10, 0xb5, 0xd4, 0x2d, 0x33, 0x4c, 0x2d, 0xf5, 0xfa, 0x6d, 0xd4, 0xbf, 0x83, - 0x99, 0xee, 0x9f, 0xea, 0x5b, 0x83, 0xd5, 0x75, 0x89, 0x18, 0x77, 0xcf, 0x2c, 0xd2, 0x19, 0x83, - 0xae, 0xc7, 0x89, 0x21, 0x62, 0x90, 0x96, 0x18, 0x26, 0x06, 0xa7, 0xbf, 0x2b, 0x6c, 0x7c, 0xf9, - 0xf2, 0x6d, 0x51, 0x7b, 0xf5, 0xb6, 0xa8, 0xfd, 0xfd, 0xb6, 0xa8, 0xfd, 0x70, 0x54, 0x1c, 0x79, - 0x75, 0x54, 0x1c, 0xf9, 0xe3, 0xa8, 0x38, 0xf2, 0xfc, 0x56, 0x47, 0x43, 0xe3, 0x3a, 0xd7, 0xe4, - 0x13, 0x4d, 0xac, 0xbe, 0xdc, 0x2a, 0x77, 0x3e, 0xdc, 0xf0, 0xfe, 0x56, 0xcd, 0x88, 0x27, 0x97, - 0xdb, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x47, 0x0c, 0x03, 0xae, 0xd3, 0x11, 0x00, 0x00, + // 1449 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x6d, 0x4f, 0xdb, 0xd6, + 0x17, 0xc7, 0x7f, 0x20, 0x24, 0x07, 0x02, 0xd4, 0xd0, 0x36, 0x35, 0x25, 0x50, 0xf3, 0x6f, 0x87, + 0x26, 0x91, 0xb4, 0x54, 0xd3, 0xda, 0x6e, 0x93, 0x06, 0x51, 0x4b, 0xd9, 0x4a, 0xa9, 0x4c, 0xba, + 0x4d, 0x7d, 0x63, 0x39, 0xf6, 0xc5, 0xb1, 0x88, 0x7d, 0x23, 0xdf, 0x6b, 0x94, 0xa0, 0x49, 0x93, + 0x2a, 0xed, 0xfd, 0x34, 0x4d, 0xda, 0xb4, 0x2f, 0xb0, 0xaf, 0xd2, 0x97, 0xd5, 0x5e, 0xad, 0x9b, + 0x54, 0x4d, 0xed, 0x27, 0xd8, 0x3e, 0xc1, 0x74, 0x1f, 0x6c, 0xe2, 0x40, 0x1e, 0xa0, 0xea, 0xab, + 0xdc, 0x73, 0xee, 0x3d, 0x4f, 0xbf, 0x73, 0xce, 0x3d, 0x37, 0x86, 0x39, 0x3b, 0xc4, 0x84, 0xd8, + 0x75, 0xcb, 0x0b, 0xca, 0xb4, 0x55, 0x6a, 0x86, 0x98, 0x62, 0x75, 0xf1, 0x08, 0x51, 0x8b, 0xf3, + 0x4a, 0x7c, 0x85, 0x43, 0x54, 0x3a, 0x3e, 0xa7, 0xcd, 0xd9, 0xd8, 0xf7, 0x71, 0x50, 0x16, 0x3f, + 0x42, 0x46, 0x9b, 0x77, 0xb1, 0x8b, 0xf9, 0xb2, 0xcc, 0x56, 0x82, 0xab, 0xff, 0xa6, 0xc0, 0x85, + 0x1d, 0xe2, 0x56, 0x42, 0x64, 0x51, 0x54, 0xdd, 0xdb, 0xfb, 0x0a, 0x53, 0x14, 0xaa, 0x05, 0x98, + 0xb0, 0x19, 0x07, 0x87, 0x05, 0x65, 0x59, 0x59, 0xcd, 0x19, 0x31, 0xa9, 0x2e, 0x02, 0x50, 0x42, + 0xcc, 0x66, 0x54, 0x3b, 0x40, 0xed, 0xc2, 0xff, 0xf8, 0x66, 0x8e, 0x12, 0xf2, 0x84, 0x33, 0xd4, + 0x0f, 0x61, 0xf6, 0x00, 0xb5, 0xb7, 0x50, 0xf0, 0x0c, 0x51, 0xeb, 0x21, 0xf2, 0xdc, 0x3a, 0x2d, + 0x8c, 0x2e, 0x2b, 0xab, 0xa3, 0xc6, 0x09, 0xbe, 0xba, 0x06, 0x19, 0x42, 0x2d, 0x1a, 0x91, 0xc2, + 0xd8, 0xb2, 0xb2, 0x3a, 0xbd, 0x7e, 0xb1, 0x24, 0xfd, 0x35, 0x90, 0x8d, 0xbc, 0x43, 0xb4, 0xc7, + 0x37, 0x0d, 0x79, 0x48, 0x5f, 0x80, 0x2b, 0x27, 0x1c, 0x35, 0x10, 0x69, 0xe2, 0x80, 0x20, 0xfd, + 0x47, 0x05, 0xd4, 0x1d, 0xe2, 0xee, 0x78, 0x6e, 0xc8, 0xb6, 0x09, 0x79, 0x10, 0x05, 0x0e, 0xe9, + 0x13, 0xc7, 0x15, 0xc8, 0x72, 0xac, 0x4c, 0xcf, 0xe1, 0x51, 0x8c, 0x1a, 0x13, 0x9c, 0xde, 0x76, + 0xd4, 0x2d, 0xc8, 0x58, 0x3e, 0x8e, 0x02, 0xe1, 0x79, 0x6e, 0xb3, 0xfc, 0xe2, 0xf5, 0xd2, 0xc8, + 0x9f, 0xaf, 0x97, 0x3e, 0x70, 0x3d, 0x5a, 0x8f, 0x6a, 0xcc, 0xcb, 0xb2, 0x8d, 0x89, 0x8f, 0x89, + 0xfc, 0x59, 0x23, 0xce, 0x41, 0x99, 0xb6, 0x9b, 0x88, 0x94, 0x9e, 0x7a, 0x01, 0x35, 0xa4, 0xb8, + 0x7e, 0x15, 0xb4, 0x93, 0x3e, 0x25, 0x2e, 0x3f, 0x86, 0xb9, 0x1d, 0xe2, 0x3e, 0x6d, 0x3a, 0x62, + 0x73, 0xc3, 0x71, 0x42, 0x44, 0xc8, 0xb9, 0xa1, 0xd7, 0x17, 0x61, 0xe1, 0x14, 0x7d, 0x89, 0xb9, + 0x7f, 0x14, 0x6e, 0x6f, 0xc3, 0x71, 0xaa, 0x78, 0x3b, 0xa8, 0xb6, 0xaa, 0xa1, 0x65, 0x1f, 0xf4, + 0x4d, 0x75, 0x1f, 0x88, 0x2e, 0xc3, 0x04, 0x6d, 0x99, 0x75, 0x8b, 0xd4, 0x05, 0x46, 0x46, 0x86, + 0xb6, 0x1e, 0x5a, 0xa4, 0xae, 0xae, 0x41, 0xce, 0xc6, 0x5e, 0x60, 0x32, 0x34, 0x64, 0x5a, 0x67, + 0xe3, 0xb4, 0x56, 0xb0, 0x17, 0x54, 0xdb, 0x4d, 0x64, 0x64, 0x6d, 0xb9, 0x52, 0x57, 0x60, 0xbc, + 0x19, 0x62, 0xbc, 0x5f, 0x18, 0x5f, 0x56, 0x56, 0x27, 0xd7, 0xf3, 0xf1, 0xd1, 0x27, 0x8c, 0x69, + 0x88, 0x3d, 0x16, 0x77, 0xad, 0x81, 0xed, 0x03, 0x61, 0x2f, 0x23, 0xe2, 0xe6, 0x1c, 0x6e, 0xf2, + 0x0a, 0x64, 0x69, 0xcb, 0xf4, 0x02, 0x07, 0xb5, 0x0a, 0x13, 0xc2, 0x4d, 0xda, 0xda, 0x66, 0xa4, + 0x84, 0xa4, 0x3b, 0xe4, 0x04, 0x92, 0xdf, 0x45, 0xed, 0x7f, 0x5d, 0xf7, 0x28, 0x6a, 0x78, 0x84, + 0xde, 0x37, 0x2a, 0xeb, 0x37, 0xfb, 0x00, 0xb2, 0x02, 0x79, 0x14, 0xda, 0xeb, 0x37, 0x4d, 0x4b, + 0x60, 0x2b, 0x73, 0x30, 0xc5, 0x99, 0x71, 0xfe, 0x3a, 0x51, 0x1b, 0x4d, 0xa3, 0xa6, 0xc2, 0x58, + 0x60, 0xf9, 0x02, 0x97, 0x9c, 0xc1, 0xd7, 0xea, 0x25, 0xc8, 0x90, 0xb6, 0x5f, 0xc3, 0x0d, 0x0e, + 0x41, 0xce, 0x90, 0x94, 0xaa, 0x41, 0xd6, 0x41, 0xb6, 0xe7, 0x5b, 0x0d, 0xc2, 0x43, 0xce, 0x1b, + 0x09, 0xad, 0x2e, 0x40, 0xce, 0xb5, 0x88, 0xd9, 0xf0, 0x7c, 0x8f, 0xca, 0x90, 0xb3, 0xae, 0x45, + 0x1e, 0x31, 0x5a, 0x37, 0x79, 0x9b, 0xa4, 0x63, 0x8a, 0x23, 0x66, 0x11, 0x1c, 0xa5, 0x22, 0x10, + 0x11, 0x4e, 0x1d, 0x75, 0x46, 0xb0, 0x08, 0x60, 0xdb, 0x09, 0xa4, 0xb2, 0xce, 0x18, 0x47, 0x80, + 0xfa, 0x4a, 0x81, 0xf9, 0x18, 0xd5, 0xdd, 0x88, 0xbe, 0x63, 0x25, 0xcd, 0xc3, 0x78, 0x80, 0x03, + 0x1b, 0x71, 0xac, 0xc6, 0x0c, 0x41, 0x74, 0xd6, 0xd7, 0x58, 0xaa, 0xbe, 0xde, 0x73, 0xc1, 0x7c, + 0x06, 0x57, 0x4f, 0x0b, 0x2d, 0xc1, 0x6f, 0x11, 0xc0, 0x23, 0x66, 0x88, 0x7c, 0x7c, 0x88, 0x1c, + 0x1e, 0x65, 0xd6, 0xc8, 0x79, 0xc4, 0x10, 0x0c, 0x7d, 0x9f, 0x63, 0x2f, 0xa8, 0x07, 0x21, 0xf6, + 0xdf, 0x13, 0x3c, 0xfa, 0x0a, 0x5c, 0xeb, 0x69, 0x27, 0xa9, 0xee, 0x5f, 0x14, 0x98, 0xdd, 0x21, + 0xee, 0x96, 0x45, 0x9e, 0x84, 0x9e, 0x8d, 0x06, 0x5d, 0xec, 0xfd, 0x9d, 0x68, 0x32, 0x15, 0xb1, + 0x13, 0x9c, 0x50, 0xaf, 0xc1, 0x94, 0x40, 0x39, 0x88, 0xfc, 0x1a, 0x0a, 0x79, 0xa2, 0xc6, 0x8c, + 0x49, 0xce, 0x7b, 0xcc, 0x59, 0xbc, 0xb8, 0xa3, 0x66, 0xb3, 0xd1, 0x4e, 0x8a, 0x9b, 0x53, 0xba, + 0x06, 0x85, 0x6e, 0xcf, 0x12, 0xb7, 0x5f, 0x8d, 0xf3, 0xa6, 0x65, 0xcc, 0xdd, 0x60, 0xb7, 0x46, + 0x50, 0x78, 0x88, 0x9c, 0xdd, 0x88, 0xd6, 0x70, 0x14, 0x38, 0xd5, 0x56, 0x9f, 0x08, 0x16, 0x80, + 0x57, 0xa9, 0xc8, 0xba, 0x28, 0xdb, 0x2c, 0x63, 0xf0, 0xa4, 0x97, 0x60, 0x0e, 0x4b, 0x65, 0x26, + 0x66, 0x70, 0x75, 0xde, 0x5e, 0x17, 0xf0, 0xb1, 0x9d, 0xaa, 0x38, 0xff, 0x29, 0x68, 0x5d, 0xe7, + 0x45, 0x01, 0x89, 0x91, 0x26, 0x62, 0x2d, 0xa4, 0xc4, 0x36, 0x8f, 0xf7, 0xd5, 0x8f, 0xe0, 0x72, + 0x97, 0x34, 0x6b, 0xd8, 0x88, 0x20, 0xa7, 0x00, 0x5c, 0x74, 0x3e, 0x25, 0xba, 0x65, 0x91, 0xa7, + 0x04, 0x39, 0xea, 0x11, 0xe8, 0x5d, 0x62, 0x68, 0x7f, 0x1f, 0xd9, 0xd4, 0x3b, 0x44, 0x5c, 0x81, + 0xc8, 0xc2, 0x24, 0x9f, 0x4a, 0x25, 0x39, 0x95, 0x6e, 0x0c, 0x31, 0x95, 0xb6, 0x03, 0x6a, 0x14, + 0x53, 0x16, 0xef, 0xc7, 0x7a, 0xe3, 0x24, 0xa8, 0x5f, 0x0c, 0xb0, 0x2d, 0x6e, 0x9b, 0x29, 0xee, + 0x7d, 0x6f, 0x5d, 0xfc, 0x0e, 0x52, 0x31, 0x4c, 0x1f, 0x5a, 0x8d, 0x08, 0x99, 0xa1, 0x98, 0xe4, + 0x8e, 0xc8, 0xff, 0xe6, 0xc3, 0x33, 0x4e, 0xd2, 0x7f, 0x5f, 0x2f, 0x5d, 0x6c, 0x5b, 0x7e, 0xe3, + 0x9e, 0x9e, 0x56, 0xa7, 0x1b, 0x79, 0xce, 0x90, 0x0f, 0x05, 0xa7, 0xe3, 0x29, 0x91, 0x19, 0xe2, + 0x29, 0xa1, 0x2e, 0xc1, 0xa4, 0x08, 0x91, 0x57, 0xb8, 0xbc, 0x04, 0x80, 0xb3, 0x2a, 0x8c, 0xa3, + 0xde, 0x80, 0x19, 0x71, 0x80, 0x0d, 0x5c, 0xd1, 0x80, 0x59, 0x1e, 0x79, 0x9e, 0xb3, 0xab, 0x84, + 0x3c, 0xe6, 0xf7, 0x54, 0x6a, 0xdc, 0xe5, 0x06, 0x8d, 0x3b, 0xfd, 0x3a, 0xac, 0xf4, 0x29, 0xed, + 0xa4, 0x05, 0x9e, 0x8f, 0xf1, 0x87, 0x43, 0xfa, 0xdc, 0x76, 0x30, 0xb8, 0x03, 0x58, 0xbf, 0xa1, + 0xc0, 0x41, 0xa1, 0x2c, 0x7f, 0x49, 0xb1, 0x70, 0xc4, 0xca, 0xec, 0x1a, 0x4d, 0x79, 0xc1, 0xae, + 0xc8, 0x46, 0xd7, 0x20, 0x2b, 0x21, 0x0e, 0xe5, 0xbd, 0x9b, 0xd0, 0xea, 0x75, 0x98, 0x8e, 0xd7, + 0x12, 0xb6, 0x71, 0xa1, 0x22, 0xe6, 0x0a, 0xe4, 0x8e, 0x1f, 0x4f, 0x99, 0x77, 0x7a, 0x3c, 0xb1, + 0x28, 0x7d, 0x44, 0x88, 0xe5, 0x0a, 0xe8, 0x73, 0x46, 0x4c, 0xaa, 0x57, 0x01, 0x18, 0xe4, 0xb2, + 0x83, 0x73, 0xc2, 0x4f, 0x2f, 0x90, 0x8d, 0x7b, 0x03, 0x66, 0xbc, 0xc0, 0x94, 0xf7, 0xbf, 0xe8, + 0x56, 0xd1, 0x72, 0x79, 0x2f, 0xe8, 0x6c, 0xd1, 0xd4, 0x10, 0x9d, 0xe4, 0x27, 0x92, 0x21, 0x9a, + 0xce, 0xeb, 0xd4, 0xc0, 0x67, 0xcc, 0x02, 0xe4, 0x68, 0xcb, 0xc4, 0xa1, 0xe7, 0x7a, 0x41, 0x21, + 0x2f, 0x1c, 0xa2, 0xad, 0x5d, 0x4e, 0xb3, 0xdb, 0xd3, 0x22, 0x04, 0xd1, 0xc2, 0x34, 0xdf, 0x10, + 0x04, 0x2b, 0x41, 0x74, 0x88, 0x02, 0x2a, 0xe7, 0xd0, 0x0c, 0x77, 0x00, 0x38, 0x4b, 0x8c, 0xa2, + 0xff, 0x83, 0xde, 0xbb, 0x06, 0x92, 0x52, 0x79, 0xc4, 0x5f, 0x30, 0x1b, 0x35, 0x1c, 0xd2, 0x3d, + 0x1a, 0xd9, 0x07, 0x95, 0x4a, 0xf5, 0x9b, 0xfe, 0x4f, 0xc8, 0x7e, 0xa3, 0x5d, 0x3c, 0xb1, 0xd3, + 0xda, 0x62, 0x53, 0xeb, 0x7f, 0x4d, 0xc2, 0xe8, 0x0e, 0x71, 0xd5, 0xef, 0x15, 0xb8, 0x70, 0x72, + 0xf8, 0xdf, 0x2e, 0xf5, 0xfd, 0x4b, 0x52, 0x3a, 0x6d, 0xac, 0x6a, 0x9f, 0x9c, 0x43, 0x28, 0x99, + 0xc5, 0xcf, 0x15, 0x98, 0x3d, 0xf1, 0x9a, 0x5d, 0x1f, 0x52, 0x63, 0x87, 0x8c, 0x76, 0xef, 0xec, + 0x32, 0x89, 0x13, 0x3f, 0x29, 0x70, 0xa9, 0xc7, 0xbc, 0xbf, 0x33, 0x58, 0xed, 0xe9, 0x92, 0xda, + 0xe7, 0xe7, 0x95, 0x4c, 0xdc, 0x6a, 0x43, 0x3e, 0x3d, 0xf7, 0xcb, 0x83, 0x55, 0xa6, 0x04, 0xb4, + 0x8f, 0xcf, 0x28, 0x90, 0x98, 0xfe, 0x55, 0x81, 0x42, 0xcf, 0xe1, 0x3d, 0x04, 0xd4, 0xbd, 0x64, + 0xb5, 0xcd, 0xf3, 0xcb, 0x26, 0xce, 0xfd, 0xac, 0xc0, 0xe5, 0x5e, 0xd7, 0xea, 0xdd, 0xb3, 0xea, + 0x4f, 0x44, 0xb5, 0x8d, 0x73, 0x8b, 0x26, 0x9e, 0x7d, 0x0b, 0xd3, 0x5d, 0xff, 0x43, 0x6e, 0x0e, + 0x56, 0x9a, 0x96, 0xd0, 0xee, 0x9c, 0x55, 0x22, 0xd5, 0x4b, 0x27, 0xfe, 0x89, 0x0e, 0xd1, 0x4b, + 0xdd, 0x32, 0xc3, 0xf4, 0x52, 0xaf, 0x7f, 0xa8, 0xea, 0x77, 0x30, 0xd3, 0xfd, 0xff, 0xfd, 0xd6, + 0x60, 0x75, 0x5d, 0x22, 0xda, 0xdd, 0x33, 0x8b, 0x74, 0xe6, 0xa0, 0xeb, 0x3b, 0xc8, 0x10, 0x39, + 0x48, 0x4b, 0x0c, 0x93, 0x83, 0xd3, 0x3f, 0x61, 0x30, 0xeb, 0x5d, 0xf7, 0xf8, 0x10, 0xd6, 0xd3, + 0x12, 0xc3, 0x58, 0x3f, 0xfd, 0x76, 0xdf, 0xfc, 0xf2, 0xc5, 0x9b, 0xa2, 0xf2, 0xf2, 0x4d, 0x51, + 0xf9, 0xfb, 0x4d, 0x51, 0xf9, 0xe1, 0x6d, 0x71, 0xe4, 0xe5, 0xdb, 0xe2, 0xc8, 0x1f, 0x6f, 0x8b, + 0x23, 0xcf, 0x6e, 0x75, 0x4c, 0x6e, 0xa6, 0x73, 0x4d, 0x7c, 0x8b, 0x8a, 0xd5, 0x97, 0x5b, 0xe5, + 0xce, 0x2f, 0x54, 0x6c, 0x90, 0xd7, 0x32, 0xfc, 0xdb, 0xd2, 0xed, 0xff, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x1e, 0x53, 0x7a, 0xa6, 0xbc, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1401,6 +1494,7 @@ type MsgClient interface { UpdateTssAddress(ctx context.Context, in *MsgUpdateTssAddress, opts ...grpc.CallOption) (*MsgUpdateTssAddressResponse, error) MigrateTssFunds(ctx context.Context, in *MsgMigrateTssFunds, opts ...grpc.CallOption) (*MsgMigrateTssFundsResponse, error) CreateTSSVoter(ctx context.Context, in *MsgCreateTSSVoter, opts ...grpc.CallOption) (*MsgCreateTSSVoterResponse, error) + AbortStuckCCTX(ctx context.Context, in *MsgAbortStuckCCTX, opts ...grpc.CallOption) (*MsgAbortStuckCCTXResponse, error) } type msgClient struct { @@ -1501,6 +1595,15 @@ func (c *msgClient) CreateTSSVoter(ctx context.Context, in *MsgCreateTSSVoter, o return out, nil } +func (c *msgClient) AbortStuckCCTX(ctx context.Context, in *MsgAbortStuckCCTX, opts ...grpc.CallOption) (*MsgAbortStuckCCTXResponse, error) { + out := new(MsgAbortStuckCCTXResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Msg/AbortStuckCCTX", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AddToOutTxTracker(context.Context, *MsgAddToOutTxTracker) (*MsgAddToOutTxTrackerResponse, error) @@ -1513,6 +1616,7 @@ type MsgServer interface { UpdateTssAddress(context.Context, *MsgUpdateTssAddress) (*MsgUpdateTssAddressResponse, error) MigrateTssFunds(context.Context, *MsgMigrateTssFunds) (*MsgMigrateTssFundsResponse, error) CreateTSSVoter(context.Context, *MsgCreateTSSVoter) (*MsgCreateTSSVoterResponse, error) + AbortStuckCCTX(context.Context, *MsgAbortStuckCCTX) (*MsgAbortStuckCCTXResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1549,6 +1653,9 @@ func (*UnimplementedMsgServer) MigrateTssFunds(ctx context.Context, req *MsgMigr func (*UnimplementedMsgServer) CreateTSSVoter(ctx context.Context, req *MsgCreateTSSVoter) (*MsgCreateTSSVoterResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateTSSVoter not implemented") } +func (*UnimplementedMsgServer) AbortStuckCCTX(ctx context.Context, req *MsgAbortStuckCCTX) (*MsgAbortStuckCCTXResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AbortStuckCCTX not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -1734,6 +1841,24 @@ func _Msg_CreateTSSVoter_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Msg_AbortStuckCCTX_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAbortStuckCCTX) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AbortStuckCCTX(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.crosschain.Msg/AbortStuckCCTX", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AbortStuckCCTX(ctx, req.(*MsgAbortStuckCCTX)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.crosschain.Msg", HandlerType: (*MsgServer)(nil), @@ -1778,6 +1903,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "CreateTSSVoter", Handler: _Msg_CreateTSSVoter_Handler, }, + { + MethodName: "AbortStuckCCTX", + Handler: _Msg_AbortStuckCCTX_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "crosschain/tx.proto", @@ -2677,6 +2806,66 @@ func (m *MsgVoteOnObservedInboundTxResponse) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } +func (m *MsgAbortStuckCCTX) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAbortStuckCCTX) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAbortStuckCCTX) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CctxIndex) > 0 { + i -= len(m.CctxIndex) + copy(dAtA[i:], m.CctxIndex) + i = encodeVarintTx(dAtA, i, uint64(len(m.CctxIndex))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgAbortStuckCCTXResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAbortStuckCCTXResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAbortStuckCCTXResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -3097,6 +3286,32 @@ func (m *MsgVoteOnObservedInboundTxResponse) Size() (n int) { return n } +func (m *MsgAbortStuckCCTX) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.CctxIndex) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAbortStuckCCTXResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -5861,6 +6076,170 @@ func (m *MsgVoteOnObservedInboundTxResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgAbortStuckCCTX) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAbortStuckCCTX: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAbortStuckCCTX: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CctxIndex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CctxIndex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAbortStuckCCTXResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAbortStuckCCTXResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAbortStuckCCTXResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From d1236ba8e6660492b131e224c66c100490401c43 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 25 Jan 2024 14:18:03 -0500 Subject: [PATCH 50/67] feat: Keygen migration script (#1632) * add migration script * add debug logs * remove debug logs * add changelog entry * remove commented code --------- Co-authored-by: Lucas Bertrand --- app/setup_handlers.go | 12 ++++ changelog.md | 3 +- x/observer/keeper/migrator.go | 5 ++ x/observer/migrations/v6/migrate.go | 39 +++++++++++ x/observer/migrations/v6/migrate_test.go | 87 ++++++++++++++++++++++++ x/observer/module.go | 5 +- x/observer/types/errors.go | 1 + 7 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 x/observer/migrations/v6/migrate.go create mode 100644 x/observer/migrations/v6/migrate_test.go diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 8619fa046f..bdb18a0aa8 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" + observerTypes "github.com/zeta-chain/zetacore/x/observer/types" ) const releaseVersion = "v12.1.0" @@ -16,6 +17,8 @@ func SetupHandlers(app *App) { for m, mb := range app.mm.Modules { vm[m] = mb.ConsensusVersion() } + vm = VersionMigrator{vm}.TriggerMigration(observerTypes.ModuleName) + return app.mm.RunMigrations(ctx, app.configurator, vm) }) @@ -34,3 +37,12 @@ func SetupHandlers(app *App) { app.SetStoreLoader(types.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } } + +type VersionMigrator struct { + v module.VersionMap +} + +func (v VersionMigrator) TriggerMigration(moduleName string) module.VersionMap { + v.v[moduleName] = v.v[moduleName] - 1 + return v.v +} diff --git a/changelog.md b/changelog.md index 01cee846e4..1adfa29044 100644 --- a/changelog.md +++ b/changelog.md @@ -5,16 +5,15 @@ ## Version: v12.1.0 ### Tests - * [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests ### Features ### Fixes - * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic * [1650](https://github.com/zeta-chain/node/pull/1605) - exempt (discounted) *system txs* from min gas price check and gas fee deduction +* [1632](https://github.com/zeta-chain/node/pull/1632) - set keygen to `KeygenStatus_KeyGenSuccess` if its in `KeygenStatus_PendingKeygen`. * [1576](https://github.com/zeta-chain/node/pull/1576) - Fix zetaclient crash due to out of bound integer conversion and log prints. * [1575](https://github.com/zeta-chain/node/issues/1575) - Skip unsupported chain parameters by IsSupported flag diff --git a/x/observer/keeper/migrator.go b/x/observer/keeper/migrator.go index 47b8ecfcc7..0cee0ed183 100644 --- a/x/observer/keeper/migrator.go +++ b/x/observer/keeper/migrator.go @@ -6,6 +6,7 @@ import ( v3 "github.com/zeta-chain/zetacore/x/observer/migrations/v3" v4 "github.com/zeta-chain/zetacore/x/observer/migrations/v4" v5 "github.com/zeta-chain/zetacore/x/observer/migrations/v5" + v6 "github.com/zeta-chain/zetacore/x/observer/migrations/v6" ) // Migrator is a struct for handling in-place store migrations. @@ -37,3 +38,7 @@ func (m Migrator) Migrate3to4(ctx sdk.Context) error { func (m Migrator) Migrate4to5(ctx sdk.Context) error { return v5.MigrateStore(ctx, m.observerKeeper) } + +func (m Migrator) Migrate5to6(ctx sdk.Context) error { + return v6.MigrateStore(ctx, m.observerKeeper) +} diff --git a/x/observer/migrations/v6/migrate.go b/x/observer/migrations/v6/migrate.go new file mode 100644 index 0000000000..a678c8a54d --- /dev/null +++ b/x/observer/migrations/v6/migrate.go @@ -0,0 +1,39 @@ +package v6 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// observerKeeper prevents circular dependency +type observerKeeper interface { + SetKeygen(ctx sdk.Context, keygen types.Keygen) + GetKeygen(ctx sdk.Context) (val types.Keygen, found bool) + GetTSS(ctx sdk.Context) (val types.TSS, found bool) + StoreKey() storetypes.StoreKey + Codec() codec.BinaryCodec +} + +func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error { + return SetKeyGenStatus(ctx, observerKeeper) +} + +func SetKeyGenStatus(ctx sdk.Context, keeper observerKeeper) error { + keygen, found := keeper.GetKeygen(ctx) + if !found { + return types.ErrKeygenNotFound + } + if keygen.Status == types.KeygenStatus_PendingKeygen { + tss, foundTss := keeper.GetTSS(ctx) + if !foundTss { + return types.ErrTssNotFound + } + keygen.Status = types.KeygenStatus_KeyGenSuccess + keygen.BlockNumber = tss.KeyGenZetaHeight + keygen.GranteePubkeys = tss.TssParticipantList + keeper.SetKeygen(ctx, keygen) + } + return nil +} diff --git a/x/observer/migrations/v6/migrate_test.go b/x/observer/migrations/v6/migrate_test.go new file mode 100644 index 0000000000..574ece4be4 --- /dev/null +++ b/x/observer/migrations/v6/migrate_test.go @@ -0,0 +1,87 @@ +package v6_test + +import ( + "math" + "testing" + + "github.com/stretchr/testify/assert" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + v6 "github.com/zeta-chain/zetacore/x/observer/migrations/v6" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMigrateObserverParams(t *testing.T) { + t.Run("Migrate when keygen is Pending", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + k.SetKeygen(ctx, types.Keygen{ + Status: types.KeygenStatus_PendingKeygen, + BlockNumber: math.MaxInt64, + }) + participantList := []string{ + "zetapub1addwnpepqglunjrgl3qg08duxq9pf28jmvrer3crwnnfzp6m0u0yh9jk9mnn5p76utc", + "zetapub1addwnpepqwwpjwwnes7cywfkr0afme7ymk8rf5jzhn8pfr6qqvfm9v342486qsrh4f5", + "zetapub1addwnpepq07xj82w5e6vr85qj3r7htmzh2mp3vkvfraapcv6ynhdwankseayk5yh80t", + "zetapub1addwnpepq0lxqx92m3fhae3usn8jffqvtx6cuzl06xh9r345c2qcqq8zyfs4cdpqcum", + "zetapub1addwnpepqvzlntzltvpm22ved5gjtn9nzqfz5fun38el4r64njc979rwanxlgq4u3p8", + "zetapub1addwnpepqg40psrhwwgy257p4xv50xp0asmtwjup66z8vk829289zxge5lyl7sycga8", + "zetapub1addwnpepqgpr5ffquqchra93r8l6d35q62cv4nsc9d4k2q7kten4sljxg5rluwx29gh", + "zetapub1addwnpepqdjf3vt8etgdddkghrvxfmmmeatky6m7hx7wjuv86udfghqpty8h5h4r78w", + "zetapub1addwnpepqtfcfmsdkzdgv03t8392gsh7kzrstp9g864w2ltz9k0xzz33q60dq6mnkex", + } + operatorList := []string{ + "zeta19jr7nl82lrktge35f52x9g5y5prmvchmk40zhg", + "zeta1cxj07f3ju484ry2cnnhxl5tryyex7gev0yzxtj", + "zeta1hjct6q7npsspsg3dgvzk3sdf89spmlpf7rqmnw", + "zeta1k6vh9y7ctn06pu5jngznv5dyy0rltl2qp0j30g", + "zeta1l07weaxkmn6z69qm55t53v4rfr43eys4cjz54h", + "zeta1p0uwsq4naus5r4l7l744upy0k8ezzj84mn40nf", + "zeta1rhj4pkp7eygw8lu9wacpepeh0fnzdxrqr27g6m", + "zeta1t0uj2z93jd2g3w94zl3jhfrn2ek6dnuk3v93j9", + "zeta1t5pgk2fucx3drkynzew9zln5z9r7s3wqqyy0pe", + } + keygenHeight := int64(1440460) + finalizedZetaHeight := int64(1440680) + k.SetTSS(ctx, types.TSS{ + KeyGenZetaHeight: keygenHeight, + TssParticipantList: participantList, + TssPubkey: "zetapub1addwnpepqtadxdyt037h86z60nl98t6zk56mw5zpnm79tsmvspln3hgt5phdc79kvfc", + OperatorAddressList: operatorList, + FinalizedZetaHeight: finalizedZetaHeight, + }) + err := v6.MigrateStore(ctx, k) + assert.NoError(t, err) + keygen, found := k.GetKeygen(ctx) + assert.True(t, found) + assert.Equal(t, types.KeygenStatus_KeyGenSuccess, keygen.Status) + assert.Equal(t, keygenHeight, keygenHeight) + assert.Equal(t, participantList, participantList) + }) + t.Run("Migrate when keygen is not Pending", func(t *testing.T) { + k, ctx := keepertest.ObserverKeeper(t) + participantList := []string{ + "zetapub1addwnpepqglunjrgl3qg08duxq9pf28jmvrer3crwnnfzp6m0u0yh9jk9mnn5p76utc", + "zetapub1addwnpepqwwpjwwnes7cywfkr0afme7ymk8rf5jzhn8pfr6qqvfm9v342486qsrh4f5", + "zetapub1addwnpepq07xj82w5e6vr85qj3r7htmzh2mp3vkvfraapcv6ynhdwankseayk5yh80t", + "zetapub1addwnpepq0lxqx92m3fhae3usn8jffqvtx6cuzl06xh9r345c2qcqq8zyfs4cdpqcum", + "zetapub1addwnpepqvzlntzltvpm22ved5gjtn9nzqfz5fun38el4r64njc979rwanxlgq4u3p8", + "zetapub1addwnpepqg40psrhwwgy257p4xv50xp0asmtwjup66z8vk829289zxge5lyl7sycga8", + "zetapub1addwnpepqgpr5ffquqchra93r8l6d35q62cv4nsc9d4k2q7kten4sljxg5rluwx29gh", + "zetapub1addwnpepqdjf3vt8etgdddkghrvxfmmmeatky6m7hx7wjuv86udfghqpty8h5h4r78w", + "zetapub1addwnpepqtfcfmsdkzdgv03t8392gsh7kzrstp9g864w2ltz9k0xzz33q60dq6mnkex", + } + keygenHeight := int64(1440460) + k.SetKeygen(ctx, types.Keygen{ + Status: types.KeygenStatus_KeyGenSuccess, + BlockNumber: keygenHeight, + GranteePubkeys: participantList, + }) + err := v6.MigrateStore(ctx, k) + assert.NoError(t, err) + keygen, found := k.GetKeygen(ctx) + assert.True(t, found) + assert.Equal(t, types.KeygenStatus_KeyGenSuccess, keygen.Status) + assert.Equal(t, keygen.BlockNumber, keygenHeight) + assert.Equal(t, keygen.GranteePubkeys, participantList) + }) + +} diff --git a/x/observer/module.go b/x/observer/module.go index 563b5188ea..8e4e750608 100644 --- a/x/observer/module.go +++ b/x/observer/module.go @@ -156,6 +156,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err := cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4to5); err != nil { panic(err) } + if err := cfg.RegisterMigration(types.ModuleName, 5, m.Migrate5to6); err != nil { + panic(err) + } } // RegisterInvariants registers the observer module's invariants. @@ -180,7 +183,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 5 } +func (AppModule) ConsensusVersion() uint64 { return 6 } // BeginBlock executes all ABCI BeginBlock logic respective to the observer module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index 8918b08e7f..fd61f4ea4d 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -36,4 +36,5 @@ var ( ErrParamsMinObserverDelegation = errorsmod.Register(ModuleName, 1128, "min observer delegation cannot be nil") ErrMinDelegationNotFound = errorsmod.Register(ModuleName, 1129, "min delegation not found") ErrObserverSetNotFound = errorsmod.Register(ModuleName, 1130, "observer set not found") + ErrTssNotFound = errorsmod.Register(ModuleName, 1131, "tss not found") ) From 62e1bfd8a60fa93a8e3801fdfcbee20ac79afae3 Mon Sep 17 00:00:00 2001 From: fx0x55 <80245546+fx0x55@users.noreply.github.com> Date: Sat, 27 Jan 2024 01:53:01 +0800 Subject: [PATCH 51/67] refactor: optimize some returns (#1628) * refactor: Optimize return delete redundant judgments * changelog --- changelog.md | 4 ++++ common/chain.go | 5 +---- rpc/namespaces/ethereum/debug/utils.go | 6 +----- x/crosschain/keeper/cctx_utils.go | 5 +---- x/crosschain/keeper/msg_server_tss_voter.go | 5 +---- 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index 1adfa29044..18632d0202 100644 --- a/changelog.md +++ b/changelog.md @@ -31,6 +31,10 @@ * [1591](https://github.com/zeta-chain/node/pull/1591) - support lower gas limit for voting on inbound and outbound transactions * [1592](https://github.com/zeta-chain/node/issues/1592) - check inbound tracker tx hash against Tss address and some refactor on inTx observation +### Refactoring + +* [1628](https://github.com/zeta-chain/node/pull/1628) optimize return and simplify code + ## Version: v12.0.0 ### Breaking Changes diff --git a/common/chain.go b/common/chain.go index d6762c1a91..cc3dde3722 100644 --- a/common/chain.go +++ b/common/chain.go @@ -23,10 +23,7 @@ type Chains []Chain // IsEqual compare two chain to see whether they represent the same chain func (chain Chain) IsEqual(c Chain) bool { - if chain.ChainId == c.ChainId { - return true - } - return false + return chain.ChainId == c.ChainId } func (chain Chain) IsZetaChain() bool { diff --git a/rpc/namespaces/ethereum/debug/utils.go b/rpc/namespaces/ethereum/debug/utils.go index a65134977d..bfd8ced432 100644 --- a/rpc/namespaces/ethereum/debug/utils.go +++ b/rpc/namespaces/ethereum/debug/utils.go @@ -30,11 +30,7 @@ import ( func isCPUProfileConfigurationActivated(ctx *server.Context) bool { // TODO: use same constants as server/start.go // constant declared in start.go cannot be imported (cyclical dependency) - const flagCPUProfile = "cpu-profile" - if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" { - return true - } - return false + return ctx.Viper.GetString("cpu-profile") != "" } // ExpandHome expands home directory in file paths. diff --git a/x/crosschain/keeper/cctx_utils.go b/x/crosschain/keeper/cctx_utils.go index 528139af69..7b43123cbe 100644 --- a/x/crosschain/keeper/cctx_utils.go +++ b/x/crosschain/keeper/cctx_utils.go @@ -124,8 +124,5 @@ func (k Keeper) GetRevertGasLimit(ctx sdk.Context, cctx types.CrossChainTx) (uin func IsPending(cctx types.CrossChainTx) bool { // pending inbound is not considered a "pending" state because it has not reached consensus yet - if cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound || cctx.CctxStatus.Status == types.CctxStatus_PendingRevert { - return true - } - return false + return cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound || cctx.CctxStatus.Status == types.CctxStatus_PendingRevert } diff --git a/x/crosschain/keeper/msg_server_tss_voter.go b/x/crosschain/keeper/msg_server_tss_voter.go index 13a97e58ae..29672a1a6d 100644 --- a/x/crosschain/keeper/msg_server_tss_voter.go +++ b/x/crosschain/keeper/msg_server_tss_voter.go @@ -116,8 +116,5 @@ func (k msgServer) CreateTSSVoter(goCtx context.Context, msg *types.MsgCreateTSS // IsAuthorizedNodeAccount checks whether a signer is authorized to sign , by checking their address against the observer mapper which contains the observer list for the chain and type func (k Keeper) IsAuthorizedNodeAccount(ctx sdk.Context, address string) bool { _, found := k.zetaObserverKeeper.GetNodeAccount(ctx, address) - if found { - return true - } - return false + return found } From 72f6407d3741d0d7a44ec44f3a46dd27c1cf7235 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 26 Jan 2024 13:40:29 -0500 Subject: [PATCH 52/67] refactor: add evm amount calculation for tss migration (#1619) * add evm amount calculation for tss migration * add changelog entry * add test for multiplier * Update common/gas_limits.go Co-authored-by: Lucas Bertrand * add additional checks for unit tests * rename crosschainTX to cctx --------- Co-authored-by: Lucas Bertrand --- changelog.md | 3 + common/gas_limits.go | 26 +++ .../keeper/msg_server_migrate_tss_funds.go | 13 ++ .../msg_server_migrate_tss_funds_test.go | 94 ++++++++--- x/crosschain/types/errors.go | 2 + x/crosschain/types/keys.go | 2 + zetaclient/evm_signer.go | 154 +++++++++--------- 7 files changed, 194 insertions(+), 100 deletions(-) create mode 100644 common/gas_limits.go diff --git a/changelog.md b/changelog.md index 18632d0202..bdd9866e84 100644 --- a/changelog.md +++ b/changelog.md @@ -35,6 +35,9 @@ * [1628](https://github.com/zeta-chain/node/pull/1628) optimize return and simplify code +### Refactoring +* [1619](https://github.com/zeta-chain/node/pull/1619) - Add evm fee calculation to tss migration of evm chains + ## Version: v12.0.0 ### Breaking Changes diff --git a/common/gas_limits.go b/common/gas_limits.go new file mode 100644 index 0000000000..bbd1f0a6c5 --- /dev/null +++ b/common/gas_limits.go @@ -0,0 +1,26 @@ +package common + +import ( + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + // EVMSend is the gas limit required to transfer tokens on an EVM based chain + EVMSend = 21000 + // TODO: Move gas limits from zeta-client to this file + // https://github.com/zeta-chain/node/issues/1606 +) + +// MultiplyGasPrice multiplies the median gas price by the given multiplier and returns the truncated value +func MultiplyGasPrice(medianGasPrice sdkmath.Uint, multiplierString string) (sdkmath.Uint, error) { + multiplier, err := sdk.NewDecFromStr(multiplierString) + if err != nil { + return sdkmath.ZeroUint(), err + } + gasPrice, err := sdk.NewDecFromStr(medianGasPrice.String()) + if err != nil { + return sdkmath.ZeroUint(), err + } + return sdkmath.NewUintFromString(gasPrice.Mul(multiplier).TruncateInt().String()), nil +} diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 081e2d6490..a552d0feb4 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -116,6 +116,19 @@ func (k Keeper) MigrateTSSFundsForChain(ctx sdk.Context, chainID int64, amount s } cctx.InboundTxParams.Sender = ethAddressOld.String() cctx.GetCurrentOutTxParam().Receiver = ethAddressNew.String() + // Tss migration is a send transaction, so the gas limit is set to 21000 + cctx.GetCurrentOutTxParam().OutboundTxGasLimit = common.EVMSend + // Multiple current gas price with standard multiplier to add some buffer + multipliedGasPrice, err := common.MultiplyGasPrice(medianGasPrice, types.TssMigrationGasMultiplierEVM) + if err != nil { + return err + } + cctx.GetCurrentOutTxParam().OutboundTxGasPrice = multipliedGasPrice.String() + evmFee := sdkmath.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit).Mul(multipliedGasPrice) + if evmFee.GT(amount) { + return errorsmod.Wrap(types.ErrInsufficientFundsTssMigration, fmt.Sprintf("insufficient funds to pay for gas fee, amount: %s, gas fee: %s, chainid: %d", amount.String(), evmFee.String(), chainID)) + } + cctx.GetCurrentOutTxParam().Amount = amount.Sub(evmFee) } // Set the sender and receiver addresses for Bitcoin chain if common.IsBitcoinChain(chainID) { diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go index 436a6b69c9..4d909abdf0 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -6,7 +6,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/common" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -15,6 +15,33 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) +func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { + t.Run("test gas price multiplier", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) + gp, found := k.GetMedianGasPriceInUint(ctx, chain.ChainId) + require.True(t, found) + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.NoError(t, err) + hash := crypto.Keccak256Hash([]byte(indexString)) + index := hash.Hex() + cctx, found := k.GetCrossChainTx(ctx, index) + require.True(t, found) + multipliedValue, err := common.MultiplyGasPrice(gp, crosschaintypes.TssMigrationGasMultiplierEVM) + require.NoError(t, err) + require.Equal(t, multipliedValue.String(), cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + + }) +} func TestMsgServer_MigrateTssFunds(t *testing.T) { t.Run("successfully create tss migration cctx", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) @@ -22,18 +49,40 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { setAdminPolicies(ctx, zk, admin) msgServer := keeper.NewMsgServerImpl(*k) chain := getValidEthChain(t) - amount := sdkmath.NewUint(100) + amount := sdkmath.NewUintFromString("10000000000000000000") + indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.NoError(t, err) + hash := crypto.Keccak256Hash([]byte(indexString)) + index := hash.Hex() + cctx, found := k.GetCrossChainTx(ctx, index) + require.True(t, found) + feeCalculated := sdk.NewUint(cctx.GetCurrentOutTxParam().OutboundTxGasLimit). + Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutTxParam().OutboundTxGasPrice)) + require.Equal(t, cctx.GetCurrentOutTxParam().Amount.String(), amount.Sub(feeCalculated).String()) + }) + t.Run("not enough funds in tss address for migration", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + admin := sample.AccAddress() + setAdminPolicies(ctx, zk, admin) + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("100") indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ Creator: admin, ChainId: chain.ChainId, Amount: amount, }) - assert.NoError(t, err) + require.ErrorContains(t, err, crosschaintypes.ErrCannotMigrateTssFunds.Error()) hash := crypto.Keccak256Hash([]byte(indexString)) index := hash.Hex() _, found := k.GetCrossChainTx(ctx, index) - assert.True(t, found) + require.False(t, found) }) t.Run("unable to migrate funds if new TSS is not created ", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) @@ -41,19 +90,18 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { setAdminPolicies(ctx, zk, admin) msgServer := keeper.NewMsgServerImpl(*k) chain := getValidEthChain(t) - amount := sdkmath.NewUint(100) + amount := sdkmath.NewUintFromString("10000000000000000000") indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, false, true) _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ Creator: admin, ChainId: chain.ChainId, Amount: amount, }) - assert.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) - assert.ErrorContains(t, err, "no new tss address has been generated") + require.ErrorContains(t, err, "no new tss address has been generated") hash := crypto.Keccak256Hash([]byte(indexString)) index := hash.Hex() _, found := k.GetCrossChainTx(ctx, index) - assert.False(t, found) + require.False(t, found) }) t.Run("unable to migrate funds when nonce low does not match nonce high", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) @@ -61,7 +109,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { setAdminPolicies(ctx, zk, admin) msgServer := keeper.NewMsgServerImpl(*k) chain := getValidEthChain(t) - amount := sdkmath.NewUint(100) + amount := sdkmath.NewUintFromString("10000000000000000000") indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, @@ -74,12 +122,12 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { ChainId: chain.ChainId, Amount: amount, }) - assert.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) - assert.ErrorContains(t, err, "cannot migrate funds when there are pending nonces") + require.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) + require.ErrorContains(t, err, "cannot migrate funds when there are pending nonces") hash := crypto.Keccak256Hash([]byte(indexString)) index := hash.Hex() _, found := k.GetCrossChainTx(ctx, index) - assert.False(t, found) + require.False(t, found) }) t.Run("unable to migrate funds when a pending cctx is presnt in migration info", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) @@ -87,7 +135,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { setAdminPolicies(ctx, zk, admin) msgServer := keeper.NewMsgServerImpl(*k) chain := getValidEthChain(t) - amount := sdkmath.NewUint(100) + amount := sdkmath.NewUintFromString("10000000000000000000") indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, @@ -107,14 +155,14 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { ChainId: chain.ChainId, Amount: amount, }) - assert.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) - assert.ErrorContains(t, err, "cannot migrate funds while there are pending migrations") + require.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) + require.ErrorContains(t, err, "cannot migrate funds while there are pending migrations") hash := crypto.Keccak256Hash([]byte(indexString)) index := hash.Hex() _, found := k.GetCrossChainTx(ctx, index) - assert.False(t, found) + require.False(t, found) _, found = k.GetCrossChainTx(ctx, existingCctx.Index) - assert.True(t, found) + require.True(t, found) }) t.Run("unable to migrate funds if current TSS is not present in TSSHistory and no new TSS has been generated", func(t *testing.T) { @@ -123,10 +171,10 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { setAdminPolicies(ctx, zk, admin) msgServer := keeper.NewMsgServerImpl(*k) chain := getValidEthChain(t) - amount := sdkmath.NewUint(100) + amount := sdkmath.NewUintFromString("10000000000000000000") indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, false, false) currentTss, found := k.GetObserverKeeper().GetTSS(ctx) - assert.True(t, found) + require.True(t, found) newTss := sample.Tss() newTss.FinalizedZetaHeight = currentTss.FinalizedZetaHeight - 10 newTss.KeyGenZetaHeight = currentTss.KeyGenZetaHeight - 10 @@ -136,12 +184,12 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { ChainId: chain.ChainId, Amount: amount, }) - assert.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) - assert.ErrorContains(t, err, "current tss is the latest") + require.ErrorIs(t, err, crosschaintypes.ErrCannotMigrateTssFunds) + require.ErrorContains(t, err, "current tss is the latest") hash := crypto.Keccak256Hash([]byte(indexString)) index := hash.Hex() _, found = k.GetCrossChainTx(ctx, index) - assert.False(t, found) + require.False(t, found) }) } func setupTssMigrationParams( @@ -192,7 +240,7 @@ func setupTssMigrationParams( ChainId: chain.ChainId, Signers: nil, BlockNums: nil, - Prices: []uint64{1, 1, 1}, + Prices: []uint64{100000, 100000, 100000}, MedianIndex: 1, }) k.GetObserverKeeper().SetChainNonces(ctx, observertypes.ChainNonces{ diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 8dc589e878..12bbd4ad84 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -43,4 +43,6 @@ var ( ErrReceiverIsEmpty = errorsmod.Register(ModuleName, 1142, "receiver is empty") ErrUnsupportedStatus = errorsmod.Register(ModuleName, 1143, "unsupported status") ErrObservedTxAlreadyFinalized = errorsmod.Register(ModuleName, 1144, "observed tx already finalized") + + ErrInsufficientFundsTssMigration = errorsmod.Register(ModuleName, 1145, "insufficient funds for TSS migration") ) diff --git a/x/crosschain/types/keys.go b/x/crosschain/types/keys.go index 8777d8df0c..4adac4d73f 100644 --- a/x/crosschain/types/keys.go +++ b/x/crosschain/types/keys.go @@ -25,6 +25,8 @@ const ( MemStoreKey = "mem_metacore" ProtocolFee = 2000000000000000000 + //TssMigrationGasMultiplierEVM is multiplied to the median gas price to get the gas price for the tss migration . This is done to avoid the tss migration tx getting stuck in the mempool + TssMigrationGasMultiplierEVM = "2.5" ) func GetProtocolFee() sdk.Uint { diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index c961a627e0..204ff75cc7 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -294,7 +294,7 @@ func (signer *EVMSigner) SignCommandTx( return tx, nil } if cmd == common.CmdMigrateTssFunds { - tx := ethtypes.NewTransaction(outboundParams.OutboundTxTssNonce, to, outboundParams.Amount.BigInt(), 21000, gasPrice, nil) + tx := ethtypes.NewTransaction(outboundParams.OutboundTxTssNonce, to, outboundParams.Amount.BigInt(), outboundParams.OutboundTxGasLimit, gasPrice, nil) hashBytes := signer.ethSigner.Hash(tx).Bytes() sig, err := signer.tssSigner.Sign(hashBytes, height, outboundParams.OutboundTxTssNonce, signer.chain, "") if err != nil { @@ -318,7 +318,7 @@ func (signer *EVMSigner) SignCommandTx( } func (signer *EVMSigner) TryProcessOutTx( - send *types.CrossChainTx, + cctx *types.CrossChainTx, outTxMan *OutTxProcessorManager, outTxID string, chainclient ChainClient, @@ -327,10 +327,10 @@ func (signer *EVMSigner) TryProcessOutTx( ) { logger := signer.logger.With(). Str("outTxID", outTxID). - Str("SendHash", send.Index). + Str("SendHash", cctx.Index). Logger() logger.Info().Msgf("start processing outTxID %s", outTxID) - logger.Info().Msgf("EVM Chain TryProcessOutTx: %s, value %d to %s", send.Index, send.GetCurrentOutTxParam().Amount.BigInt(), send.GetCurrentOutTxParam().Receiver) + logger.Info().Msgf("EVM Chain TryProcessOutTx: %s, value %d to %s", cctx.Index, cctx.GetCurrentOutTxParam().Amount.BigInt(), cctx.GetCurrentOutTxParam().Receiver) defer func() { outTxMan.EndTryProcess(outTxID) @@ -339,23 +339,23 @@ func (signer *EVMSigner) TryProcessOutTx( var to ethcommon.Address var toChain *common.Chain - if send.CctxStatus.Status == types.CctxStatus_PendingRevert { - to = ethcommon.HexToAddress(send.InboundTxParams.Sender) - toChain = common.GetChainFromChainID(send.InboundTxParams.SenderChainId) + if cctx.CctxStatus.Status == types.CctxStatus_PendingRevert { + to = ethcommon.HexToAddress(cctx.InboundTxParams.Sender) + toChain = common.GetChainFromChainID(cctx.InboundTxParams.SenderChainId) if toChain == nil { - logger.Error().Msgf("Unknown chain: %d", send.InboundTxParams.SenderChainId) + logger.Error().Msgf("Unknown chain: %d", cctx.InboundTxParams.SenderChainId) return } logger.Info().Msgf("Abort: reverting inbound") - } else if send.CctxStatus.Status == types.CctxStatus_PendingOutbound { - to = ethcommon.HexToAddress(send.GetCurrentOutTxParam().Receiver) - toChain = common.GetChainFromChainID(send.GetCurrentOutTxParam().ReceiverChainId) + } else if cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound { + to = ethcommon.HexToAddress(cctx.GetCurrentOutTxParam().Receiver) + toChain = common.GetChainFromChainID(cctx.GetCurrentOutTxParam().ReceiverChainId) if toChain == nil { - logger.Error().Msgf("Unknown chain: %d", send.GetCurrentOutTxParam().ReceiverChainId) + logger.Error().Msgf("Unknown chain: %d", cctx.GetCurrentOutTxParam().ReceiverChainId) return } } else { - logger.Info().Msgf("Transaction doesn't need to be processed status: %d", send.CctxStatus.Status) + logger.Info().Msgf("Transaction doesn't need to be processed status: %d", cctx.CctxStatus.Status) return } evmClient, ok := chainclient.(*EVMChainClient) @@ -365,8 +365,8 @@ func (signer *EVMSigner) TryProcessOutTx( } // Early return if the cctx is already processed - nonce := send.GetCurrentOutTxParam().OutboundTxTssNonce - included, confirmed, err := evmClient.IsSendOutTxProcessed(send.Index, nonce, send.GetCurrentOutTxParam().CoinType, logger) + nonce := cctx.GetCurrentOutTxParam().OutboundTxTssNonce + included, confirmed, err := evmClient.IsSendOutTxProcessed(cctx.Index, nonce, cctx.GetCurrentOutTxParam().CoinType, logger) if err != nil { logger.Error().Err(err).Msg("IsSendOutTxProcessed failed") } @@ -376,27 +376,27 @@ func (signer *EVMSigner) TryProcessOutTx( } var message []byte - if send.GetCurrentOutTxParam().CoinType != common.CoinType_Cmd { - message, err = base64.StdEncoding.DecodeString(send.RelayedMessage) + if cctx.GetCurrentOutTxParam().CoinType != common.CoinType_Cmd { + message, err = base64.StdEncoding.DecodeString(cctx.RelayedMessage) if err != nil { - logger.Err(err).Msgf("decode CCTX.Message %s error", send.RelayedMessage) + logger.Err(err).Msgf("decode CCTX.Message %s error", cctx.RelayedMessage) } } - gasLimit := send.GetCurrentOutTxParam().OutboundTxGasLimit + gasLimit := cctx.GetCurrentOutTxParam().OutboundTxGasLimit if gasLimit < 100_000 { gasLimit = 100_000 - logger.Warn().Msgf("gasLimit %d is too low; set to %d", send.GetCurrentOutTxParam().OutboundTxGasLimit, gasLimit) + logger.Warn().Msgf("gasLimit %d is too low; set to %d", cctx.GetCurrentOutTxParam().OutboundTxGasLimit, gasLimit) } if gasLimit > 1_000_000 { gasLimit = 1_000_000 - logger.Warn().Msgf("gasLimit %d is too high; set to %d", send.GetCurrentOutTxParam().OutboundTxGasLimit, gasLimit) + logger.Warn().Msgf("gasLimit %d is too high; set to %d", cctx.GetCurrentOutTxParam().OutboundTxGasLimit, gasLimit) } - logger.Info().Msgf("chain %s minting %d to %s, nonce %d, finalized zeta bn %d", toChain, send.InboundTxParams.Amount, to.Hex(), nonce, send.InboundTxParams.InboundTxFinalizedZetaHeight) - sendHash, err := hex.DecodeString(send.Index[2:]) // remove the leading 0x + logger.Info().Msgf("chain %s minting %d to %s, nonce %d, finalized zeta bn %d", toChain, cctx.InboundTxParams.Amount, to.Hex(), nonce, cctx.InboundTxParams.InboundTxFinalizedZetaHeight) + sendHash, err := hex.DecodeString(cctx.Index[2:]) // remove the leading 0x if err != nil || len(sendHash) != 32 { - logger.Error().Err(err).Msgf("decode CCTX %s error", send.Index) + logger.Error().Err(err).Msgf("decode CCTX %s error", cctx.Index) return } var sendhash [32]byte @@ -408,7 +408,7 @@ func (signer *EVMSigner) TryProcessOutTx( // The code below is a fix for https://github.com/zeta-chain/node/issues/1085 // doesn't close directly the issue because we should determine if we want to keep using SuggestGasPrice if no OutboundTxGasPrice // we should possibly remove it completely and return an error if no OutboundTxGasPrice is provided because it means no fee is processed on ZetaChain - specified, ok := new(big.Int).SetString(send.GetCurrentOutTxParam().OutboundTxGasPrice, 10) + specified, ok := new(big.Int).SetString(cctx.GetCurrentOutTxParam().OutboundTxGasPrice, 10) if !ok { if common.IsEthereumChain(toChain.ChainId) { suggested, err := signer.client.SuggestGasPrice(context.Background()) @@ -418,7 +418,7 @@ func (signer *EVMSigner) TryProcessOutTx( } gasprice = roundUpToNearestGwei(suggested) } else { - logger.Error().Err(err).Msgf("cannot convert gas price %s ", send.GetCurrentOutTxParam().OutboundTxGasPrice) + logger.Error().Err(err).Msgf("cannot convert gas price %s ", cctx.GetCurrentOutTxParam().OutboundTxGasPrice) return } } else { @@ -444,138 +444,138 @@ func (signer *EVMSigner) TryProcessOutTx( var tx *ethtypes.Transaction - if send.GetCurrentOutTxParam().CoinType == common.CoinType_Cmd { // admin command - to := ethcommon.HexToAddress(send.GetCurrentOutTxParam().Receiver) + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_Cmd { // admin command + to := ethcommon.HexToAddress(cctx.GetCurrentOutTxParam().Receiver) if to == (ethcommon.Address{}) { - logger.Error().Msgf("invalid receiver %s", send.GetCurrentOutTxParam().Receiver) + logger.Error().Msgf("invalid receiver %s", cctx.GetCurrentOutTxParam().Receiver) return } - msg := strings.Split(send.RelayedMessage, ":") + msg := strings.Split(cctx.RelayedMessage, ":") if len(msg) != 2 { logger.Error().Msgf("invalid message %s", msg) return } - tx, err = signer.SignCommandTx(msg[0], msg[1], to, send.GetCurrentOutTxParam(), gasLimit, gasprice, height) - } else if send.InboundTxParams.SenderChainId == zetaBridge.ZetaChain().ChainId && send.CctxStatus.Status == types.CctxStatus_PendingOutbound && flags.IsOutboundEnabled { - if send.GetCurrentOutTxParam().CoinType == common.CoinType_Gas { - logger.Info().Msgf("SignWithdrawTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + tx, err = signer.SignCommandTx(msg[0], msg[1], to, cctx.GetCurrentOutTxParam(), gasLimit, gasprice, height) + } else if cctx.InboundTxParams.SenderChainId == zetaBridge.ZetaChain().ChainId && cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound && flags.IsOutboundEnabled { + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_Gas { + logger.Info().Msgf("SignWithdrawTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignWithdrawTx( to, - send.GetCurrentOutTxParam().Amount.BigInt(), - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } - if send.GetCurrentOutTxParam().CoinType == common.CoinType_ERC20 { - asset := ethcommon.HexToAddress(send.InboundTxParams.Asset) - logger.Info().Msgf("SignERC20WithdrawTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_ERC20 { + asset := ethcommon.HexToAddress(cctx.InboundTxParams.Asset) + logger.Info().Msgf("SignERC20WithdrawTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignERC20WithdrawTx( to, asset, - send.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().Amount.BigInt(), gasLimit, - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } - if send.GetCurrentOutTxParam().CoinType == common.CoinType_Zeta { - logger.Info().Msgf("SignOutboundTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_Zeta { + logger.Info().Msgf("SignOutboundTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignOutboundTx( - ethcommon.HexToAddress(send.InboundTxParams.Sender), - big.NewInt(send.InboundTxParams.SenderChainId), + ethcommon.HexToAddress(cctx.InboundTxParams.Sender), + big.NewInt(cctx.InboundTxParams.SenderChainId), to, - send.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().Amount.BigInt(), gasLimit, message, sendhash, - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } - } else if send.CctxStatus.Status == types.CctxStatus_PendingRevert && send.OutboundTxParams[0].ReceiverChainId == zetaBridge.ZetaChain().ChainId { - if send.GetCurrentOutTxParam().CoinType == common.CoinType_Gas { - logger.Info().Msgf("SignWithdrawTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + } else if cctx.CctxStatus.Status == types.CctxStatus_PendingRevert && cctx.OutboundTxParams[0].ReceiverChainId == zetaBridge.ZetaChain().ChainId { + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_Gas { + logger.Info().Msgf("SignWithdrawTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignWithdrawTx( to, - send.GetCurrentOutTxParam().Amount.BigInt(), - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } - if send.GetCurrentOutTxParam().CoinType == common.CoinType_ERC20 { - asset := ethcommon.HexToAddress(send.InboundTxParams.Asset) - logger.Info().Msgf("SignERC20WithdrawTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + if cctx.GetCurrentOutTxParam().CoinType == common.CoinType_ERC20 { + asset := ethcommon.HexToAddress(cctx.InboundTxParams.Asset) + logger.Info().Msgf("SignERC20WithdrawTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignERC20WithdrawTx( to, asset, - send.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().Amount.BigInt(), gasLimit, - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } - } else if send.CctxStatus.Status == types.CctxStatus_PendingRevert { - logger.Info().Msgf("SignRevertTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + } else if cctx.CctxStatus.Status == types.CctxStatus_PendingRevert { + logger.Info().Msgf("SignRevertTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignRevertTx( - ethcommon.HexToAddress(send.InboundTxParams.Sender), - big.NewInt(send.OutboundTxParams[0].ReceiverChainId), + ethcommon.HexToAddress(cctx.InboundTxParams.Sender), + big.NewInt(cctx.OutboundTxParams[0].ReceiverChainId), to.Bytes(), - big.NewInt(send.GetCurrentOutTxParam().ReceiverChainId), - send.GetCurrentOutTxParam().Amount.BigInt(), + big.NewInt(cctx.GetCurrentOutTxParam().ReceiverChainId), + cctx.GetCurrentOutTxParam().Amount.BigInt(), gasLimit, message, sendhash, - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) - } else if send.CctxStatus.Status == types.CctxStatus_PendingOutbound { - logger.Info().Msgf("SignOutboundTx: %d => %s, nonce %d, gasprice %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) + } else if cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound { + logger.Info().Msgf("SignOutboundTx: %d => %s, nonce %d, gasprice %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice) tx, err = signer.SignOutboundTx( - ethcommon.HexToAddress(send.InboundTxParams.Sender), - big.NewInt(send.InboundTxParams.SenderChainId), + ethcommon.HexToAddress(cctx.InboundTxParams.Sender), + big.NewInt(cctx.InboundTxParams.SenderChainId), to, - send.GetCurrentOutTxParam().Amount.BigInt(), + cctx.GetCurrentOutTxParam().Amount.BigInt(), gasLimit, message, sendhash, - send.GetCurrentOutTxParam().OutboundTxTssNonce, + cctx.GetCurrentOutTxParam().OutboundTxTssNonce, gasprice, height, ) } if err != nil { - logger.Warn().Err(err).Msgf("signer SignOutbound error: nonce %d chain %d", send.GetCurrentOutTxParam().OutboundTxTssNonce, send.GetCurrentOutTxParam().ReceiverChainId) + logger.Warn().Err(err).Msgf("signer SignOutbound error: nonce %d chain %d", cctx.GetCurrentOutTxParam().OutboundTxTssNonce, cctx.GetCurrentOutTxParam().ReceiverChainId) return } - logger.Info().Msgf("Key-sign success: %d => %s, nonce %d", send.InboundTxParams.SenderChainId, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce) + logger.Info().Msgf("Key-sign success: %d => %s, nonce %d", cctx.InboundTxParams.SenderChainId, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce) _, err = zetaBridge.GetObserverList() if err != nil { - logger.Warn().Err(err).Msgf("unable to get observer list: chain %d observation %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, observertypes.ObservationType_OutBoundTx.String()) + logger.Warn().Err(err).Msgf("unable to get observer list: chain %d observation %s", cctx.GetCurrentOutTxParam().OutboundTxTssNonce, observertypes.ObservationType_OutBoundTx.String()) } if tx != nil { outTxHash := tx.Hash().Hex() - logger.Info().Msgf("on chain %s nonce %d, outTxHash %s signer %s", signer.chain, send.GetCurrentOutTxParam().OutboundTxTssNonce, outTxHash, myID) + logger.Info().Msgf("on chain %s nonce %d, outTxHash %s signer %s", signer.chain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, outTxHash, myID) //if len(signers) == 0 || myid == signers[send.OutboundTxParams.Broadcaster] || myid == signers[int(send.OutboundTxParams.Broadcaster+1)%len(signers)] { backOff := 1000 * time.Millisecond // retry loop: 1s, 2s, 4s, 8s, 16s in case of RPC error for i := 0; i < 5; i++ { - logger.Info().Msgf("broadcasting tx %s to chain %s: nonce %d, retry %d", outTxHash, toChain, send.GetCurrentOutTxParam().OutboundTxTssNonce, i) + logger.Info().Msgf("broadcasting tx %s to chain %s: nonce %d, retry %d", outTxHash, toChain, cctx.GetCurrentOutTxParam().OutboundTxTssNonce, i) // #nosec G404 randomness is not a security issue here time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // FIXME: use backoff err := signer.Broadcast(tx) if err != nil { log.Warn().Err(err).Msgf("OutTx Broadcast error") - retry, report := HandleBroadcastError(err, strconv.FormatUint(send.GetCurrentOutTxParam().OutboundTxTssNonce, 10), toChain.String(), outTxHash) + retry, report := HandleBroadcastError(err, strconv.FormatUint(cctx.GetCurrentOutTxParam().OutboundTxTssNonce, 10), toChain.String(), outTxHash) if report { signer.reportToOutTxTracker(zetaBridge, toChain.ChainId, tx.Nonce(), outTxHash, logger) } @@ -585,7 +585,7 @@ func (signer *EVMSigner) TryProcessOutTx( backOff *= 2 continue } - logger.Info().Msgf("Broadcast success: nonce %d to chain %s outTxHash %s", send.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) + logger.Info().Msgf("Broadcast success: nonce %d to chain %s outTxHash %s", cctx.GetCurrentOutTxParam().OutboundTxTssNonce, toChain, outTxHash) signer.reportToOutTxTracker(zetaBridge, toChain.ChainId, tx.Nonce(), outTxHash, logger) break // successful broadcast; no need to retry } From 64ed9b116dc555f745a44b0b3b5a750c305ad97f Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:00:25 -0600 Subject: [PATCH 53/67] fix: outtx tracker report timeout (#1616) * fix outtx tracker report timeout * make generate * remove err when print Info logs * update changelog --------- Co-authored-by: Lucas Bertrand --- changelog.md | 3 ++ zetaclient/evm_signer.go | 83 +++++++++++++++++++++++++-------- zetaclient/interfaces.go | 1 + zetaclient/tx.go | 10 ++++ zetaclient/zetacore_observer.go | 3 +- 5 files changed, 80 insertions(+), 20 deletions(-) diff --git a/changelog.md b/changelog.md index bdd9866e84..16d486fb0c 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,9 @@ ## Unreleased +### Fixes +* [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes + ## Version: v12.1.0 ### Tests diff --git a/zetaclient/evm_signer.go b/zetaclient/evm_signer.go index 204ff75cc7..05a476a64b 100644 --- a/zetaclient/evm_signer.go +++ b/zetaclient/evm_signer.go @@ -21,12 +21,15 @@ import ( "github.com/rs/zerolog/log" "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/erc20custody.sol" "github.com/zeta-chain/zetacore/common" + crosschainkeeper "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) const ( + OutTxInclusionTimeout = 10 * time.Minute OutTxTrackerReportTimeout = 10 * time.Minute + ZetaBlockTime = 6500 * time.Millisecond ) type EVMSigner struct { @@ -592,7 +595,7 @@ func (signer *EVMSigner) TryProcessOutTx( } } -// reportToOutTxTracker reports outTxHash to tracker only when tx receipt is available +// reportToOutTxTracker reports outTxHash to tracker only when tx is included in a block func (signer *EVMSigner) reportToOutTxTracker(zetaBridge ZetaCoreBridger, chainID int64, nonce uint64, outTxHash string, logger zerolog.Logger) { // skip if already being reported signer.mu.Lock() @@ -611,36 +614,78 @@ func (signer *EVMSigner) reportToOutTxTracker(zetaBridge ZetaCoreBridger, chainI signer.mu.Unlock() }() - // try fetching tx receipt for 10 minutes + // try monitoring tx inclusion status for 10 minutes + var err error + report := false + isPending := false + blockNumber := uint64(0) tStart := time.Now() for { - if time.Since(tStart) > OutTxTrackerReportTimeout { // give up after 10 minutes - logger.Info().Msgf("reportToOutTxTracker: outTxHash report timeout for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) - return + // give up after 10 minutes of monitoring + time.Sleep(10 * time.Second) + if time.Since(tStart) > OutTxInclusionTimeout { + // if tx is still pending after timeout, report to outTxTracker anyway as we cannot monitor forever + if isPending { + report = true // probably will be included later + } + logger.Info().Msgf("reportToOutTxTracker: timeout waiting tx inclusion for chain %d nonce %d outTxHash %s report %v", chainID, nonce, outTxHash, report) + break } - receipt, err := signer.client.TransactionReceipt(context.TODO(), ethcommon.HexToHash(outTxHash)) + // try getting the tx + _, isPending, err = signer.client.TransactionByHash(context.TODO(), ethcommon.HexToHash(outTxHash)) if err != nil { - logger.Info().Err(err).Msgf("reportToOutTxTracker: receipt not available for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) - time.Sleep(10 * time.Second) + logger.Info().Err(err).Msgf("reportToOutTxTracker: error getting tx for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) continue } - if receipt != nil { - _, isPending, err := signer.client.TransactionByHash(context.TODO(), ethcommon.HexToHash(outTxHash)) - if err != nil || isPending { - logger.Info().Err(err).Msgf("reportToOutTxTracker: error getting tx or tx is pending for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) - time.Sleep(10 * time.Second) - continue + // if tx is include in a block, try getting receipt + if !isPending { + report = true // included + receipt, err := signer.client.TransactionReceipt(context.TODO(), ethcommon.HexToHash(outTxHash)) + if err != nil { + logger.Info().Err(err).Msgf("reportToOutTxTracker: error getting receipt for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + } + if receipt != nil { + blockNumber = receipt.BlockNumber.Uint64() } break } + // keep monitoring pending tx + logger.Info().Msgf("reportToOutTxTracker: tx has not been included yet for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) } - // report to outTxTracker - zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(chainID, nonce, outTxHash, nil, "", -1) - if err != nil { - logger.Err(err).Msgf("reportToOutTxTracker: unable to add to tracker on ZetaCore for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + // try adding to outTx tracker for 10 minutes + if report { + tStart := time.Now() + for { + // give up after 10 minutes of retrying + if time.Since(tStart) > OutTxTrackerReportTimeout { + logger.Info().Msgf("reportToOutTxTracker: timeout adding outtx tracker for chain %d nonce %d outTxHash %s, please add manually", chainID, nonce, outTxHash) + break + } + // stop if the cctx is already finalized + cctx, err := zetaBridge.GetCctxByNonce(chainID, nonce) + if err != nil { + logger.Err(err).Msgf("reportToOutTxTracker: error getting cctx for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + } else if !crosschainkeeper.IsPending(*cctx) { + logger.Info().Msgf("reportToOutTxTracker: cctx already finalized for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + break + } + // report to outTx tracker + zetaHash, err := zetaBridge.AddTxHashToOutTxTracker(chainID, nonce, outTxHash, nil, "", -1) + if err != nil { + logger.Err(err).Msgf("reportToOutTxTracker: error adding to outtx tracker for chain %d nonce %d outTxHash %s", chainID, nonce, outTxHash) + } else if zetaHash != "" { + logger.Info().Msgf("reportToOutTxTracker: added outTxHash to core successful %s, chain %d nonce %d outTxHash %s block %d", + zetaHash, chainID, nonce, outTxHash, blockNumber) + } else { + // stop if the tracker contains the outTxHash + logger.Info().Msgf("reportToOutTxTracker: outtx tracker contains outTxHash %s for chain %d nonce %d", outTxHash, chainID, nonce) + break + } + // retry otherwise + time.Sleep(ZetaBlockTime * 3) + } } - logger.Info().Msgf("reportToOutTxTracker: reported outTxHash to core successful %s, chain %d nonce %d outTxHash %s", zetaHash, chainID, nonce, outTxHash) }() } diff --git a/zetaclient/interfaces.go b/zetaclient/interfaces.go index 6ca41f59fd..6ccf4faef8 100644 --- a/zetaclient/interfaces.go +++ b/zetaclient/interfaces.go @@ -82,6 +82,7 @@ type ZetaCoreBridger interface { ListPendingCctx(chainID int64) ([]*crosschaintypes.CrossChainTx, uint64, error) GetPendingNoncesByChain(chainID int64) (observertypes.PendingNonces, error) GetCctxByNonce(chainID int64, nonce uint64) (*crosschaintypes.CrossChainTx, error) + GetOutTxTracker(chain common.Chain, nonce uint64) (*crosschaintypes.OutTxTracker, error) GetAllOutTxTrackerByChain(chainID int64, order Order) ([]crosschaintypes.OutTxTracker, error) GetCrosschainFlags() (observertypes.CrosschainFlags, error) GetObserverList() ([]string, error) diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 15847c3f80..491b76d133 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -2,6 +2,7 @@ package zetaclient import ( "fmt" + "strings" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -78,6 +79,15 @@ func (b *ZetaCoreBridge) AddTxHashToOutTxTracker( blockHash string, txIndex int64, ) (string, error) { + // don't report if the tracker already contains the txHash + tracker, err := b.GetOutTxTracker(common.Chain{ChainId: chainID}, nonce) + if err == nil { + for _, hash := range tracker.HashList { + if strings.EqualFold(hash.TxHash, txHash) { + return "", nil + } + } + } signerAddress := b.keys.GetOperatorAddress().String() msg := types.NewMsgAddToOutTxTracker(signerAddress, chainID, nonce, txHash, proof, blockHash, txIndex) diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 8d8d426a39..333c6ce262 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -249,7 +249,8 @@ func (co *CoreObserver) scheduleCctxEVM( continue } if params.OutboundTxTssNonce > cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce+MaxLookaheadNonce { - co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxEVM: nonce too high: signing %d, earliest pending %d", params.OutboundTxTssNonce, cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce) + co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxEVM: nonce too high: signing %d, earliest pending %d, chain %d", + params.OutboundTxTssNonce, cctxList[0].GetCurrentOutTxParam().OutboundTxTssNonce, chainID) break } From e78d15298402cc3c97eb37ccbe7a0c1ddd73908b Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 29 Jan 2024 02:25:32 -0500 Subject: [PATCH 54/67] fix: modify emissions to follow fixed rewards per block (#1658) --- changelog.md | 2 +- common/coin.go | 14 + common/coin_test.go | 65 +++ x/emissions/abci.go | 35 +- x/emissions/abci_test.go | 477 +++++++++--------- .../client/tests/observer_rewards_test.go | 10 +- .../keeper/block_rewards_components.go | 26 +- .../keeper/block_rewards_components_test.go | 50 ++ x/emissions/types/keys.go | 8 +- 9 files changed, 417 insertions(+), 270 deletions(-) create mode 100644 common/coin_test.go create mode 100644 x/emissions/keeper/block_rewards_components_test.go diff --git a/changelog.md b/changelog.md index 16d486fb0c..edf96c140d 100644 --- a/changelog.md +++ b/changelog.md @@ -11,7 +11,7 @@ * [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests ### Features - +* [1658](https://github.com/zeta-chain/node/pull/1658) - modify emission distribution to use fixed block rewards ### Fixes * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic diff --git a/common/coin.go b/common/coin.go index 4c875d97bb..b05a6d3cec 100644 --- a/common/coin.go +++ b/common/coin.go @@ -3,6 +3,8 @@ package common import ( "fmt" "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func GetCoinType(coin string) (CoinType, error) { @@ -16,3 +18,15 @@ func GetCoinType(coin string) (CoinType, error) { // #nosec G701 always in range return CoinType(coinInt), nil } + +func GetAzetaDecFromAmountInZeta(zetaAmount string) (sdk.Dec, error) { + zetaDec, err := sdk.NewDecFromStr(zetaAmount) + if err != nil { + return sdk.Dec{}, err + } + zetaToAzetaConvertionFactor, err := sdk.NewDecFromStr("1000000000000000000") + if err != nil { + return sdk.Dec{}, err + } + return zetaDec.Mul(zetaToAzetaConvertionFactor), nil +} diff --git a/common/coin_test.go b/common/coin_test.go new file mode 100644 index 0000000000..4dd03fa2db --- /dev/null +++ b/common/coin_test.go @@ -0,0 +1,65 @@ +package common_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/zeta-chain/zetacore/common" +) + +func Test_GetAzetaDecFromAmountInZeta(t *testing.T) { + tt := []struct { + name string + zetaAmount string + err assert.ErrorAssertionFunc + azetaAmount sdk.Dec + }{ + { + name: "valid zeta amount", + zetaAmount: "210000000", + err: assert.NoError, + azetaAmount: sdk.MustNewDecFromStr("210000000000000000000000000"), + }, + { + name: "very high zeta amount", + zetaAmount: "21000000000000000000", + err: assert.NoError, + azetaAmount: sdk.MustNewDecFromStr("21000000000000000000000000000000000000"), + }, + { + name: "very low zeta amount", + zetaAmount: "1", + err: assert.NoError, + azetaAmount: sdk.MustNewDecFromStr("1000000000000000000"), + }, + { + name: "zero zeta amount", + zetaAmount: "0", + err: assert.NoError, + azetaAmount: sdk.MustNewDecFromStr("0"), + }, + { + name: "decimal zeta amount", + zetaAmount: "0.1", + err: assert.NoError, + azetaAmount: sdk.MustNewDecFromStr("100000000000000000"), + }, + { + name: "invalid zeta amount", + zetaAmount: "%%%%%$#", + err: assert.Error, + azetaAmount: sdk.MustNewDecFromStr("0"), + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + azeta, err := common.GetAzetaDecFromAmountInZeta(tc.zetaAmount) + tc.err(t, err) + if err == nil { + assert.Equal(t, tc.azetaAmount, azeta) + } + }) + } + +} diff --git a/x/emissions/abci.go b/x/emissions/abci.go index 50f2f3daae..bc15398209 100644 --- a/x/emissions/abci.go +++ b/x/emissions/abci.go @@ -1,6 +1,7 @@ package emissions import ( + "fmt" "sort" sdkmath "cosmossdk.io/math" @@ -11,29 +12,38 @@ import ( ) func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) { + emissionPoolBalance := keeper.GetReservesFactor(ctx) + blockRewards := types.BlockReward - reservesFactor, bondFactor, durationFactor := keeper.GetBlockRewardComponents(ctx) - blockRewards := reservesFactor.Mul(bondFactor).Mul(durationFactor) - if blockRewards.IsZero() { + if blockRewards.GT(emissionPoolBalance) { + ctx.Logger().Info(fmt.Sprintf("Block rewards %s are greater than emission pool balance %s", blockRewards.String(), emissionPoolBalance.String())) return } validatorRewards := sdk.MustNewDecFromStr(keeper.GetParams(ctx).ValidatorEmissionPercentage).Mul(blockRewards).TruncateInt() observerRewards := sdk.MustNewDecFromStr(keeper.GetParams(ctx).ObserverEmissionPercentage).Mul(blockRewards).TruncateInt() tssSignerRewards := sdk.MustNewDecFromStr(keeper.GetParams(ctx).TssSignerEmissionPercentage).Mul(blockRewards).TruncateInt() - err := DistributeValidatorRewards(ctx, validatorRewards, keeper.GetBankKeeper(), keeper.GetFeeCollector()) + // Use a tmpCtx, which is a cache-wrapped context to avoid writing to the store + // We commit only if all three distributions are successful, if not the funds stay in the emission pool + tmpCtx, commit := ctx.CacheContext() + err := DistributeValidatorRewards(tmpCtx, validatorRewards, keeper.GetBankKeeper(), keeper.GetFeeCollector()) if err != nil { - panic(err) + ctx.Logger().Error(fmt.Sprintf("Error while distributing validator rewards %s", err)) + return } - err = DistributeObserverRewards(ctx, observerRewards, keeper) + err = DistributeObserverRewards(tmpCtx, observerRewards, keeper) if err != nil { - panic(err) + ctx.Logger().Error(fmt.Sprintf("Error while distributing observer rewards %s", err)) + return } - err = DistributeTssRewards(ctx, tssSignerRewards, keeper.GetBankKeeper()) + err = DistributeTssRewards(tmpCtx, tssSignerRewards, keeper.GetBankKeeper()) if err != nil { - panic(err) + ctx.Logger().Error(fmt.Sprintf("Error while distributing tss signer rewards %s", err)) + return } - types.EmitValidatorEmissions(ctx, bondFactor.String(), reservesFactor.String(), - durationFactor.String(), + commit() + + types.EmitValidatorEmissions(ctx, "", "", + "", validatorRewards.String(), observerRewards.String(), tssSignerRewards.String()) @@ -44,6 +54,7 @@ func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) { // This function uses the distribution module of cosmos-sdk , by directly sending funds to the feecollector. func DistributeValidatorRewards(ctx sdk.Context, amount sdkmath.Int, bankKeeper types.BankKeeper, feeCollector string) error { coin := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, amount)) + ctx.Logger().Info(fmt.Sprintf(fmt.Sprintf("Distributing Validator Rewards Total:%s To FeeCollector : %s", amount.String(), feeCollector))) return bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, feeCollector, coin) } @@ -76,7 +87,7 @@ func DistributeObserverRewards(ctx sdk.Context, amount sdkmath.Int, keeper keepe if totalRewardsUnits > 0 && amount.IsPositive() { rewardPerUnit = amount.Quo(sdk.NewInt(totalRewardsUnits)) } - + ctx.Logger().Debug(fmt.Sprintf("Total Rewards Units : %d , rewards per Unit %s ,number of ballots :%d", totalRewardsUnits, rewardPerUnit.String(), len(ballotIdentifiers))) sortedKeys := make([]string, 0, len(rewardsDistributer)) for k := range rewardsDistributer { sortedKeys = append(sortedKeys, k) diff --git a/x/emissions/abci_test.go b/x/emissions/abci_test.go index fd7a49f0b2..50651ca3e2 100644 --- a/x/emissions/abci_test.go +++ b/x/emissions/abci_test.go @@ -1,252 +1,229 @@ package emissions_test -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sort" - "strconv" - "testing" - - 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/stretchr/testify/assert" - "github.com/tendermint/tendermint/crypto/ed25519" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - zetaapp "github.com/zeta-chain/zetacore/app" - "github.com/zeta-chain/zetacore/cmd/zetacored/config" - "github.com/zeta-chain/zetacore/testutil/simapp" - emissionsModule "github.com/zeta-chain/zetacore/x/emissions" - emissionsModuleTypes "github.com/zeta-chain/zetacore/x/emissions/types" -) - -func getaZetaFromString(amount string) sdk.Coins { - emissionPoolInt, _ := sdk.NewIntFromString(amount) - return sdk.NewCoins(sdk.NewCoin(config.BaseDenom, emissionPoolInt)) -} - -func SetupApp(t *testing.T, params emissionsModuleTypes.Params, emissionPoolCoins sdk.Coins) (*zetaapp.App, sdk.Context, *tmtypes.ValidatorSet, *authtypes.BaseAccount) { - pk1 := ed25519.GenPrivKey().PubKey() - acc1 := authtypes.NewBaseAccountWithAddress(sdk.AccAddress(pk1.Address())) - // genDelActs and genDelBalances need to have the same addresses - // bondAmount is specified separately , the Balances here are additional tokens for delegators to have in their accounts - genDelActs := make(authtypes.GenesisAccounts, 1) - genDelBalances := make([]banktypes.Balance, 1) - genDelActs[0] = acc1 - genDelBalances[0] = banktypes.Balance{ - Address: acc1.GetAddress().String(), - Coins: emissionPoolCoins, - } - delBondAmount := getaZetaFromString("1000000000000000000000000") - - //genBalances := make([]banktypes.Balance, 1) - //genBalances[0] = banktypes.Balance{ - // Address: emissionsModuleTypes.EmissionsModuleAddress.String(), - // Coins: emissionPoolCoins, - //} - - vset := tmtypes.NewValidatorSet([]*tmtypes.Validator{}) - for i := 0; i < 1; i++ { - privKey := ed25519.GenPrivKey() - pubKey := privKey.PubKey() - val := tmtypes.NewValidator(pubKey, 1) - err := vset.UpdateWithChangeSet([]*tmtypes.Validator{val}) - if err != nil { - panic("Failed to add validator") - } - } - - app := simapp.SetupWithGenesisValSet(t, vset, genDelActs, delBondAmount.AmountOf(config.BaseDenom), params, genDelBalances, nil) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - ctx = ctx.WithBlockHeight(app.LastBlockHeight()) - return app, ctx, vset, acc1 -} - -type EmissionTestData struct { - BlockHeight int64 `json:"blockHeight,omitempty"` - BondFactor sdk.Dec `json:"bondFactor"` - ReservesFactor sdk.Dec `json:"reservesFactor"` - DurationFactor string `json:"durationFactor"` -} - -func TestAppModule_GetBlockRewardComponents(t *testing.T) { - - tests := []struct { - name string - startingEmissionPool string - params emissionsModuleTypes.Params - testMaxHeight int64 - inputFilename string - checkValues []EmissionTestData - generateOnly bool - }{ - { - name: "default values", - params: emissionsModuleTypes.DefaultParams(), - startingEmissionPool: "1000000000000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - { - name: "higher starting pool", - params: emissionsModuleTypes.DefaultParams(), - startingEmissionPool: "100000000000000000000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - { - name: "lower starting pool", - params: emissionsModuleTypes.DefaultParams(), - startingEmissionPool: "100000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - { - name: "different distribution percentages", - params: emissionsModuleTypes.Params{ - MaxBondFactor: "1.25", - MinBondFactor: "0.75", - AvgBlockTime: "6.00", - TargetBondRatio: "00.67", - ValidatorEmissionPercentage: "00.10", - ObserverEmissionPercentage: "00.85", - TssSignerEmissionPercentage: "00.05", - DurationFactorConstant: "0.001877876953694702", - }, - startingEmissionPool: "1000000000000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - { - name: "higher block time", - params: emissionsModuleTypes.Params{ - MaxBondFactor: "1.25", - MinBondFactor: "0.75", - AvgBlockTime: "20.00", - TargetBondRatio: "00.67", - ValidatorEmissionPercentage: "00.10", - ObserverEmissionPercentage: "00.85", - TssSignerEmissionPercentage: "00.05", - DurationFactorConstant: "0.1", - }, - startingEmissionPool: "1000000000000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - { - name: "different duration constant", - params: emissionsModuleTypes.Params{ - MaxBondFactor: "1.25", - MinBondFactor: "0.75", - AvgBlockTime: "6.00", - TargetBondRatio: "00.67", - ValidatorEmissionPercentage: "00.10", - ObserverEmissionPercentage: "00.85", - TssSignerEmissionPercentage: "00.05", - DurationFactorConstant: "0.1", - }, - startingEmissionPool: "1000000000000000000000000", - testMaxHeight: 300, - inputFilename: "simulations.json", - generateOnly: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - app, ctx, _, minter := SetupApp(t, tt.params, getaZetaFromString(tt.startingEmissionPool)) - err := app.BankKeeper.SendCoinsFromAccountToModule(ctx, minter.GetAddress(), emissionsModuleTypes.ModuleName, getaZetaFromString(tt.startingEmissionPool)) - assert.NoError(t, err) - GenerateTestDataMaths(app, ctx, tt.testMaxHeight, tt.inputFilename) - defer func(t *testing.T, fp string) { - err := os.RemoveAll(fp) - assert.NoError(t, err) - }(t, tt.inputFilename) - - if tt.generateOnly { - return - } - inputTestData, err := GetInputData(tt.inputFilename) - assert.NoError(t, err) - sort.SliceStable(inputTestData, func(i, j int) bool { return inputTestData[i].BlockHeight < inputTestData[j].BlockHeight }) - startHeight := ctx.BlockHeight() - assert.Equal(t, startHeight, inputTestData[0].BlockHeight, "starting block height should be equal to the first block height in the input data") - for i := startHeight; i < tt.testMaxHeight; i++ { - //The First distribution will occur only when begin-block is triggered - reservesFactor, bondFactor, durationFactor := app.EmissionsKeeper.GetBlockRewardComponents(ctx) - assert.Equal(t, inputTestData[i-1].ReservesFactor, reservesFactor, "reserves factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) - assert.Equal(t, inputTestData[i-1].BondFactor, bondFactor, "bond factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) - assert.Equal(t, inputTestData[i-1].DurationFactor, durationFactor.String(), "duration factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) - emissionsModule.BeginBlocker(ctx, app.EmissionsKeeper) - ctx = ctx.WithBlockHeight(i + 1) - } - }) - } -} - -func GetInputData(fp string) ([]EmissionTestData, error) { - data := []EmissionTestData{} - file, err := filepath.Abs(fp) - if err != nil { - - return nil, err - } - file = filepath.Clean(file) - input, err := ioutil.ReadFile(file) // #nosec G304 - if err != nil { - return nil, err - } - err = json.Unmarshal(input, &data) - if err != nil { - return nil, err - } - formatedData := make([]EmissionTestData, len(data)) - for i, dd := range data { - fl, err := strconv.ParseFloat(dd.DurationFactor, 64) - if err != nil { - return nil, err - } - dd.DurationFactor = fmt.Sprintf("%0.18f", fl) - formatedData[i] = dd - } - return formatedData, nil -} - -func GenerateTestDataMaths(app *zetaapp.App, ctx sdk.Context, testMaxHeight int64, fileName string) { - var generatedTestData []EmissionTestData - reserverCoins := app.BankKeeper.GetBalance(ctx, emissionsModuleTypes.EmissionsModuleAddress, config.BaseDenom) - startHeight := ctx.BlockHeight() - for i := startHeight; i < testMaxHeight; i++ { - reservesFactor := sdk.NewDecFromInt(reserverCoins.Amount) - bondFactor := app.EmissionsKeeper.GetBondFactor(ctx, app.StakingKeeper) - durationFactor := app.EmissionsKeeper.GetDurationFactor(ctx) - blockRewards := reservesFactor.Mul(bondFactor).Mul(durationFactor) - generatedTestData = append(generatedTestData, EmissionTestData{ - BlockHeight: i, - BondFactor: bondFactor, - DurationFactor: durationFactor.String(), - ReservesFactor: reservesFactor, - }) - validatorRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).ValidatorEmissionPercentage).Mul(blockRewards).TruncateInt() - observerRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).ObserverEmissionPercentage).Mul(blockRewards).TruncateInt() - tssSignerRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).TssSignerEmissionPercentage).Mul(blockRewards).TruncateInt() - truncatedRewards := validatorRewards.Add(observerRewards).Add(tssSignerRewards) - reserverCoins = reserverCoins.Sub(sdk.NewCoin(config.BaseDenom, truncatedRewards)) - ctx = ctx.WithBlockHeight(i + 1) - } - GenerateSampleFile(fileName, generatedTestData) -} - -func GenerateSampleFile(fp string, data []EmissionTestData) { - file, _ := json.MarshalIndent(data, "", " ") - _ = ioutil.WriteFile(fp, file, 0600) -} +//TODO : https://github.com/zeta-chain/node/issues/1659 +//func getaZetaFromString(amount string) sdk.Coins { +// emissionPoolInt, _ := sdk.NewIntFromString(amount) +// return sdk.NewCoins(sdk.NewCoin(config.BaseDenom, emissionPoolInt)) +//} +// +//func SetupApp(t *testing.T, params emissionsModuleTypes.Params, emissionPoolCoins sdk.Coins) (*zetaapp.App, sdk.Context, *tmtypes.ValidatorSet, *authtypes.BaseAccount) { +// pk1 := ed25519.GenPrivKey().PubKey() +// acc1 := authtypes.NewBaseAccountWithAddress(sdk.AccAddress(pk1.Address())) +// // genDelActs and genDelBalances need to have the same addresses +// // bondAmount is specified separately , the Balances here are additional tokens for delegators to have in their accounts +// genDelActs := make(authtypes.GenesisAccounts, 1) +// genDelBalances := make([]banktypes.Balance, 1) +// genDelActs[0] = acc1 +// genDelBalances[0] = banktypes.Balance{ +// Address: acc1.GetAddress().String(), +// Coins: emissionPoolCoins, +// } +// delBondAmount := getaZetaFromString("1000000000000000000000000") +// +// //genBalances := make([]banktypes.Balance, 1) +// //genBalances[0] = banktypes.Balance{ +// // Address: emissionsModuleTypes.EmissionsModuleAddress.String(), +// // Coins: emissionPoolCoins, +// //} +// +// vset := tmtypes.NewValidatorSet([]*tmtypes.Validator{}) +// for i := 0; i < 1; i++ { +// privKey := ed25519.GenPrivKey() +// pubKey := privKey.PubKey() +// val := tmtypes.NewValidator(pubKey, 1) +// err := vset.UpdateWithChangeSet([]*tmtypes.Validator{val}) +// if err != nil { +// panic("Failed to add validator") +// } +// } +// +// app := simapp.SetupWithGenesisValSet(t, vset, genDelActs, delBondAmount.AmountOf(config.BaseDenom), params, genDelBalances, nil) +// ctx := app.BaseApp.NewContext(false, tmproto.Header{}) +// ctx = ctx.WithBlockHeight(app.LastBlockHeight()) +// return app, ctx, vset, acc1 +//} +// +//type EmissionTestData struct { +// BlockHeight int64 `json:"blockHeight,omitempty"` +// BondFactor sdk.Dec `json:"bondFactor"` +// ReservesFactor sdk.Dec `json:"reservesFactor"` +// DurationFactor string `json:"durationFactor"` +//} +// +//func TestAppModule_GetBlockRewardComponents(t *testing.T) { +// +// tests := []struct { +// name string +// startingEmissionPool string +// params emissionsModuleTypes.Params +// testMaxHeight int64 +// inputFilename string +// checkValues []EmissionTestData +// generateOnly bool +// }{ +// { +// name: "default values", +// params: emissionsModuleTypes.DefaultParams(), +// startingEmissionPool: "1000000000000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// { +// name: "higher starting pool", +// params: emissionsModuleTypes.DefaultParams(), +// startingEmissionPool: "100000000000000000000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// { +// name: "lower starting pool", +// params: emissionsModuleTypes.DefaultParams(), +// startingEmissionPool: "100000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// { +// name: "different distribution percentages", +// params: emissionsModuleTypes.Params{ +// MaxBondFactor: "1.25", +// MinBondFactor: "0.75", +// AvgBlockTime: "6.00", +// TargetBondRatio: "00.67", +// ValidatorEmissionPercentage: "00.10", +// ObserverEmissionPercentage: "00.85", +// TssSignerEmissionPercentage: "00.05", +// DurationFactorConstant: "0.001877876953694702", +// }, +// startingEmissionPool: "1000000000000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// { +// name: "higher block time", +// params: emissionsModuleTypes.Params{ +// MaxBondFactor: "1.25", +// MinBondFactor: "0.75", +// AvgBlockTime: "20.00", +// TargetBondRatio: "00.67", +// ValidatorEmissionPercentage: "00.10", +// ObserverEmissionPercentage: "00.85", +// TssSignerEmissionPercentage: "00.05", +// DurationFactorConstant: "0.1", +// }, +// startingEmissionPool: "1000000000000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// { +// name: "different duration constant", +// params: emissionsModuleTypes.Params{ +// MaxBondFactor: "1.25", +// MinBondFactor: "0.75", +// AvgBlockTime: "6.00", +// TargetBondRatio: "00.67", +// ValidatorEmissionPercentage: "00.10", +// ObserverEmissionPercentage: "00.85", +// TssSignerEmissionPercentage: "00.05", +// DurationFactorConstant: "0.1", +// }, +// startingEmissionPool: "1000000000000000000000000", +// testMaxHeight: 300, +// inputFilename: "simulations.json", +// generateOnly: false, +// }, +// } +// +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// app, ctx, _, minter := SetupApp(t, tt.params, getaZetaFromString(tt.startingEmissionPool)) +// err := app.BankKeeper.SendCoinsFromAccountToModule(ctx, minter.GetAddress(), emissionsModuleTypes.ModuleName, getaZetaFromString(tt.startingEmissionPool)) +// assert.NoError(t, err) +// GenerateTestDataMaths(app, ctx, tt.testMaxHeight, tt.inputFilename) +// defer func(t *testing.T, fp string) { +// err := os.RemoveAll(fp) +// assert.NoError(t, err) +// }(t, tt.inputFilename) +// +// if tt.generateOnly { +// return +// } +// inputTestData, err := GetInputData(tt.inputFilename) +// assert.NoError(t, err) +// sort.SliceStable(inputTestData, func(i, j int) bool { return inputTestData[i].BlockHeight < inputTestData[j].BlockHeight }) +// startHeight := ctx.BlockHeight() +// assert.Equal(t, startHeight, inputTestData[0].BlockHeight, "starting block height should be equal to the first block height in the input data") +// for i := startHeight; i < tt.testMaxHeight; i++ { +// //The First distribution will occur only when begin-block is triggered +// reservesFactor, bondFactor, durationFactor := app.EmissionsKeeper.GetBlockRewardComponents(ctx) +// assert.Equal(t, inputTestData[i-1].ReservesFactor, reservesFactor, "reserves factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) +// assert.Equal(t, inputTestData[i-1].BondFactor, bondFactor, "bond factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) +// assert.Equal(t, inputTestData[i-1].DurationFactor, durationFactor.String(), "duration factor should be equal to the input data"+fmt.Sprintf(" , block height: %d", i)) +// emissionsModule.BeginBlocker(ctx, app.EmissionsKeeper) +// ctx = ctx.WithBlockHeight(i + 1) +// } +// }) +// } +//} +// +//func GetInputData(fp string) ([]EmissionTestData, error) { +// data := []EmissionTestData{} +// file, err := filepath.Abs(fp) +// if err != nil { +// +// return nil, err +// } +// file = filepath.Clean(file) +// input, err := ioutil.ReadFile(file) // #nosec G304 +// if err != nil { +// return nil, err +// } +// err = json.Unmarshal(input, &data) +// if err != nil { +// return nil, err +// } +// formatedData := make([]EmissionTestData, len(data)) +// for i, dd := range data { +// fl, err := strconv.ParseFloat(dd.DurationFactor, 64) +// if err != nil { +// return nil, err +// } +// dd.DurationFactor = fmt.Sprintf("%0.18f", fl) +// formatedData[i] = dd +// } +// return formatedData, nil +//} +// +//func GenerateTestDataMaths(app *zetaapp.App, ctx sdk.Context, testMaxHeight int64, fileName string) { +// var generatedTestData []EmissionTestData +// reserverCoins := app.BankKeeper.GetBalance(ctx, emissionsModuleTypes.EmissionsModuleAddress, config.BaseDenom) +// startHeight := ctx.BlockHeight() +// for i := startHeight; i < testMaxHeight; i++ { +// reservesFactor := sdk.NewDecFromInt(reserverCoins.Amount) +// bondFactor := app.EmissionsKeeper.GetBondFactor(ctx, app.StakingKeeper) +// durationFactor := app.EmissionsKeeper.GetDurationFactor(ctx) +// blockRewards := reservesFactor.Mul(bondFactor).Mul(durationFactor) +// generatedTestData = append(generatedTestData, EmissionTestData{ +// BlockHeight: i, +// BondFactor: bondFactor, +// DurationFactor: durationFactor.String(), +// ReservesFactor: reservesFactor, +// }) +// validatorRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).ValidatorEmissionPercentage).Mul(blockRewards).TruncateInt() +// observerRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).ObserverEmissionPercentage).Mul(blockRewards).TruncateInt() +// tssSignerRewards := sdk.MustNewDecFromStr(app.EmissionsKeeper.GetParams(ctx).TssSignerEmissionPercentage).Mul(blockRewards).TruncateInt() +// truncatedRewards := validatorRewards.Add(observerRewards).Add(tssSignerRewards) +// reserverCoins = reserverCoins.Sub(sdk.NewCoin(config.BaseDenom, truncatedRewards)) +// ctx = ctx.WithBlockHeight(i + 1) +// } +// GenerateSampleFile(fileName, generatedTestData) +//} +// +//func GenerateSampleFile(fp string, data []EmissionTestData) { +// file, _ := json.MarshalIndent(data, "", " ") +// _ = ioutil.WriteFile(fp, file, 0600) +//} diff --git a/x/emissions/client/tests/observer_rewards_test.go b/x/emissions/client/tests/observer_rewards_test.go index 853e3a3ad8..c8f11d2449 100644 --- a/x/emissions/client/tests/observer_rewards_test.go +++ b/x/emissions/client/tests/observer_rewards_test.go @@ -8,8 +8,10 @@ import ( clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + "github.com/stretchr/testify/suite" "github.com/zeta-chain/zetacore/cmd/zetacored/config" emissionscli "github.com/zeta-chain/zetacore/x/emissions/client/cli" + emissionskeeper "github.com/zeta-chain/zetacore/x/emissions/keeper" emissionstypes "github.com/zeta-chain/zetacore/x/emissions/types" observercli "github.com/zeta-chain/zetacore/x/observer/client/cli" observertypes "github.com/zeta-chain/zetacore/x/observer/types" @@ -59,7 +61,7 @@ func (s *CliTestSuite) TestObserverRewards() { // Duration factor is calculated in the same block,so we need to query based from the committed state at which the distribution is done // Would be cleaner to use `--height` flag, but it is not supported by the ExecTestCLICmd function yet emissionFactors.DurationFactor = resFactorsNewBlocks.DurationFactor - asertValues := CalculateObserverRewards(s.ballots, emissionParams.Params.ObserverEmissionPercentage, emissionFactors.ReservesFactor, emissionFactors.BondFactor, emissionFactors.DurationFactor) + asertValues := CalculateObserverRewards(&s.Suite, s.ballots, emissionParams.Params.ObserverEmissionPercentage, emissionFactors.ReservesFactor, emissionFactors.BondFactor, emissionFactors.DurationFactor) // Assert withdrawable rewards for each validator resAvailable := emissionstypes.QueryShowAvailableEmissionsResponse{} @@ -72,9 +74,11 @@ func (s *CliTestSuite) TestObserverRewards() { } -func CalculateObserverRewards(ballots []*observertypes.Ballot, observerEmissionPercentage, reservesFactor, bondFactor, durationFactor string) map[string]sdkmath.Int { +func CalculateObserverRewards(s *suite.Suite, ballots []*observertypes.Ballot, observerEmissionPercentage, reservesFactor, bondFactor, durationFactor string) map[string]sdkmath.Int { calculatedDistributer := map[string]sdkmath.Int{} - blockRewards := sdk.MustNewDecFromStr(reservesFactor).Mul(sdk.MustNewDecFromStr(bondFactor)).Mul(sdk.MustNewDecFromStr(durationFactor)) + //blockRewards := sdk.MustNewDecFromStr(reservesFactor).Mul(sdk.MustNewDecFromStr(bondFactor)).Mul(sdk.MustNewDecFromStr(durationFactor)) + blockRewards, err := emissionskeeper.CalculateFixedValidatorRewards(emissionstypes.AvgBlockTime) + s.Require().NoError(err) observerRewards := sdk.MustNewDecFromStr(observerEmissionPercentage).Mul(blockRewards).TruncateInt() rewardsDistributer := map[string]int64{} totalRewardsUnits := int64(0) diff --git a/x/emissions/keeper/block_rewards_components.go b/x/emissions/keeper/block_rewards_components.go index cc93fb3111..ab70e13de5 100644 --- a/x/emissions/keeper/block_rewards_components.go +++ b/x/emissions/keeper/block_rewards_components.go @@ -3,11 +3,12 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/cmd/zetacored/config" + "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/emissions/types" ) func (k Keeper) GetBlockRewardComponents(ctx sdk.Context) (sdk.Dec, sdk.Dec, sdk.Dec) { - reservesFactor := GetReservesFactor(ctx, k.GetBankKeeper()) + reservesFactor := k.GetReservesFactor(ctx) if reservesFactor.LTE(sdk.ZeroDec()) { return sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec() } @@ -55,7 +56,26 @@ func (k Keeper) GetDurationFactor(ctx sdk.Context) sdk.Dec { return fractionNumerator.Quo(fractionDenominator) } -func GetReservesFactor(ctx sdk.Context, keeper types.BankKeeper) sdk.Dec { - reserveAmount := keeper.GetBalance(ctx, types.EmissionsModuleAddress, config.BaseDenom) +func (k Keeper) GetReservesFactor(ctx sdk.Context) sdk.Dec { + reserveAmount := k.GetBankKeeper().GetBalance(ctx, types.EmissionsModuleAddress, config.BaseDenom) return sdk.NewDecFromInt(reserveAmount.Amount) } + +func (k Keeper) GetFixedBlockRewards() (sdk.Dec, error) { + return CalculateFixedValidatorRewards(types.AvgBlockTime) +} + +func CalculateFixedValidatorRewards(avgBlockTimeString string) (sdk.Dec, error) { + azetaAmountTotalRewards, err := common.GetAzetaDecFromAmountInZeta(types.BlockRewardsInZeta) + if err != nil { + return sdk.ZeroDec(), err + } + avgBlockTime, err := sdk.NewDecFromStr(avgBlockTimeString) + if err != nil { + return sdk.ZeroDec(), err + } + numberOfBlocksInAMonth := sdk.NewDec(types.SecsInMonth).Quo(avgBlockTime) + numberOfBlocksTotal := numberOfBlocksInAMonth.Mul(sdk.NewDec(12)).Mul(sdk.NewDec(types.EmissionScheduledYears)) + constantRewardPerBlock := azetaAmountTotalRewards.Quo(numberOfBlocksTotal) + return constantRewardPerBlock, nil +} diff --git a/x/emissions/keeper/block_rewards_components_test.go b/x/emissions/keeper/block_rewards_components_test.go new file mode 100644 index 0000000000..f8d206fbde --- /dev/null +++ b/x/emissions/keeper/block_rewards_components_test.go @@ -0,0 +1,50 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + emissionskeeper "github.com/zeta-chain/zetacore/x/emissions/keeper" +) + +func TestKeeper_CalculateFixedValidatorRewards(t *testing.T) { + tt := []struct { + name string + blockTimeInSecs string + expectedBlockRewards sdk.Dec + }{ + { + name: "Block Time 5.7", + blockTimeInSecs: "5.7", + expectedBlockRewards: sdk.MustNewDecFromStr("9620949074074074074.074070733466756687"), + }, + { + name: "Block Time 6", + blockTimeInSecs: "6", + expectedBlockRewards: sdk.MustNewDecFromStr("10127314814814814814.814814814814814815"), + }, + { + name: "Block Time 3", + blockTimeInSecs: "3", + expectedBlockRewards: sdk.MustNewDecFromStr("5063657407407407407.407407407407407407"), + }, + { + name: "Block Time 2", + blockTimeInSecs: "2", + expectedBlockRewards: sdk.MustNewDecFromStr("3375771604938271604.938271604938271605"), + }, + { + name: "Block Time 8", + blockTimeInSecs: "8", + expectedBlockRewards: sdk.MustNewDecFromStr("13503086419753086419.753086419753086420"), + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + blockRewards, err := emissionskeeper.CalculateFixedValidatorRewards(tc.blockTimeInSecs) + assert.NoError(t, err) + assert.Equal(t, tc.expectedBlockRewards, blockRewards) + }) + } +} diff --git a/x/emissions/types/keys.go b/x/emissions/types/keys.go index e78b0ddade..4be2d268b4 100644 --- a/x/emissions/types/keys.go +++ b/x/emissions/types/keys.go @@ -1,6 +1,7 @@ package types import ( + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -23,7 +24,11 @@ const ( MemStoreKey = "mem_emissions" WithdrawableEmissionsKey = "WithdrawableEmissions-value-" - SecsInMonth = 30 * 24 * 60 * 60 + SecsInMonth = 30 * 24 * 60 * 60 + BlockRewardsInZeta = "210000000" + + EmissionScheduledYears = 4 + AvgBlockTime = "5.7" ) func KeyPrefix(p string) []byte { @@ -46,4 +51,5 @@ var ( EmissionsModuleAddress = authtypes.NewModuleAddress(ModuleName) UndistributedObserverRewardsPoolAddress = authtypes.NewModuleAddress(UndistributedObserverRewardsPool) UndistributedTssRewardsPoolAddress = authtypes.NewModuleAddress(UndistributedTssRewardsPool) + BlockReward = sdk.MustNewDecFromStr("9620949074074074074.074070733466756687") ) From 1c97d9f6cd83e6883384c29c10a15f0b52259cc5 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:27:27 -0800 Subject: [PATCH 55/67] fix: change WhitelistERC20 authorization from group1=>group2 (#1642) * change WhitelistERC20 authorization from group1=>group2 * changelog update * Update changelog.md --------- Co-authored-by: Lucas Bertrand --- changelog.md | 3 +++ x/crosschain/keeper/msg_server_whitelist_erc20.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index edf96c140d..82a98252e3 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,9 @@ ## Unreleased ### Fixes +### Fixes + +* [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes ## Version: v12.1.0 diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20.go b/x/crosschain/keeper/msg_server_whitelist_erc20.go index 9dc082ec31..cadd5b51e0 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20.go @@ -25,7 +25,7 @@ import ( // Authorized: admin policy group 1. func (k msgServer) WhitelistERC20(goCtx context.Context, msg *types.MsgWhitelistERC20) (*types.MsgWhitelistERC20Response, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_group1) { + if msg.Creator != k.zetaObserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_group2) { return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") } erc20Addr := ethcommon.HexToAddress(msg.Erc20Address) From be1c04009b15b091bd681d2cd5df9a744dc973a4 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:12:08 -0600 Subject: [PATCH 56/67] schedule bitcoin keysign with intervals to avoid keysign failures (#1664) --- changelog.md | 4 +++- zetaclient/btc_signer.go | 11 ----------- zetaclient/zetacore_observer.go | 17 +++++++++++++++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index 82a98252e3..f48ad9d2da 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes +* [1656](https://github.com/zeta-chain/node/issues/1656) - schedule bitcoin keysign with intervals to avoid keysign failures ## Version: v12.1.0 @@ -14,7 +15,8 @@ * [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests ### Features -* [1658](https://github.com/zeta-chain/node/pull/1658) - modify emission distribution to use fixed block rewards +* [1658](https://github.com/zeta-chain/node/pull/1658) - modify emission distribution to use fixed block rewards + ### Fixes * [1535](https://github.com/zeta-chain/node/issues/1535) - Avoid voting on wrong ballots due to false blockNumber in EVM tx receipt * [1588](https://github.com/zeta-chain/node/pull/1588) - fix chain params comparison logic diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index ba493a9fce..4cd57a5e0b 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -275,18 +275,7 @@ func (signer *BTCSigner) TryProcessOutTx( return } myid := zetaBridge.GetKeys().GetAddress() - // Early return if the send is already processed - // FIXME: handle revert case outboundTxTssNonce := params.OutboundTxTssNonce - included, confirmed, err := btcClient.IsSendOutTxProcessed(cctx.Index, outboundTxTssNonce, common.CoinType_Gas, logger) - if err != nil { - logger.Error().Err(err).Msgf("cannot check if send %s is processed", cctx.Index) - return - } - if included || confirmed { - logger.Info().Msgf("CCTX %s already processed; exit signer", outTxID) - return - } sizelimit := params.OutboundTxGasLimit gasprice, ok := new(big.Int).SetString(params.OutboundTxGasPrice, 10) diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 333c6ce262..6fae898ece 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -257,7 +257,7 @@ func (co *CoreObserver) scheduleCctxEVM( // try confirming the outtx included, _, err := ob.IsSendOutTxProcessed(cctx.Index, params.OutboundTxTssNonce, params.CoinType, co.logger.ZetaChainWatcher) if err != nil { - co.logger.ZetaChainWatcher.Error().Err(err).Msgf("scheduleCctxEVM: IsSendOutTxProcessed faild for chain %d", chainID) + co.logger.ZetaChainWatcher.Error().Err(err).Msgf("scheduleCctxEVM: IsSendOutTxProcessed faild for chain %d nonce %d", chainID, nonce) continue } if included { @@ -320,6 +320,8 @@ func (co *CoreObserver) scheduleCctxBTC( co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxBTC: chain client is not a bitcoin client") return } + // #nosec G701 positive + interval := uint64(ob.GetChainParams().OutboundTxScheduleInterval) lookahead := ob.GetChainParams().OutboundTxScheduleLookahead // schedule at most one keysign per ticker @@ -332,6 +334,17 @@ func (co *CoreObserver) scheduleCctxBTC( co.logger.ZetaChainWatcher.Error().Msgf("scheduleCctxBTC: outtx %s chainid mismatch: want %d, got %d", outTxID, chainID, params.ReceiverChainId) continue } + // try confirming the outtx + included, confirmed, err := btcClient.IsSendOutTxProcessed(cctx.Index, nonce, params.CoinType, co.logger.ZetaChainWatcher) + if err != nil { + co.logger.ZetaChainWatcher.Error().Err(err).Msgf("scheduleCctxBTC: IsSendOutTxProcessed faild for chain %d nonce %d", chainID, nonce) + continue + } + if included || confirmed { + co.logger.ZetaChainWatcher.Info().Msgf("scheduleCctxBTC: outtx %s already included; do not schedule keysign", outTxID) + return + } + // stop if the nonce being processed is higher than the pending nonce if nonce > btcClient.GetPendingNonce() { break @@ -342,7 +355,7 @@ func (co *CoreObserver) scheduleCctxBTC( break } // try confirming the outtx or scheduling a keysign - if !outTxMan.IsOutTxActive(outTxID) { + if nonce%interval == zetaHeight%interval && !outTxMan.IsOutTxActive(outTxID) { outTxMan.StartTryProcess(outTxID) co.logger.ZetaChainWatcher.Debug().Msgf("scheduleCctxBTC: sign outtx %s with value %d\n", outTxID, params.Amount) go signer.TryProcessOutTx(cctx, outTxMan, outTxID, ob, co.bridge, zetaHeight) From 6e660cc6e67f2fc8e8eb298875ae8788f0588427 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:34:55 -0600 Subject: [PATCH 57/67] fix: fix SegWit tx size estimation (in vByte) and gas fee calculation (#1669) * fix SegWit tx size and gas fee calculation * define outTxBytesMin and outTxBytesMax as constants --- changelog.md | 3 +- zetaclient/btc_signer.go | 20 ++---- zetaclient/btc_signer_test.go | 127 +++++++++++++++++++++------------- zetaclient/utils.go | 39 +++++++---- 4 files changed, 113 insertions(+), 76 deletions(-) diff --git a/changelog.md b/changelog.md index f48ad9d2da..9f45aecda3 100644 --- a/changelog.md +++ b/changelog.md @@ -2,12 +2,13 @@ ## Unreleased -### Fixes ### Fixes * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes * [1656](https://github.com/zeta-chain/node/issues/1656) - schedule bitcoin keysign with intervals to avoid keysign failures +* [1661](https://github.com/zeta-chain/node/issues/1661) - use estimated SegWit tx size for Bitcoin gas fee calculation +* [1667](https://github.com/zeta-chain/node/issues/1667) - estimate SegWit tx size in uinit of vByte ## Version: v12.1.0 diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 4cd57a5e0b..245f4039ff 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -23,19 +23,11 @@ import ( const ( maxNoOfInputsPerTx = 20 - consolidationRank = 10 // the rank below (or equal to) which we consolidate UTXOs + consolidationRank = 10 // the rank below (or equal to) which we consolidate UTXOs + outTxBytesMin = uint64(239) // 239vB == EstimateSegWitTxSize(2, 3) + outTxBytesMax = uint64(1531) // 1531v == EstimateSegWitTxSize(21, 3) ) -var ( - outTxBytesMin uint64 - outTxBytesMax uint64 -) - -func init() { - outTxBytesMin = EstimateSegWitTxSize(2, 3) // 403B, estimated size for a 2-input, 3-output SegWit tx - outTxBytesMax = EstimateSegWitTxSize(21, 3) // 3234B, estimated size for a 21-input, 3-output SegWit tx -} - type BTCSigner struct { tssSigner TSSSigner rpcClient BTCRPCClient @@ -114,9 +106,9 @@ func (signer *BTCSigner) SignWithdrawTx( // size checking // #nosec G701 always positive - txSize := uint64(tx.SerializeSize()) - if txSize > sizeLimit { // ZRC20 'withdraw' charged less fee from end user - signer.logger.Info().Msgf("sizeLimit %d is less than txSize %d for nonce %d", sizeLimit, txSize, nonce) + txSize := EstimateSegWitTxSize(uint64(len(prevOuts)), 3) + if sizeLimit < BtcOutTxBytesWithdrawer { // ZRC20 'withdraw' charged less fee from end user + signer.logger.Info().Msgf("sizeLimit %d is less than BtcOutTxBytesWithdrawer %d for nonce %d", sizeLimit, txSize, nonce) } if txSize < outTxBytesMin { // outbound shouldn't be blocked a low sizeLimit signer.logger.Warn().Msgf("txSize %d is less than outTxBytesMin %d; use outTxBytesMin", txSize, outTxBytesMin) diff --git a/zetaclient/btc_signer_test.go b/zetaclient/btc_signer_test.go index 5c12e67876..348bd8a4d5 100644 --- a/zetaclient/btc_signer_test.go +++ b/zetaclient/btc_signer_test.go @@ -9,6 +9,7 @@ import ( "sync" "testing" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg" @@ -31,6 +32,31 @@ type BTCSignerSuite struct { var _ = Suite(&BTCSignerSuite{}) +// 21 example UTXO txids to use in the test. +var exampleTxids = []string{ + "c1729638e1c9b6bfca57d11bf93047d98b65594b0bf75d7ee68bf7dc80dc164e", + "54f9ebbd9e3ad39a297da54bf34a609b6831acbea0361cb5b7b5c8374f5046aa", + "b18a55a34319cfbedebfcfe1a80fef2b92ad8894d06caf8293a0344824c2cfbc", + "969fb309a4df7c299972700da788b5d601c0c04bab4ab46fff79d0335a7d75de", + "6c71913061246ffc20e268c1b0e65895055c36bfbf1f8faf92dcad6f8242121e", + "ba6d6e88cb5a97556684a1232719a3ffe409c5c9501061e1f59741bc412b3585", + "69b56c3c8c5d1851f9eaec256cd49f290b477a5d43e2aef42ef25d3c1d9f4b33", + "b87effd4cb46fe1a575b5b1ba0289313dc9b4bc9e615a3c6cbc0a14186921fdf", + "3135433054523f5e220621c9e3d48efbbb34a6a2df65635c2a3e7d462d3e1cda", + "8495c22a9ce6359ab53aa048c13b41c64fdf5fe141f516ba2573cc3f9313f06e", + "f31583544b475370d7b9187c9a01b92e44fb31ac5fcfa7fc55565ac64043aa9a", + "c03d55f9f717c1df978623e2e6b397b720999242f9ead7db9b5988fee3fb3933", + "ee55688439b47a5410cdc05bac46be0094f3af54d307456fdfe6ba8caf336e0b", + "61895f86c70f0bc3eef55d9a00347b509fa90f7a344606a9774be98a3ee9e02a", + "ffabb401a19d04327bd4a076671d48467dbcde95459beeab23df21686fd01525", + "b7e1c03b9b73e4e90fc06da893072c5604203c49e66699acbb2f61485d822981", + "185614d21973990138e478ce10e0a4014352df58044276d4e4c0093aa140f482", + "4a2800f13d15dc0c82308761d6fe8f6d13b65e42d7ca96a42a3a7048830e8c55", + "fb98f52e91db500735b185797cebb5848afbfe1289922d87e03b98c3da5b85ef", + "7901c5e36d9e8456ac61b29b82048650672a889596cbd30a9f8910a589ffc5b3", + "6bcd0850fd2fa1404290ed04d78d4ae718414f16d4fbfd344951add8dcf60326", +} + func (s *BTCSignerSuite) SetUpTest(c *C) { // test private key with EVM address //// EVM: 0x236C7f53a90493Bb423411fe4117Cb4c2De71DfB @@ -219,11 +245,10 @@ func generateKeyPair(t *testing.T, net *chaincfg.Params) (*btcec.PrivateKey, []b func addTxInputs(t *testing.T, tx *wire.MsgTx, txids []string) { preTxSize := tx.SerializeSize() - require.Equal(t, bytesEmptyTx, preTxSize) - for i, txid := range txids { + for _, txid := range txids { hash, err := chainhash.NewHashFromStr(txid) require.Nil(t, err) - outpoint := wire.NewOutPoint(hash, uint32(i%3)) + outpoint := wire.NewOutPoint(hash, uint32(rand.Intn(100))) txIn := wire.NewTxIn(outpoint, nil, nil) tx.AddTxIn(txIn) require.Equal(t, bytesPerInput, tx.SerializeSize()-preTxSize) @@ -307,13 +332,12 @@ func TestP2WPHSize2In3Out(t *testing.T) { // Payer sign the redeeming transaction. signTx(t, tx, payerScript, privateKey) - // Estimate the tx size + // Estimate the tx size in vByte // #nosec G701 always positive - txSize := uint64(tx.SerializeSize()) - sizeEstimated := EstimateSegWitTxSize(uint64(len(utxosTxids)), 3) - require.Equal(t, outTxBytesMin, sizeEstimated) - require.True(t, outTxBytesMin >= txSize) - require.True(t, outTxBytesMin-txSize <= 2) // 2 witness may vary + vBytes := uint64(blockchain.GetTransactionWeight(btcutil.NewTx(tx)) / blockchain.WitnessScaleFactor) + vBytesEstimated := EstimateSegWitTxSize(uint64(len(utxosTxids)), 3) + require.Equal(t, vBytes, vBytesEstimated) + require.Equal(t, vBytes, outTxBytesMin) } func TestP2WPHSize21In3Out(t *testing.T) { @@ -321,35 +345,9 @@ func TestP2WPHSize21In3Out(t *testing.T) { privateKey, payerScript := generateKeyPair(t, &chaincfg.TestNet3Params) _, payeeScript := generateKeyPair(t, &chaincfg.TestNet3Params) - // 21 example UTXO txids to use in the test. - utxosTxids := []string{ - "c1729638e1c9b6bfca57d11bf93047d98b65594b0bf75d7ee68bf7dc80dc164e", - "54f9ebbd9e3ad39a297da54bf34a609b6831acbea0361cb5b7b5c8374f5046aa", - "b18a55a34319cfbedebfcfe1a80fef2b92ad8894d06caf8293a0344824c2cfbc", - "969fb309a4df7c299972700da788b5d601c0c04bab4ab46fff79d0335a7d75de", - "6c71913061246ffc20e268c1b0e65895055c36bfbf1f8faf92dcad6f8242121e", - "ba6d6e88cb5a97556684a1232719a3ffe409c5c9501061e1f59741bc412b3585", - "69b56c3c8c5d1851f9eaec256cd49f290b477a5d43e2aef42ef25d3c1d9f4b33", - "b87effd4cb46fe1a575b5b1ba0289313dc9b4bc9e615a3c6cbc0a14186921fdf", - "3135433054523f5e220621c9e3d48efbbb34a6a2df65635c2a3e7d462d3e1cda", - "8495c22a9ce6359ab53aa048c13b41c64fdf5fe141f516ba2573cc3f9313f06e", - "f31583544b475370d7b9187c9a01b92e44fb31ac5fcfa7fc55565ac64043aa9a", - "c03d55f9f717c1df978623e2e6b397b720999242f9ead7db9b5988fee3fb3933", - "ee55688439b47a5410cdc05bac46be0094f3af54d307456fdfe6ba8caf336e0b", - "61895f86c70f0bc3eef55d9a00347b509fa90f7a344606a9774be98a3ee9e02a", - "ffabb401a19d04327bd4a076671d48467dbcde95459beeab23df21686fd01525", - "b7e1c03b9b73e4e90fc06da893072c5604203c49e66699acbb2f61485d822981", - "185614d21973990138e478ce10e0a4014352df58044276d4e4c0093aa140f482", - "4a2800f13d15dc0c82308761d6fe8f6d13b65e42d7ca96a42a3a7048830e8c55", - "fb98f52e91db500735b185797cebb5848afbfe1289922d87e03b98c3da5b85ef", - "7901c5e36d9e8456ac61b29b82048650672a889596cbd30a9f8910a589ffc5b3", - "6bcd0850fd2fa1404290ed04d78d4ae718414f16d4fbfd344951add8dcf60326", - } - // Create a new transaction and add inputs tx := wire.NewMsgTx(wire.TxVersion) - require.Equal(t, bytesEmptyTx, tx.SerializeSize()) - addTxInputs(t, tx, utxosTxids) + addTxInputs(t, tx, exampleTxids) // Add P2WPKH outputs addTxOutputs(t, tx, payerScript, payeeScript) @@ -357,13 +355,48 @@ func TestP2WPHSize21In3Out(t *testing.T) { // Payer sign the redeeming transaction. signTx(t, tx, payerScript, privateKey) - // Estimate the tx size + // Estimate the tx size in vByte // #nosec G701 always positive - txSize := uint64(tx.SerializeSize()) - sizeEstimated := EstimateSegWitTxSize(uint64(len(utxosTxids)), 3) - require.Equal(t, outTxBytesMax, sizeEstimated) - require.True(t, outTxBytesMax >= txSize) - require.True(t, outTxBytesMax-txSize <= 21) // 21 witness may vary + vError := uint64(21 / 4) // 5 vBytes error tolerance + vBytes := uint64(blockchain.GetTransactionWeight(btcutil.NewTx(tx)) / blockchain.WitnessScaleFactor) + vBytesEstimated := EstimateSegWitTxSize(uint64(len(exampleTxids)), 3) + require.Equal(t, vBytesEstimated, outTxBytesMax) + if vBytes > vBytesEstimated { + require.True(t, vBytes-vBytesEstimated <= vError) + } else { + require.True(t, vBytesEstimated-vBytes <= vError) + } +} + +func TestP2WPHSizeXIn3Out(t *testing.T) { + // Generate payer/payee private keys and P2WPKH addresss + privateKey, payerScript := generateKeyPair(t, &chaincfg.TestNet3Params) + _, payeeScript := generateKeyPair(t, &chaincfg.TestNet3Params) + + // Create new transactions with X (2 <= X <= 21) inputs and 3 outputs respectively + for x := 2; x <= 21; x++ { + tx := wire.NewMsgTx(wire.TxVersion) + addTxInputs(t, tx, exampleTxids[:x]) + + // Add P2WPKH outputs + addTxOutputs(t, tx, payerScript, payeeScript) + + // Payer sign the redeeming transaction. + signTx(t, tx, payerScript, privateKey) + + // Estimate the tx size + // #nosec G701 always positive + vError := uint64(0.25 + float64(x)/4) // 1st witness incur 0.25 vByte error, other witness incur 1/4 vByte error tolerance, + vBytes := uint64(blockchain.GetTransactionWeight(btcutil.NewTx(tx)) / blockchain.WitnessScaleFactor) + vBytesEstimated := EstimateSegWitTxSize(uint64(len(exampleTxids[:x])), 3) + if vBytes > vBytesEstimated { + require.True(t, vBytes-vBytesEstimated <= vError) + //fmt.Printf("%d error percentage: %.2f%%\n", float64(vBytes-vBytesEstimated)/float64(vBytes)*100) + } else { + require.True(t, vBytesEstimated-vBytes <= vError) + //fmt.Printf("error percentage: %.2f%%\n", float64(vBytesEstimated-vBytes)/float64(vBytes)*100) + } + } } func TestP2WPHSizeBreakdown(t *testing.T) { @@ -374,14 +407,14 @@ func TestP2WPHSizeBreakdown(t *testing.T) { fmt.Printf("1 input, 1 output: %d\n", sz) txSizeDepositor := SegWitTxSizeDepositor() - require.Equal(t, uint64(149), txSizeDepositor) + require.Equal(t, uint64(68), txSizeDepositor) txSizeWithdrawer := SegWitTxSizeWithdrawer() - require.Equal(t, uint64(254), txSizeWithdrawer) - require.Equal(t, txSize2In3Out, txSizeDepositor+txSizeWithdrawer) // 403 = 149 + 254 + require.Equal(t, uint64(171), txSizeWithdrawer) + require.Equal(t, txSize2In3Out, txSizeDepositor+txSizeWithdrawer) // 239 = 68 + 171 - depositFee := DepositorFee(5) - require.Equal(t, depositFee, 0.00000745) + depositFee := DepositorFee(20) + require.Equal(t, depositFee, 0.00001360) } // helper function to create a new BitcoinChainClient diff --git a/zetaclient/utils.go b/zetaclient/utils.go index 5a0fcd9ab2..a886d4e309 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -13,7 +13,9 @@ import ( "time" sdkmath "cosmossdk.io/math" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" @@ -36,22 +38,18 @@ const ( ) var ( - BtcOutTxBytesMin uint64 - BtcOutTxBytesMax uint64 BtcOutTxBytesDepositor uint64 BtcOutTxBytesWithdrawer uint64 BtcDepositorFeeMin float64 ) func init() { - BtcOutTxBytesMin = EstimateSegWitTxSize(2, 3) // 403B, estimated size for a 2-input, 3-output SegWit tx - BtcOutTxBytesMax = EstimateSegWitTxSize(21, 3) // 3234B, estimated size for a 21-input, 3-output SegWit tx - BtcOutTxBytesDepositor = SegWitTxSizeDepositor() // 149B, the outtx size incurred by the depositor - BtcOutTxBytesWithdrawer = SegWitTxSizeWithdrawer() // 254B, the outtx size incurred by the withdrawer + BtcOutTxBytesDepositor = SegWitTxSizeDepositor() // 68vB, the outtx size incurred by the depositor + BtcOutTxBytesWithdrawer = SegWitTxSizeWithdrawer() // 171vB, the outtx size incurred by the withdrawer - // depositor fee calculation is based on a fixed fee rate of 5 sat/byte just for simplicity. + // depositor fee calculation is based on a fixed fee rate of 20 sat/byte just for simplicity. // In reality, the fee rate on UTXO deposit is different from the fee rate when the UTXO is spent. - BtcDepositorFeeMin = DepositorFee(5) // 0.00000745 (5 * 149B / 100000000), the minimum deposit fee in BTC for 5 sat/byte + BtcDepositorFeeMin = DepositorFee(20) // 0.00001360 (20 * 68vB / 100000000), the minimum deposit fee in BTC for 20 sat/byte } func PrettyPrintStruct(val interface{}) (string, error) { @@ -73,27 +71,40 @@ func FeeRateToSatPerByte(rate float64) *big.Int { return new(big.Int).Div(satPerKB, big.NewInt(bytesPerKB)) } -// EstimateSegWitTxSize estimates SegWit tx size +// WiredTxSize calculates the wired tx size in bytes +func WiredTxSize(numInputs uint64, numOutputs uint64) uint64 { + // Version 4 bytes + LockTime 4 bytes + Serialized varint size for the + // number of transaction inputs and outputs. + // #nosec G701 always positive + return uint64(8 + wire.VarIntSerializeSize(numInputs) + wire.VarIntSerializeSize(numOutputs)) +} + +// EstimateSegWitTxSize estimates SegWit tx size in vByte func EstimateSegWitTxSize(numInputs uint64, numOutputs uint64) uint64 { if numInputs == 0 { return 0 } + bytesWiredTx := WiredTxSize(numInputs, numOutputs) bytesInput := numInputs * bytesPerInput bytesOutput := numOutputs * bytesPerOutput bytesWitness := bytes1stWitness + (numInputs-1)*bytesPerWitness - return bytesEmptyTx + bytesInput + bytesOutput + bytesWitness + + // 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 + bytesWitness/blockchain.WitnessScaleFactor } -// SegWitTxSizeDepositor returns SegWit tx size (149B) incurred by the depositor +// SegWitTxSizeDepositor returns SegWit tx size (68vB) incurred by the depositor func SegWitTxSizeDepositor() uint64 { - return bytesPerInput + bytesPerWitness + return bytesPerInput + bytesPerWitness/blockchain.WitnessScaleFactor } -// SegWitTxSizeWithdrawer returns SegWit tx size (254B) incurred by the withdrawer +// SegWitTxSizeWithdrawer returns SegWit tx size (171vB) incurred by the withdrawer (1 input, 3 outputs) func SegWitTxSizeWithdrawer() uint64 { + bytesWiredTx := WiredTxSize(1, 3) bytesInput := uint64(1) * bytesPerInput // nonce mark bytesOutput := uint64(3) * bytesPerOutput // 3 outputs: new nonce mark, payment, change - return bytesEmptyTx + bytesInput + bytesOutput + bytes1stWitness + return bytesWiredTx + bytesInput + bytesOutput + bytes1stWitness/blockchain.WitnessScaleFactor } // DepositorFee calculates the depositor fee in BTC for a given sat/byte fee rate From 39dedf31d30edde06a17ec7498121dd965370a71 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:52:31 -0600 Subject: [PATCH 58/67] fix: skip Goerli BlobTxType transaction and Mumbai empty block (#1665) * skip Goerli BlobTxType transaction and Mumbai empty block * use original ethrpc package and some updates according to suggestions --- changelog.md | 2 + go.mod | 5 +- go.sum | 3 + zetaclient/evm_client.go | 241 +++++++++++++++++++++++++++------------ zetaclient/tss_signer.go | 41 ++++--- zetaclient/utils.go | 6 + 6 files changed, 210 insertions(+), 88 deletions(-) diff --git a/changelog.md b/changelog.md index 9f45aecda3..c37ee97805 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,8 @@ * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes * [1656](https://github.com/zeta-chain/node/issues/1656) - schedule bitcoin keysign with intervals to avoid keysign failures +* [1662](https://github.com/zeta-chain/node/issues/1662) - skip Goerli BlobTxType transactions introduced in Dencun upgrade +* [1663](https://github.com/zeta-chain/node/issues/1663) - skip Mumbai empty block if ethclient sanity check fails * [1661](https://github.com/zeta-chain/node/issues/1661) - use estimated SegWit tx size for Bitcoin gas fee calculation * [1667](https://github.com/zeta-chain/node/issues/1667) - estimate SegWit tx size in uinit of vByte diff --git a/go.mod b/go.mod index aff1f815c3..8341c0bddf 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,10 @@ require ( gorm.io/gorm v1.24.6 ) -require github.com/binance-chain/tss-lib v0.0.0-20201118045712-70b2cb4bf916 +require ( + github.com/binance-chain/tss-lib v0.0.0-20201118045712-70b2cb4bf916 + github.com/onrik/ethrpc v1.2.0 +) require ( github.com/DataDog/zstd v1.5.2 // indirect diff --git a/go.sum b/go.sum index 96ac6b81eb..be10cf47d8 100644 --- a/go.sum +++ b/go.sum @@ -1869,6 +1869,7 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea/go.mod h1:QMdK4dGB3YhEW2BmA1wgGpPYI3HZy/5gD705PXKUVSg= github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= +github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= @@ -2358,6 +2359,8 @@ github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1 github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onrik/ethrpc v1.2.0 h1:BBcr1iWxW1RBP/eyZfzvSKtGgeqexq5qS0yyf4pmKbc= +github.com/onrik/ethrpc v1.2.0/go.mod h1:uvyqpn8+WbsTgBYfouImgEfpIMb0hR8fWGjwdgPHtFU= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 36d5ee0570..8d5b78655e 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -1,6 +1,7 @@ package zetaclient import ( + "bytes" "context" "fmt" "math" @@ -8,6 +9,7 @@ import ( "os" "sort" "strconv" + "strings" "sync" "sync/atomic" "time" @@ -22,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rlp" lru "github.com/hashicorp/golang-lru" + "github.com/onrik/ethrpc" "github.com/pkg/errors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -70,6 +73,7 @@ type EVMChainClient struct { *ChainMetrics chain common.Chain evmClient EVMRPCClient + evmClientAlternate *ethrpc.EthRPC // a fallback rpc client KlaytnClient KlaytnRPCClient zetaClient ZetaCoreBridger Tss TSSSigner @@ -92,7 +96,9 @@ type EVMChainClient struct { params observertypes.ChainParams ts *TelemetryServer - BlockCache *lru.Cache + blockCache *lru.Cache + blockCacheV3 *lru.Cache // blockCacheV3 caches blocks containing type-3 (BlobTxType) transactions + headerCache *lru.Cache } var _ ChainClient = (*EVMChainClient)(nil) @@ -146,12 +152,24 @@ func NewEVMChainClient( return nil, err } ob.evmClient = client + ob.evmClientAlternate = ethrpc.NewEthRPC(evmCfg.Endpoint) - ob.BlockCache, err = lru.New(1000) + // create block header and block caches + ob.blockCache, err = lru.New(1000) if err != nil { ob.logger.ChainLogger.Error().Err(err).Msg("failed to create block cache") return nil, err } + ob.blockCacheV3, err = lru.New(1000) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("failed to create block cache v3") + return nil, err + } + ob.headerCache, err = lru.New(1000) + if err != nil { + ob.logger.ChainLogger.Error().Err(err).Msg("failed to create header cache") + return nil, err + } if ob.chain.IsKlaytnChain() { client, err := Dial(evmCfg.Endpoint) @@ -756,26 +774,6 @@ func (ob *EVMChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtyp return nil, nil, false } - // cross-check receipt against the block - block, err := ob.GetBlockByNumberCached(receipt.BlockNumber.Uint64()) - if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: GetBlockByNumberCached error, txHash %s nonce %d block %d", - txHash, nonce, receipt.BlockNumber) - return nil, nil, false - } - // #nosec G701 non negative value - if receipt.TransactionIndex >= uint(len(block.Transactions())) { - log.Error().Msgf("confirmTxByHash: transaction index %d out of range [0, %d), txHash %s nonce %d block %d", - receipt.TransactionIndex, len(block.Transactions()), txHash, nonce, receipt.BlockNumber) - return nil, nil, false - } - txAtIndex := block.Transactions()[receipt.TransactionIndex] - if txAtIndex.Hash() != transaction.Hash() { - log.Error().Msgf("confirmTxByHash: transaction at index %d has different hash %s, txHash %s nonce %d block %d", - receipt.TransactionIndex, txAtIndex.Hash().Hex(), txHash, nonce, receipt.BlockNumber) - 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", @@ -783,9 +781,49 @@ func (ob *EVMChainClient) checkConfirmedTx(txHash string, nonce uint64) (*ethtyp 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.BlockNumber.Uint64(), receipt.TransactionIndex) + 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 in the block at blockNumber and txIndex +func (ob *EVMChainClient) checkTxInclusion(tx *ethtypes.Transaction, blockNumber uint64, txIndex uint) error { + block, blockRPC, fallBack, _, err := ob.GetBlockByNumberCached(blockNumber) + if err != nil { + return fmt.Errorf("GetBlockByNumberCached error for block %d txHash %s nonce %d: %w", blockNumber, tx.Hash(), tx.Nonce(), err) + } + if !fallBack { + // #nosec G701 non negative value + if txIndex >= uint(len(block.Transactions())) { + return fmt.Errorf("transaction index %d out of range [0, %d), txHash %s nonce %d block %d", + txIndex, len(block.Transactions()), tx.Hash(), tx.Nonce(), blockNumber) + } + txAtIndex := block.Transactions()[txIndex] + if txAtIndex.Hash() != tx.Hash() { + return fmt.Errorf("transaction at index %d has different hash %s, txHash %s nonce %d block %d", + txIndex, txAtIndex.Hash().Hex(), tx.Hash(), tx.Nonce(), blockNumber) + } + } else { // fell back on ETH RPC as ethclient failed to parse the block + // #nosec G701 non negative value + if txIndex >= uint(len(blockRPC.Transactions)) { + return fmt.Errorf("transaction index %d out of range [0, %d), txHash %s nonce %d block %d", + txIndex, len(block.Transactions()), tx.Hash(), tx.Nonce(), blockNumber) + } + txAtIndex := blockRPC.Transactions[txIndex] + if ethcommon.HexToHash(txAtIndex.Hash) != tx.Hash() { + return fmt.Errorf("transaction at index %d has different hash %s, txHash %s nonce %d block %d", + txIndex, txAtIndex.Hash, tx.Hash(), tx.Nonce(), blockNumber) + } + } + return nil +} + // SetLastBlockHeightScanned set last block height scanned (not necessarily caught up with external block; could be slow/paused) func (ob *EVMChainClient) SetLastBlockHeightScanned(height uint64) { atomic.StoreUint64(&ob.lastBlockScanned, height) @@ -863,12 +901,12 @@ func (ob *EVMChainClient) postBlockHeader(tip uint64) error { return fmt.Errorf("postBlockHeader: must post block confirmed block header: %d > %d", bn, tip) } - block, err := ob.GetBlockByNumberCached(bn) + header, err := ob.GetBlockHeaderCached(bn) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("postBlockHeader: error getting block: %d", bn) return err } - headerRLP, err := rlp.EncodeToBytes(block.Header()) + headerRLP, err := rlp.EncodeToBytes(header) if err != nil { ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("postBlockHeader: error encoding block header: %d", bn) return err @@ -876,8 +914,8 @@ func (ob *EVMChainClient) postBlockHeader(tip uint64) error { _, err = ob.zetaClient.PostAddBlockHeader( ob.chain.ChainId, - block.Hash().Bytes(), - block.Number().Int64(), + header.Hash().Bytes(), + header.Number.Int64(), common.NewEthereumHeader(headerRLP), ) if err != nil { @@ -1159,48 +1197,39 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse } // TODO: we can track the total number of 'getBlockByNumber' RPC calls made - block, err := ob.GetBlockByNumberCached(bn) + block, blockRPC, fallBack, skip, err := ob.GetBlockByNumberCached(bn) if err != nil { + if skip { + ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("observeTssRecvd: skip block %d for chain %d", bn, ob.chain.ChainId) + continue + } ob.logger.ExternalChainWatcher.Error().Err(err).Msgf("observeTssRecvd: error getting block %d for chain %d", bn, ob.chain.ChainId) return bn - 1 // we have to re-scan from this block next time } - for _, tx := range block.Transactions() { - if tx.To() == nil { - continue - } - - if *tx.To() == tssAddress { - receipt, err := ob.evmClient.TransactionReceipt(context.Background(), tx.Hash()) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf( - "observeTssRecvd: TransactionReceipt error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - return bn - 1 // we have to re-scan this block next time - } - if receipt.Status != 1 { // 1: successful, 0: failed - ob.logger.ExternalChainWatcher.Info().Msgf("observeTssRecvd: tx %s chain %d failed; don't act", tx.Hash().Hex(), ob.chain.ChainId) - continue - } - - sender, err := ob.GetTransactionSender(tx, block.Hash(), receipt.TransactionIndex) - if err != nil { - ob.logger.ExternalChainWatcher.Err(err).Msgf( - "observeTssRecvd: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) - return bn - 1 // we have to re-scan this block next time - } - - msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, receipt.BlockNumber.Uint64()) - if msg == nil { - continue + if !fallBack { + for _, tx := range block.Transactions() { + if tx.To() != nil && *tx.To() == tssAddress { + if ok := ob.processIntxToTss(tx, bn, block.Hash()); !ok { + return bn - 1 // we have to re-scan this block next time + } } - zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) - if err != nil { - ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( - "observeTssRecvd: error posting to zeta core for tx %s at height %d for chain %d", tx.Hash().Hex(), bn, ob.chain.ChainId) - return bn - 1 // we have to re-scan this block next time - } else if zetaHash != "" { - ob.logger.ExternalChainWatcher.Info().Msgf( - "observeTssRecvd: gas asset deposit detected in tx %s at height %d for chain %d, PostVoteInbound zeta tx: %s ballot %s", - tx.Hash().Hex(), bn, ob.chain.ChainId, zetaHash, ballot) + } + } else { // fell back on ETH RPC as ethclient failed to parse the block + ob.logger.ExternalChainWatcher.Info().Msgf("observeTssRecvd: processing block %d using fallback for chain %d", bn, ob.chain.ChainId) + for _, txRPC := range blockRPC.Transactions { + if ethcommon.HexToAddress(txRPC.To) == tssAddress { + tx, _, err := ob.evmClient.TransactionByHash(context.Background(), ethcommon.HexToHash(txRPC.Hash)) + if err != nil { + if strings.Contains(err.Error(), "transaction type not supported") { + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "observeTssRecvd: transaction type not supported for tx %s chain %d", txRPC.Hash, ob.chain.ChainId) + continue // skip blob-carrying tx to TSS address + } + return bn - 1 // we have to re-scan this block next time + } + if ok := ob.processIntxToTss(tx, bn, ethcommon.HexToHash(blockRPC.Hash)); !ok { + return bn - 1 // we have to re-scan this block next time + } } } } @@ -1209,6 +1238,48 @@ func (ob *EVMChainClient) observeTssRecvd(startBlock, toBlock uint64, flags obse return toBlock } +// processIntxToTss processes the incoming tx to TSS address and posts to zetacore +// returns true if the tx is successfully processed, false otherwise +func (ob *EVMChainClient) processIntxToTss(tx *ethtypes.Transaction, bn uint64, blockHash ethcommon.Hash) bool { + receipt, err := ob.evmClient.TransactionReceipt(context.Background(), tx.Hash()) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "processIntxToTss: TransactionReceipt error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return false // we have to re-scan this block next time + } + if receipt.Status != 1 { // 1: successful, 0: failed + ob.logger.ExternalChainWatcher.Info().Msgf("processIntxToTss: tx %s chain %d failed; don't act", tx.Hash().Hex(), ob.chain.ChainId) + return true // skip failed tx + } + if bytes.Equal(tx.Data(), []byte(DonationMessage)) { + ob.logger.ExternalChainWatcher.Info().Msgf( + "processIntxToTss: thank you rich folk for your donation!: %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return true // skip donation tx + } + sender, err := ob.GetTransactionSender(tx, blockHash, receipt.TransactionIndex) + if err != nil { + ob.logger.ExternalChainWatcher.Err(err).Msgf( + "processIntxToTss: GetTransactionSender error for tx %s chain %d", tx.Hash().Hex(), ob.chain.ChainId) + return false // we have to re-scan this block next time + } + + msg := ob.GetInboundVoteMsgForTokenSentToTSS(tx, sender, bn) + if msg == nil { + return true // should never happen, always non-nil + } + zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(PostVoteInboundGasLimit, PostVoteInboundExecutionGasLimit, msg) + if err != nil { + ob.logger.ExternalChainWatcher.Error().Err(err).Msgf( + "processIntxToTss: error posting to zeta core for tx %s at height %d for chain %d", tx.Hash().Hex(), bn, ob.chain.ChainId) + return false // we have to re-scan this block next time + } else if zetaHash != "" { + ob.logger.ExternalChainWatcher.Info().Msgf( + "processIntxToTss: gas asset deposit detected in tx %s at height %d for chain %d, PostSend zeta tx: %s ballot %s", + tx.Hash().Hex(), bn, ob.chain.ChainId, zetaHash, ballot) + } + return true +} + func (ob *EVMChainClient) WatchGasPrice() { ob.logger.WatchGasPrice.Info().Msg("WatchGasPrice starting...") err := ob.PostGasPrice() @@ -1411,15 +1482,45 @@ func (ob *EVMChainClient) GetTxID(nonce uint64) string { return fmt.Sprintf("%d-%s-%d", ob.chain.ChainId, tssAddr, nonce) } -func (ob *EVMChainClient) GetBlockByNumberCached(blockNumber uint64) (*ethtypes.Block, error) { - if block, ok := ob.BlockCache.Get(blockNumber); ok { - return block.(*ethtypes.Block), nil +func (ob *EVMChainClient) GetBlockHeaderCached(blockNumber uint64) (*ethtypes.Header, error) { + if header, ok := ob.headerCache.Get(blockNumber); ok { + return header.(*ethtypes.Header), nil } - block, err := ob.evmClient.BlockByNumber(context.Background(), new(big.Int).SetUint64(blockNumber)) + header, err := ob.evmClient.HeaderByNumber(context.Background(), new(big.Int).SetUint64(blockNumber)) if err != nil { return nil, err } - ob.BlockCache.Add(blockNumber, block) - ob.BlockCache.Add(block.Hash(), block) - return block, nil + ob.headerCache.Add(blockNumber, header) + return header, nil +} + +// GetBlockByNumberCached get block by number from cache +// returns block, ethrpc.Block, isFallback, isSkip, error +func (ob *EVMChainClient) GetBlockByNumberCached(blockNumber uint64) (*ethtypes.Block, *ethrpc.Block, bool, bool, error) { + if block, ok := ob.blockCache.Get(blockNumber); ok { + return block.(*ethtypes.Block), nil, false, false, nil + } + if block, ok := ob.blockCacheV3.Get(blockNumber); ok { + return nil, block.(*ethrpc.Block), true, false, nil + } + block, err := ob.evmClient.BlockByNumber(context.Background(), new(big.Int).SetUint64(blockNumber)) + if err != nil { + if strings.Contains(err.Error(), "block header indicates no transactions") { + return nil, nil, false, true, err // it's ok skip empty block + } else if strings.Contains(err.Error(), "transaction type not supported") { + if blockNumber > math.MaxInt32 { + return nil, nil, true, false, fmt.Errorf("block number %d is too large", blockNumber) + } + // #nosec G701 always in range, checked above + rpcBlock, err := ob.evmClientAlternate.EthGetBlockByNumber(int(blockNumber), true) + if err != nil { + return nil, nil, true, false, err // fall back on ethRPC but still fail + } + ob.blockCacheV3.Add(blockNumber, rpcBlock) + return nil, rpcBlock, true, false, nil // fall back on ethRPC without error + } + return nil, nil, false, false, err + } + ob.blockCache.Add(blockNumber, block) + return block, nil, false, false, nil } diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index dd75835024..2bb59a5550 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -32,6 +32,10 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/metrics" ) +const ( + envFlagPostBlame = "POST_BLAME" +) + type TSSKey struct { PubkeyInBytes []byte // FIXME: compressed pubkey? PubkeyInBech32 string // FIXME: same above @@ -200,13 +204,16 @@ func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *common.C if ksRes.Status == thorcommon.Fail { log.Warn().Msgf("keysign status FAIL posting blame to core, blaming node(s): %#v", ksRes.Blame.BlameNodes) - digest := hex.EncodeToString(digest) - index := observertypes.GetBlameIndex(chain.ChainId, nonce, digest, height) - - zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) - if err != nil { - log.Error().Err(err).Msg("error sending blame data to core") - return [65]byte{}, err + // post blame data if enabled + if IsEnvFlagEnabled(envFlagPostBlame) { + digest := hex.EncodeToString(digest) + index := observertypes.GetBlameIndex(chain.ChainId, nonce, digest, height) + zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) + if err != nil { + log.Error().Err(err).Msg("error sending blame data to core") + return [65]byte{}, err + } + log.Info().Msgf("keysign posted blame data tx hash: %s", zetaHash) } // Increment Blame counter @@ -218,8 +225,6 @@ func (tss *TSS) Sign(digest []byte, height uint64, nonce uint64, chain *common.C } counter.Inc() } - - log.Info().Msgf("keysign posted blame data tx hash: %s", zetaHash) } signature := ksRes.Signatures @@ -273,13 +278,17 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, nonce uint64, chain * if ksRes.Status == thorcommon.Fail { log.Warn().Msg("keysign status FAIL posting blame to core") - digest := combineDigests(digestBase64) - index := observertypes.GetBlameIndex(chain.ChainId, nonce, hex.EncodeToString(digest), height) - zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) - if err != nil { - log.Error().Err(err).Msg("error sending blame data to core") - return [][65]byte{}, err + // post blame data if enabled + if IsEnvFlagEnabled(envFlagPostBlame) { + digest := combineDigests(digestBase64) + index := observertypes.GetBlameIndex(chain.ChainId, nonce, hex.EncodeToString(digest), height) + zetaHash, err := tss.CoreBridge.PostBlameData(&ksRes.Blame, chain.ChainId, index) + if err != nil { + log.Error().Err(err).Msg("error sending blame data to core") + return [][65]byte{}, err + } + log.Info().Msgf("keysign posted blame data tx hash: %s", zetaHash) } // Increment Blame counter @@ -291,8 +300,6 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, nonce uint64, chain * } counter.Inc() } - - log.Info().Msgf("keysign posted blame data tx hash: %s", zetaHash) } signatures := ksRes.Signatures diff --git a/zetaclient/utils.go b/zetaclient/utils.go index a886d4e309..06f701a20d 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -9,6 +9,7 @@ import ( "fmt" "math" "math/big" + "os" "strings" "time" @@ -52,6 +53,11 @@ func init() { BtcDepositorFeeMin = DepositorFee(20) // 0.00001360 (20 * 68vB / 100000000), the minimum deposit fee in BTC for 20 sat/byte } +func IsEnvFlagEnabled(flag string) bool { + value := os.Getenv(flag) + return value == "true" || value == "1" +} + func PrettyPrintStruct(val interface{}) (string, error) { prettyStruct, err := json.MarshalIndent( val, From 54b7a927841285550d5831675b8ff4b1928380e6 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:30:19 -0800 Subject: [PATCH 59/67] fix: paying 50% more than base gas price to buffer EIP1559 gas price increase (#1672) * paying 50% more than base gas price to buffer block by block gas price increase * udpate changelog --- changelog.md | 1 + zetaclient/broadcast.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index c37ee97805..d68bff7e2e 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ ### Fixes +* [1672](https://github.com/zeta-chain/node/pull/1672) - paying 50% more than base gas price to buffer EIP1559 gas price increase * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes * [1656](https://github.com/zeta-chain/node/issues/1656) - schedule bitcoin keysign with intervals to avoid keysign failures diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index 97870d3791..a40fc04743 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -25,6 +25,12 @@ const ( DefaultBaseGasPrice = 1_000_000 ) +var ( + // paying 50% more than the current base gas price to buffer for potential block-by-block + // gas price increase due to EIP1559 feemarket on ZetaChain + bufferMultiplier = sdktypes.MustNewDecFromStr("1.5") +) + // Broadcast Broadcasts tx to metachain. Returns txHash and error func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg, authzSigner AuthZSigner) (string, error) { b.broadcastLock.Lock() @@ -44,7 +50,7 @@ func (b *ZetaCoreBridge) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg } reductionRate := sdktypes.MustNewDecFromStr(ante.GasPriceReductionRate) // multiply gas price by the system tx reduction rate - adjustedBaseGasPrice := sdktypes.NewDec(baseGasPrice).Mul(reductionRate) + adjustedBaseGasPrice := sdktypes.NewDec(baseGasPrice).Mul(reductionRate).Mul(bufferMultiplier) if blockHeight > b.blockHeight { b.blockHeight = blockHeight From 6c9afe074b9aacd3dc268815a8e6408a98ff943f Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Tue, 30 Jan 2024 20:04:51 -0800 Subject: [PATCH 60/67] chore: increment handler for v12.2.0 (#1673) Co-authored-by: Tanmay --- app/setup_handlers.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/setup_handlers.go b/app/setup_handlers.go index bdb18a0aa8..0ed66638d1 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -5,10 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/upgrade/types" - observerTypes "github.com/zeta-chain/zetacore/x/observer/types" ) -const releaseVersion = "v12.1.0" +const releaseVersion = "v12.2.0" func SetupHandlers(app *App) { app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm module.VersionMap) (module.VersionMap, error) { @@ -17,7 +16,6 @@ func SetupHandlers(app *App) { for m, mb := range app.mm.Modules { vm[m] = mb.ConsensusVersion() } - vm = VersionMigrator{vm}.TriggerMigration(observerTypes.ModuleName) return app.mm.RunMigrations(ctx, app.configurator, vm) }) From 83568e2ae64f42a19a4c889f6decc6cca7c42527 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:11:11 -0600 Subject: [PATCH 61/67] fix: Trailofbits - make sure block number always increases (#1639) * make sure block number always increases * update changelog * added log prints * update changelog --------- Co-authored-by: Lucas Bertrand --- changelog.md | 1 + zetaclient/bitcoin_client.go | 12 ++++++++---- zetaclient/evm_client.go | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index d68bff7e2e..4ad8ef044f 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ ### Fixes +* [1638](https://github.com/zeta-chain/node/issues/1638) - additional check to make sure external chain height always increases * [1672](https://github.com/zeta-chain/node/pull/1672) - paying 50% more than base gas price to buffer EIP1559 gas price increase * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 * [1610](https://github.com/zeta-chain/node/issues/1610) - add pending outtx hash to tracker after monitoring for 10 minutes diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index d802d2b953..5dee82bdb8 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -372,10 +372,13 @@ func (ob *BitcoinChainClient) observeInTx() error { // get and update latest block height cnt, err := ob.rpcClient.GetBlockCount() if err != nil { - return fmt.Errorf("observeInTxBTC: error getting block count: %s", err) + return fmt.Errorf("observeInTxBTC: error getting block number: %s", err) } if cnt < 0 { - return fmt.Errorf("observeInTxBTC: block count is negative: %d", cnt) + return fmt.Errorf("observeInTxBTC: block number is negative: %d", cnt) + } + if cnt < ob.GetLastBlockHeight() { + return fmt.Errorf("observeInTxBTC: block number should not decrease: current %d last %d", cnt, ob.GetLastBlockHeight()) } ob.SetLastBlockHeight(cnt) @@ -439,7 +442,7 @@ func (ob *BitcoinChainClient) observeInTx() error { ob.logger.WatchInTx.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.WatchInTx.Info().Msgf("observeInTxBTC: BTC deposit detected and reported: PostVoteInbound zeta tx: %s ballot %s", zetaHash, ballot) + ob.logger.WatchInTx.Info().Msgf("observeInTxBTC: PostVoteInbound zeta tx hash: %s inTx %s ballot %s", zetaHash, inTx.TxHash, ballot) } } @@ -633,11 +636,12 @@ func FilterAndParseIncomingTx( } inTx, err := GetBtcEvent(tx, targetAddress, blockNumber, logger, chainID) if err != nil { - logger.Error().Err(err).Msg("error getting btc event") + logger.Error().Err(err).Msgf("FilterAndParseIncomingTx: error getting btc event for tx %s in block %d", tx.Txid, blockNumber) continue } if inTx != nil { inTxs = append(inTxs, inTx) + logger.Info().Msgf("FilterAndParseIncomingTx: found btc event for tx %s in block %d", tx.Txid, blockNumber) } } return inTxs diff --git a/zetaclient/evm_client.go b/zetaclient/evm_client.go index 8d5b78655e..a4cf459c8b 100644 --- a/zetaclient/evm_client.go +++ b/zetaclient/evm_client.go @@ -940,6 +940,9 @@ func (ob *EVMChainClient) observeInTX(sampledLogger zerolog.Logger) error { 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 From 82fb21f87d779284c99e59e45414ad37f6e67886 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 2 Feb 2024 18:41:59 -0500 Subject: [PATCH 62/67] fix: emission params query and add unit tests (#1692) --- changelog.md | 1 + .../msg_server_add_to_outtx_tracker_test.go | 7 +- x/emissions/keeper/params.go | 5 +- x/emissions/keeper/params_test.go | 254 ++++++++++++++++++ x/emissions/types/keys.go | 1 + x/emissions/types/params.go | 40 ++- 6 files changed, 289 insertions(+), 19 deletions(-) create mode 100644 x/emissions/keeper/params_test.go diff --git a/changelog.md b/changelog.md index 4ad8ef044f..ff54b389f9 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ * [1663](https://github.com/zeta-chain/node/issues/1663) - skip Mumbai empty block if ethclient sanity check fails * [1661](https://github.com/zeta-chain/node/issues/1661) - use estimated SegWit tx size for Bitcoin gas fee calculation * [1667](https://github.com/zeta-chain/node/issues/1667) - estimate SegWit tx size in uinit of vByte +* [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module ## Version: v12.1.0 diff --git a/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go b/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go index 72820fcffc..c2ad9d6e7a 100644 --- a/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go +++ b/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go @@ -1,6 +1,3 @@ -//go:build TESTNET -// +build TESTNET - package keeper_test import ( @@ -283,7 +280,7 @@ func setupTssAndNonceToCctx(k *keeper.Keeper, ctx sdk.Context, chainId, nonce in k.GetObserverKeeper().SetTSS(ctx, observerTypes.TSS{ TssPubkey: tssPubKey, }) - k.SetPendingNonces(ctx, types.PendingNonces{ + k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ Tss: tssPubKey, NonceLow: 0, NonceHigh: 1, @@ -297,7 +294,7 @@ func setupTssAndNonceToCctx(k *keeper.Keeper, ctx sdk.Context, chainId, nonce in }, } k.SetCrossChainTx(ctx, cctx) - k.SetNonceToCctx(ctx, types.NonceToCctx{ + k.GetObserverKeeper().SetNonceToCctx(ctx, observertypes.NonceToCctx{ ChainId: chainId, Nonce: nonce, CctxIndex: "0x123", diff --git a/x/emissions/keeper/params.go b/x/emissions/keeper/params.go index 2e93eb1cde..17d506bbca 100644 --- a/x/emissions/keeper/params.go +++ b/x/emissions/keeper/params.go @@ -6,8 +6,9 @@ import ( ) // GetParams get all parameters as types.Params -func (k Keeper) GetParams(_ sdk.Context) types.Params { - return types.NewParams() +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + k.paramstore.GetParamSet(ctx, ¶ms) + return } // SetParams set the params diff --git a/x/emissions/keeper/params_test.go b/x/emissions/keeper/params_test.go new file mode 100644 index 0000000000..159e948a55 --- /dev/null +++ b/x/emissions/keeper/params_test.go @@ -0,0 +1,254 @@ +package keeper_test + +import ( + "testing" + + sdkmath "cosmossdk.io/math" + "github.com/stretchr/testify/assert" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + emissionstypes "github.com/zeta-chain/zetacore/x/emissions/types" +) + +func TestKeeper_GetParams(t *testing.T) { + tests := []struct { + name string + params emissionstypes.Params + isPanic string + }{ + { + name: "Successfully set params", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "", + }, + { + name: "negative observer slashed amount", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(-10), + }, + isPanic: "slash amount cannot be less than 0", + }, + { + name: "MaxBondFactor too high", + params: emissionstypes.Params{ + MaxBondFactor: "1.35", + MinBondFactor: "0.85", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "max bond factor cannot be higher that 0.25", + }, + { + name: "MinBondFactor too low", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.35", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "min bond factor cannot be lower that 0.75", + }, + { + name: "invalid block time", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "invalidTime", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "invalid block time", + }, + { + name: "invalid block time less than 0", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "-2", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "block time cannot be less than or equal to 0", + }, + { + name: "bond ratio too high", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "2.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "target bond ratio cannot be more than 100 percent", + }, + { + name: "bond ratio too low", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "-1.00", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "target bond ratio cannot be less than 0 percent", + }, + { + name: "validator emission percentage too high", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "1.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "validator emission percentage cannot be more than 100 percent", + }, + { + name: "validator emission percentage too low", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "-1.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "validator emission percentage cannot be less than 0 percent", + }, + { + name: "observer percentage too low", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "-00.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "observer emission percentage cannot be less than 0 percent", + }, + { + name: "observer percentage too high", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "150.25", + TssSignerEmissionPercentage: "00.25", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "observer emission percentage cannot be more than 100 percent", + }, + { + name: "tss signer percentage too high", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "102.22", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "tss emission percentage cannot be more than 100 percent", + }, + { + name: "tss signer percentage too loo", + params: emissionstypes.Params{ + MaxBondFactor: "1.25", + MinBondFactor: "0.75", + AvgBlockTime: "6.00", + TargetBondRatio: "00.67", + ValidatorEmissionPercentage: "00.50", + ObserverEmissionPercentage: "00.25", + TssSignerEmissionPercentage: "-102.22", + DurationFactorConstant: "0.001877876953694702", + ObserverSlashAmount: sdkmath.NewInt(100000000000000000), + }, + isPanic: "tss emission percentage cannot be less than 0 percent", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k, ctx := keepertest.EmissionsKeeper(t) + defaultParams := k.GetParams(ctx) + assertPanic(t, func() { + k.SetParams(ctx, tt.params) + }, tt.isPanic) + + if tt.isPanic != "" { + assert.Equal(t, defaultParams, k.GetParams(ctx)) + } else { + assert.Equal(t, tt.params, k.GetParams(ctx)) + } + }) + } +} + +func assertPanic(t *testing.T, f func(), errorLog string) { + defer func() { + r := recover() + if r != nil { + assert.Contains(t, r, errorLog) + } + }() + f() +} diff --git a/x/emissions/types/keys.go b/x/emissions/types/keys.go index 4be2d268b4..9f1fa705fc 100644 --- a/x/emissions/types/keys.go +++ b/x/emissions/types/keys.go @@ -45,6 +45,7 @@ const ( ParamObserverEmissionPercentage = "ObserverEmissionPercentage" ParamTssSignerEmissionPercentage = "SignerEmissionPercentage" ParamDurationFactorConstant = "DurationFactorConstant" + ParamObserverSlashAmount = "ObserverSlashAmount" ) var ( diff --git a/x/emissions/types/params.go b/x/emissions/types/params.go index a61c4ecfea..aa896f77e8 100644 --- a/x/emissions/types/params.go +++ b/x/emissions/types/params.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "strconv" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -49,10 +50,11 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyPrefix(ParamMinBondFactor), &p.MinBondFactor, validateMinBondFactor), paramtypes.NewParamSetPair(KeyPrefix(ParamAvgBlockTime), &p.AvgBlockTime, validateAvgBlockTime), paramtypes.NewParamSetPair(KeyPrefix(ParamTargetBondRatio), &p.TargetBondRatio, validateTargetBondRatio), - paramtypes.NewParamSetPair(KeyPrefix(ParamValidatorEmissionPercentage), &p.ValidatorEmissionPercentage, validateValidatorEmissonPercentage), - paramtypes.NewParamSetPair(KeyPrefix(ParamObserverEmissionPercentage), &p.ObserverEmissionPercentage, validateObserverEmissonPercentage), + paramtypes.NewParamSetPair(KeyPrefix(ParamValidatorEmissionPercentage), &p.ValidatorEmissionPercentage, validateValidatorEmissionPercentage), + paramtypes.NewParamSetPair(KeyPrefix(ParamObserverEmissionPercentage), &p.ObserverEmissionPercentage, validateObserverEmissionPercentage), paramtypes.NewParamSetPair(KeyPrefix(ParamTssSignerEmissionPercentage), &p.TssSignerEmissionPercentage, validateTssEmissonPercentage), paramtypes.NewParamSetPair(KeyPrefix(ParamDurationFactorConstant), &p.DurationFactorConstant, validateDurationFactorConstant), + paramtypes.NewParamSetPair(KeyPrefix(ParamObserverSlashAmount), &p.ObserverSlashAmount, validateObserverSlashAmount), } } @@ -70,6 +72,16 @@ func (p Params) String() string { return string(out) } +func validateObserverSlashAmount(i interface{}) error { + v, ok := i.(sdkmath.Int) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if v.LT(sdk.ZeroInt()) { + return fmt.Errorf("slash amount cannot be less than 0") + } + return nil +} func validateDurationFactorConstant(i interface{}) error { _, ok := i.(string) if !ok { @@ -95,9 +107,6 @@ func validateMinBondFactor(i interface{}) error { if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } decMaxBond := sdk.MustNewDecFromStr(v) if decMaxBond.LT(sdk.MustNewDecFromStr("0.75")) { return fmt.Errorf("min bond factor cannot be lower that 0.75") @@ -106,10 +115,17 @@ func validateMinBondFactor(i interface{}) error { } func validateAvgBlockTime(i interface{}) error { - _, ok := i.(string) + v, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } + blocktime, err := strconv.ParseFloat(v, 64) + if err != nil { + return fmt.Errorf("invalid block time: %T", i) + } + if blocktime <= 0 { + return fmt.Errorf("block time cannot be less than or equal to 0") + } return nil } @@ -119,7 +135,7 @@ func validateTargetBondRatio(i interface{}) error { return fmt.Errorf("invalid parameter type: %T", i) } decMaxBond := sdk.MustNewDecFromStr(v) - if decMaxBond.GT(sdk.MustNewDecFromStr("100.00")) { + if decMaxBond.GT(sdk.OneDec()) { return fmt.Errorf("target bond ratio cannot be more than 100 percent") } if decMaxBond.LT(sdk.ZeroDec()) { @@ -128,13 +144,13 @@ func validateTargetBondRatio(i interface{}) error { return nil } -func validateValidatorEmissonPercentage(i interface{}) error { +func validateValidatorEmissionPercentage(i interface{}) error { v, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } dec := sdk.MustNewDecFromStr(v) - if dec.GT(sdk.MustNewDecFromStr("100.00")) { + if dec.GT(sdk.OneDec()) { return fmt.Errorf("validator emission percentage cannot be more than 100 percent") } if dec.LT(sdk.ZeroDec()) { @@ -143,13 +159,13 @@ func validateValidatorEmissonPercentage(i interface{}) error { return nil } -func validateObserverEmissonPercentage(i interface{}) error { +func validateObserverEmissionPercentage(i interface{}) error { v, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } dec := sdk.MustNewDecFromStr(v) - if dec.GT(sdk.MustNewDecFromStr("100.00")) { + if dec.GT(sdk.OneDec()) { return fmt.Errorf("observer emission percentage cannot be more than 100 percent") } if dec.LT(sdk.ZeroDec()) { @@ -164,7 +180,7 @@ func validateTssEmissonPercentage(i interface{}) error { return fmt.Errorf("invalid parameter type: %T", i) } dec := sdk.MustNewDecFromStr(v) - if dec.GT(sdk.MustNewDecFromStr("100.00")) { + if dec.GT(sdk.OneDec()) { return fmt.Errorf("tss emission percentage cannot be more than 100 percent") } if dec.LT(sdk.ZeroDec()) { From 62e7f7f358c9bfa3f889804af402286a9a8be596 Mon Sep 17 00:00:00 2001 From: kevinssgh <79858682+kevinssgh@users.noreply.github.com> Date: Fri, 2 Feb 2024 19:19:04 -0500 Subject: [PATCH 63/67] feat: TSS and Hotkey password Prompt - develop (#1630) * initial commit * update pr number in changelog --- changelog.md | 3 ++ cmd/zetaclientd/keygen_tss.go | 6 ++- cmd/zetaclientd/start.go | 36 +++++++++++-- cmd/zetaclientd/utils.go | 6 +-- contrib/localnet/scripts/password.file | 2 + .../scripts/start-zetaclientd-background.sh | 17 +++++-- .../scripts/start-zetaclientd-genesis.sh | 4 +- .../scripts/start-zetaclientd-p2p-diag.sh | 4 +- go.mod | 1 + go.sum | 4 ++ zetaclient/broadcast.go | 5 +- zetaclient/keys.go | 51 +++++-------------- zetaclient/keys_test.go | 8 +-- zetaclient/tss_signer.go | 9 ++-- 14 files changed, 90 insertions(+), 66 deletions(-) create mode 100644 contrib/localnet/scripts/password.file diff --git a/changelog.md b/changelog.md index ff54b389f9..6481dd7b36 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,9 @@ # CHANGELOG ## Unreleased +* [1630](https://github.com/zeta-chain/node/pull/1630) added password prompts for hotkey and tss keyshare in zetaclient + Starting zetaclient now requires two passwords to be input; one for the hotkey and another for the tss key-share. +* `zetaclientd start` : 2 inputs required from stdin ### Fixes diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 0b21f880ff..1c77086f59 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -27,7 +27,9 @@ func GenerateTss(logger zerolog.Logger, priKey secp256k1.PrivKey, ts *mc.TelemetryServer, tssHistoricalList []observertypes.TSS, - metrics *metrics.Metrics) (*mc.TSS, error) { + metrics *metrics.Metrics, + tssPassword string, + hotkeyPassword string) (*mc.TSS, error) { keygenLogger := logger.With().Str("module", "keygen").Logger() // Bitcoin chain ID is currently used for using the correct signature format @@ -47,6 +49,8 @@ func GenerateTss(logger zerolog.Logger, tssHistoricalList, metrics, bitcoinChainID, + tssPassword, + hotkeyPassword, ) if err != nil { keygenLogger.Error().Err(err).Msg("NewTSS error") diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index f0528fb9d1..483cab01ee 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "encoding/json" "fmt" "io" @@ -45,6 +46,12 @@ func start(_ *cobra.Command, _ []string) error { SetupConfigForTest() + //Prompt for Hotkey and TSS key-share passwords + hotkeyPass, tssKeyPass, err := promptPasswords() + if err != nil { + return err + } + //Load Config file given path cfg, err := config.Load(rootArgs.zetaCoreHome) if err != nil { @@ -77,7 +84,7 @@ func start(_ *cobra.Command, _ []string) error { // CreateZetaBridge: Zetabridge is used for all communication to zetacore , which this client connects to. // Zetacore accumulates votes , and provides a centralized source of truth for all clients - zetaBridge, err := CreateZetaBridge(cfg, telemetryServer) + zetaBridge, err := CreateZetaBridge(cfg, telemetryServer, hotkeyPass) if err != nil { panic(err) } @@ -120,7 +127,7 @@ func start(_ *cobra.Command, _ []string) error { // The bridgePk is private key for the Hotkey. The Hotkey is used to sign all inbound transactions // Each node processes a portion of the key stored in ~/.tss by default . Custom location can be specified in config file during init. // After generating the key , the address is set on the zetacore - bridgePk, err := zetaBridge.GetKeys().GetPrivateKey() + bridgePk, err := zetaBridge.GetKeys().GetPrivateKey(hotkeyPass) if err != nil { startLogger.Error().Err(err).Msg("zetabridge getPrivateKey error") } @@ -160,7 +167,7 @@ func start(_ *cobra.Command, _ []string) error { } telemetryServer.SetIPAddress(cfg.PublicIP) - tss, err := GenerateTss(masterLogger, cfg, zetaBridge, peers, priKey, telemetryServer, tssHistoricalList, metrics) + tss, err := GenerateTss(masterLogger, cfg, zetaBridge, peers, priKey, telemetryServer, tssHistoricalList, metrics, tssKeyPass, hotkeyPass) if err != nil { return err } @@ -309,3 +316,26 @@ func initPreParams(path string) { } } } + +// promptPasswords() This function will prompt for passwords which will be used to decrypt two key files: +// 1. HotKey +// 2. TSS key-share +func promptPasswords() (string, string, error) { + reader := bufio.NewReader(os.Stdin) + fmt.Print("HotKey Password: ") + hotKeyPass, err := reader.ReadString('\n') + if err != nil { + return "", "", err + } + fmt.Print("TSS Password: ") + TSSKeyPass, err := reader.ReadString('\n') + if err != nil { + return "", "", err + } + + if TSSKeyPass == "" { + return "", "", errors.New("tss password is required to start zetaclient") + } + + return hotKeyPass, TSSKeyPass, err +} diff --git a/cmd/zetaclientd/utils.go b/cmd/zetaclientd/utils.go index 9b17b1ef80..c1a4dfa069 100644 --- a/cmd/zetaclientd/utils.go +++ b/cmd/zetaclientd/utils.go @@ -15,7 +15,7 @@ func CreateAuthzSigner(granter string, grantee sdk.AccAddress) { zetaclient.SetupAuthZSignerList(granter, grantee) } -func CreateZetaBridge(cfg *config.Config, telemetry *zetaclient.TelemetryServer) (*zetaclient.ZetaCoreBridge, error) { +func CreateZetaBridge(cfg *config.Config, telemetry *zetaclient.TelemetryServer, hotkeyPassword string) (*zetaclient.ZetaCoreBridge, error) { hotKey := cfg.AuthzHotkey if cfg.HsmMode { hotKey = cfg.HsmHotKey @@ -23,7 +23,7 @@ func CreateZetaBridge(cfg *config.Config, telemetry *zetaclient.TelemetryServer) chainIP := cfg.ZetaCoreURL - kb, _, err := zetaclient.GetKeyringKeybase(cfg) + kb, _, err := zetaclient.GetKeyringKeybase(cfg, hotkeyPassword) if err != nil { return nil, err } @@ -33,7 +33,7 @@ func CreateZetaBridge(cfg *config.Config, telemetry *zetaclient.TelemetryServer) return nil, err } - k := zetaclient.NewKeysWithKeybase(kb, granterAddreess, cfg.AuthzHotkey) + k := zetaclient.NewKeysWithKeybase(kb, granterAddreess, cfg.AuthzHotkey, hotkeyPassword) bridge, err := zetaclient.NewZetaCoreBridge(k, chainIP, hotKey, cfg.ChainID, cfg.HsmMode, telemetry) if err != nil { diff --git a/contrib/localnet/scripts/password.file b/contrib/localnet/scripts/password.file new file mode 100644 index 0000000000..96b3814661 --- /dev/null +++ b/contrib/localnet/scripts/password.file @@ -0,0 +1,2 @@ +password +pass2 diff --git a/contrib/localnet/scripts/start-zetaclientd-background.sh b/contrib/localnet/scripts/start-zetaclientd-background.sh index 74ee897fdf..c41d13ff58 100644 --- a/contrib/localnet/scripts/start-zetaclientd-background.sh +++ b/contrib/localnet/scripts/start-zetaclientd-background.sh @@ -4,12 +4,19 @@ HOSTNAME=$(hostname) +# read HOTKEY_BACKEND env var for hotkey keyring backend and set default to test +BACKEND="test" +if [ "$HOTKEY_BACKEND" == "file" ]; then + BACKEND="file" +fi + + cp /root/preparams/PreParams_$HOSTNAME.json /root/preParams.json num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" echo "Wait for zetacore to exchange genesis file" -sleep 30 +sleep 40 operator=$(cat $HOME/.zetacored/os.json | jq '.ObserverAddress' ) operatorAddress=$(echo "$operator" | tr -d '"') echo "operatorAddress: $operatorAddress" @@ -18,8 +25,8 @@ if [ $HOSTNAME == "zetaclient0" ] then rm ~/.tss/* MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) - zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" - zetaclientd start > $HOME/zetaclient.log 2>&1 & + zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --keyring-backend "$BACKEND" + zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 & else num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" @@ -30,8 +37,8 @@ else SEED=$(curl --retry 10 --retry-delay 5 --retry-connrefused -s zetaclient0:8123/p2p) done rm ~/.tss/* - zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 0 - zetaclientd start > $HOME/zetaclient.log 2>&1 & + zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" + zetaclientd start < /root/password.file > $HOME/zetaclient.log 2>&1 & fi sleep 3 diff --git a/contrib/localnet/scripts/start-zetaclientd-genesis.sh b/contrib/localnet/scripts/start-zetaclientd-genesis.sh index 5f2cadceab..4716973fc8 100755 --- a/contrib/localnet/scripts/start-zetaclientd-genesis.sh +++ b/contrib/localnet/scripts/start-zetaclientd-genesis.sh @@ -25,7 +25,7 @@ then rm ~/.tss/* MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) zetaclientd init --zetacore-url zetacore0 --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --keyring-backend "$BACKEND" - zetaclientd start + zetaclientd start < /root/password.file else num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" @@ -37,5 +37,5 @@ else done rm ~/.tss/* zetaclientd init --peer /ip4/172.20.0.21/tcp/6668/p2p/"$SEED" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" - zetaclientd start + zetaclientd start < /root/password.file fi diff --git a/contrib/localnet/scripts/start-zetaclientd-p2p-diag.sh b/contrib/localnet/scripts/start-zetaclientd-p2p-diag.sh index a1fc3358f7..310e245878 100644 --- a/contrib/localnet/scripts/start-zetaclientd-p2p-diag.sh +++ b/contrib/localnet/scripts/start-zetaclientd-p2p-diag.sh @@ -17,7 +17,7 @@ then --pre-params ~/preParams.json --zetacore-url zetacore0 \ --chain-id athens_101-1 --dev --operator zeta1z46tdw75jvh4h39y3vu758ctv34rw5z9kmyhgz --log-level 0 --hotkey=val_grantee_observer \ --p2p-diagnostic - zetaclientd start + zetaclientd start < /root/password.file else num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" @@ -29,5 +29,5 @@ else --pre-params ~/preParams.json --zetacore-url $node \ --chain-id athens_101-1 --dev --operator zeta1lz2fqwzjnk6qy48fgj753h48444fxtt7hekp52 --log-level 0 --hotkey=val_grantee_observer \ --p2p-diagnostic - zetaclientd start + zetaclientd start < /root/password.file fi diff --git a/go.mod b/go.mod index 8341c0bddf..95525856ce 100644 --- a/go.mod +++ b/go.mod @@ -338,6 +338,7 @@ replace ( // use cometbft github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.28 github.com/tendermint/tm-db => github.com/BlockPILabs/cosmos-db v0.0.3 + github.com/zeta-chain/go-tss => github.com/zeta-chain/go-tss v0.1.1-0.20240115203400-a5b80e5da933 ) diff --git a/go.sum b/go.sum index be10cf47d8..5ebeddd613 100644 --- a/go.sum +++ b/go.sum @@ -1848,6 +1848,7 @@ github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8 github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= @@ -2760,6 +2761,7 @@ github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34c github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -3035,6 +3037,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zeta-chain/go-tss v0.1.1-0.20240103170132-35850edf5dbd h1:wv+VGLFX8IhPuoqAVQGAQjlEPWqYjowJgJVNReolJTM= github.com/zeta-chain/go-tss v0.1.1-0.20240103170132-35850edf5dbd/go.mod h1:+lJfk/qqt+oxXeVuJV+PzpUoxftUfoTRf2eF3qlbyFI= +github.com/zeta-chain/go-tss v0.1.1-0.20240115203400-a5b80e5da933 h1:cx6ZXVmV9LpkYRQER7+sTgu56wdmaU1U5VJcx3rsCwc= +github.com/zeta-chain/go-tss v0.1.1-0.20240115203400-a5b80e5da933/go.mod h1:+lJfk/qqt+oxXeVuJV+PzpUoxftUfoTRf2eF3qlbyFI= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 h1:gd2uE0X+ZbdFJ8DubxNqLbOVlCB12EgWdzSNRAR82tM= github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2/go.mod h1:x7Bkwbzt2W2lQfjOirnff0Dj+tykdbTG1FMJPVPZsvE= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20230816152528-db7d2bf9144b h1:aZRt5BtXdoDdyrUKwcv3B7mS30m/B854cjKjmnXBE5A= diff --git a/zetaclient/broadcast.go b/zetaclient/broadcast.go index a40fc04743..b46a9c6c8d 100644 --- a/zetaclient/broadcast.go +++ b/zetaclient/broadcast.go @@ -142,10 +142,7 @@ func (b *ZetaCoreBridge) GetContext() (client.Context, error) { } // if password is needed, set it as input - password, err := b.keys.GetHotkeyPassword() - if err != nil { - return ctx, err - } + password := b.keys.GetHotkeyPassword() if password != "" { ctx = ctx.WithInput(strings.NewReader(fmt.Sprintf("%[1]s\n%[1]s\n", password))) } diff --git a/zetaclient/keys.go b/zetaclient/keys.go index 6eae47850f..77f424eac7 100644 --- a/zetaclient/keys.go +++ b/zetaclient/keys.go @@ -2,7 +2,6 @@ package zetaclient import ( "bytes" - "errors" "fmt" "io" "os" @@ -20,22 +19,21 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/config" ) -// HotkeyPasswordEnvVar is the environment variable used to retrieve the password for the hotkey -const HotkeyPasswordEnvVar = "HOTKEY_PASSWORD" - // Keys manages all the keys used by zeta client type Keys struct { signerName string kb ckeys.Keyring OperatorAddress sdk.AccAddress + hotkeyPassword string } // NewKeysWithKeybase create a new instance of Keys -func NewKeysWithKeybase(kb ckeys.Keyring, granterAddress sdk.AccAddress, granteeName string) *Keys { +func NewKeysWithKeybase(kb ckeys.Keyring, granterAddress sdk.AccAddress, granteeName string, hotkeyPassword string) *Keys { return &Keys{ signerName: granteeName, kb: kb, OperatorAddress: granterAddress, + hotkeyPassword: hotkeyPassword, } } @@ -44,7 +42,7 @@ func GetGranteeKeyName(signerName string) string { } // GetKeyringKeybase return keyring and key info -func GetKeyringKeybase(cfg *config.Config) (ckeys.Keyring, string, error) { +func GetKeyringKeybase(cfg *config.Config, hotkeyPassword string) (ckeys.Keyring, string, error) { granteeName := cfg.AuthzHotkey chainHomeFolder := cfg.ZetaCoreHome logger := log.Logger.With().Str("module", "GetKeyringKeybase").Logger() @@ -55,13 +53,9 @@ func GetKeyringKeybase(cfg *config.Config) (ckeys.Keyring, string, error) { // read password from env if using keyring backend file buf := bytes.NewBufferString("") if cfg.KeyringBackend == config.KeyringBackendFile { - password, err := getHotkeyPassword() - if err != nil { - return nil, "", err - } - buf.WriteString(password) + buf.WriteString(hotkeyPassword) buf.WriteByte('\n') // the library used by keyring is using ReadLine , which expect a new line - buf.WriteString(password) + buf.WriteString(hotkeyPassword) buf.WriteByte('\n') } @@ -137,12 +131,7 @@ func (k *Keys) GetAddress() sdk.AccAddress { } // GetPrivateKey return the private key -func (k *Keys) GetPrivateKey() (cryptotypes.PrivKey, error) { - password, err := k.GetHotkeyPassword() - if err != nil { - return nil, err - } - +func (k *Keys) GetPrivateKey(password string) (cryptotypes.PrivKey, error) { signer := GetGranteeKeyName(k.signerName) privKeyArmor, err := k.kb.ExportPrivKeyArmor(signer, password) if err != nil { @@ -160,13 +149,13 @@ func (k *Keys) GetKeybase() ckeys.Keyring { return k.kb } -func (k *Keys) GetPubKeySet() (common.PubKeySet, error) { +func (k *Keys) GetPubKeySet(password string) (common.PubKeySet, error) { pubkeySet := common.PubKeySet{ Secp256k1: "", Ed25519: "", } - pK, err := k.GetPrivateKey() + pK, err := k.GetPrivateKey(password) if err != nil { return pubkeySet, err } @@ -185,25 +174,9 @@ func (k *Keys) GetPubKeySet() (common.PubKeySet, error) { // GetHotkeyPassword returns the password to be used // returns empty if no password is needed -func (k *Keys) GetHotkeyPassword() (string, error) { +func (k *Keys) GetHotkeyPassword() string { if k.GetKeybase().Backend() == ckeys.BackendFile { - return getHotkeyPassword() - } - return "", nil -} - -// getHotkeyPassword retrieves the HOTKEY_PASSWORD environment variable -// and returns an error if it's not defined or shorter than 8 characters. -func getHotkeyPassword() (string, error) { - password := os.Getenv(HotkeyPasswordEnvVar) - - if password == "" { - return "", errors.New("HOTKEY_PASSWORD environment variable is not defined, use --keyring-backend-test to use the test keyring") + return k.hotkeyPassword } - - if len(password) < 8 { - return "", errors.New("HOTKEY_PASSWORD should be at least 8 characters long") - } - - return password, nil + return "" } diff --git a/zetaclient/keys_test.go b/zetaclient/keys_test.go index a2bd2fdcd5..74bb9b970b 100644 --- a/zetaclient/keys_test.go +++ b/zetaclient/keys_test.go @@ -80,7 +80,7 @@ func (ks *KeysSuite) TestGetKeyringKeybase(c *C) { AuthzHotkey: "bob", ZetaCoreHome: "/Users/test/.zetacored/", } - _, _, err := GetKeyringKeybase(cfg) + _, _, err := GetKeyringKeybase(cfg, "") c.Assert(err, NotNil) } @@ -101,15 +101,15 @@ func (ks *KeysSuite) TestNewKeys(c *C) { ZetaCoreHome: folder, } - k, _, err := GetKeyringKeybase(cfg) + k, _, err := GetKeyringKeybase(cfg, "") c.Assert(err, IsNil) c.Assert(k, NotNil) granter := cosmos.AccAddress(crypto.AddressHash([]byte("granter"))) - ki := NewKeysWithKeybase(k, granter, signerNameForTest) + ki := NewKeysWithKeybase(k, granter, signerNameForTest, "") kInfo := ki.GetSignerInfo() c.Assert(kInfo, NotNil) //c.Assert(kInfo.G, Equals, signerNameForTest) - priKey, err := ki.GetPrivateKey() + priKey, err := ki.GetPrivateKey("") c.Assert(err, IsNil) c.Assert(priKey, NotNil) c.Assert(priKey.Bytes(), HasLen, 32) diff --git a/zetaclient/tss_signer.go b/zetaclient/tss_signer.go index 2bb59a5550..c286622d42 100644 --- a/zetaclient/tss_signer.go +++ b/zetaclient/tss_signer.go @@ -87,8 +87,10 @@ func NewTSS( tssHistoricalList []observertypes.TSS, metrics *metrics.Metrics, bitcoinChainID int64, + tssPassword string, + hotkeyPassword string, ) (*TSS, error) { - server, err := SetupTSSServer(peer, privkey, preParams, cfg) + server, err := SetupTSSServer(peer, privkey, preParams, cfg, tssPassword) if err != nil { return nil, fmt.Errorf("SetupTSSServer error: %w", err) } @@ -105,7 +107,7 @@ func NewTSS( if err != nil { return nil, err } - _, pubkeyInBech32, err := GetKeyringKeybase(cfg) + _, pubkeyInBech32, err := GetKeyringKeybase(cfg, hotkeyPassword) if err != nil { return nil, err } @@ -122,7 +124,7 @@ func NewTSS( return &newTss, nil } -func SetupTSSServer(peer p2p.AddrList, privkey tmcrypto.PrivKey, preParams *keygen.LocalPreParams, cfg *config.Config) (*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) @@ -156,6 +158,7 @@ func SetupTSSServer(peer p2p.AddrList, privkey tmcrypto.PrivKey, preParams *keyg }, preParams, // use pre-generated pre-params if non-nil IP, // for docker test + tssPassword, ) if err != nil { log.Error().Err(err).Msg("NewTSS error") From 7572fadaa1d0e617e370dda40ea2293d4f1d7d6d Mon Sep 17 00:00:00 2001 From: blockpinetwork <90677657+blockpinetwork@users.noreply.github.com> Date: Sat, 3 Feb 2024 08:44:46 +0800 Subject: [PATCH 64/67] fix: json-rpc.allow-unprotected-txs (#1691) Co-authored-by: Lucas Bertrand Co-authored-by: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> --- server/config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/config/config.go b/server/config/config.go index 0d2b433c71..20ddf48218 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -347,6 +347,7 @@ func GetConfig(v *viper.Viper) (Config, error) { BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"), HTTPTimeout: v.GetDuration("json-rpc.http-timeout"), HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"), + AllowUnprotectedTxs: v.GetBool("json-rpc.allow-unprotected-txs"), MaxOpenConnections: v.GetInt("json-rpc.max-open-connections"), EnableIndexer: v.GetBool("json-rpc.enable-indexer"), MetricsAddress: v.GetString("json-rpc.metrics-address"), From 7d8665167be392eb37263d3ac5f830879f7d41d5 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Sat, 3 Feb 2024 17:39:22 -0800 Subject: [PATCH 65/67] test(`e2e`): allow to run E2E tests on any networks (#1584) * add new logger functionality * add eth withdraw tests * logger event parsing * simplify logs * add account command * add example config * add cctx wait in deposit tests * bitcoin config * lint * push back Ethereum tests * update config example * add report rendering * goimport * changelog * fix balance calculation and remove accounting * initialize bitcoin balance * remove btc balance * remove cmd/smoketest * change deposit value * some changes for btc * goimport * some tests for balances * fix bitcoin balance code * initialize bitcoin deposit test * some fixes for bitcoin setup * goimports * some renaming * start some work to support zeta out test on testnet * goimports * disable bitcoin balance * add donation test * add readme * replace hardcoded address for zeta in and out * fix erc20 deposit * fix bitcoin deposit for testnet * some renaming * implement list tests command * zeta withdraw * goimport * fix zeta withdraw * fix TestZetaWithdrawBTCRevert * add zeta deposit test * reorganize tests * add some more logs * improve logger concurrency * introduce stress tests * some proposal tests * add more proposal to test * add bitcoin stress tests * deposit stress tests * btc deposit stress tests * make generate * remove legacy get TSS * fix chain ID * fix chain ID --- .gitignore | 6 +- Makefile | 2 +- changelog.md | 5 + cmd/zetae2e/balances.go | 89 ++++++ cmd/zetae2e/bitcoin_address.go | 92 ++++++ cmd/zetae2e/config/clients.go | 35 ++- cmd/zetae2e/config/config.go | 15 +- cmd/zetae2e/config/contracts.go | 22 ++ cmd/zetae2e/config/example.yml | 35 +++ cmd/zetae2e/init.go | 2 +- cmd/zetae2e/list_tests.go | 48 ++++ cmd/zetae2e/local/bitcoin.go | 2 +- cmd/zetae2e/local/erc20.go | 2 +- cmd/zetae2e/local/ethereum.go | 1 + cmd/zetae2e/local/local.go | 4 +- cmd/zetae2e/local/zeta.go | 2 +- cmd/zetae2e/readme.md | 190 +++++++++++++ cmd/zetae2e/root.go | 14 +- cmd/zetae2e/run.go | 40 ++- cmd/zetae2e/show_tss.go | 79 ++++++ cmd/zetae2e/stress.go | 4 +- common/chain.go | 13 + .../smoketest/cmd/smoketest/local/accounts.go | 37 --- .../smoketest/cmd/smoketest/local/admin.go | 76 ----- .../smoketest/cmd/smoketest/local/bitcoin.go | 82 ------ .../smoketest/cmd/smoketest/local/erc20.go | 83 ------ .../smoketest/cmd/smoketest/local/ethereum.go | 75 ----- .../smoketest/cmd/smoketest/local/local.go | 184 ------------ .../smoketest/cmd/smoketest/local/misc.go | 70 ----- .../smoketest/cmd/smoketest/local/utils.go | 264 ------------------ .../smoketest/cmd/smoketest/local/zeta.go | 74 ----- .../smoketest/cmd/smoketest/main.go | 20 -- .../smoketest/cmd/smoketest/root.go | 16 -- .../orchestrator/smoketest/config/config.go | 77 ++++- .../orchestrator/smoketest/runner/balances.go | 195 +++++++++++++ .../orchestrator/smoketest/runner/bitcoin.go | 61 +++- .../orchestrator/smoketest/runner/evm.go | 38 +-- .../orchestrator/smoketest/runner/logger.go | 131 +++++++++ .../orchestrator/smoketest/runner/report.go | 55 ++++ .../orchestrator/smoketest/runner/runner.go | 115 ++++++-- .../smoketest/runner/setup_bitcoin.go | 44 ++- .../smoketest/runner/setup_zeta.go | 80 +++--- .../orchestrator/smoketest/runner/zeta.go | 30 +- .../smoketest/smoketests/smoketests.go | 82 ++++-- .../smoketests/test_bitcoin_deposit.go | 27 ++ ...st_bitcoin.go => test_bitcoin_withdraw.go} | 0 .../smoketests/test_crosschain_swap.go | 2 +- .../smoketest/smoketests/test_donation.go | 25 ++ .../smoketests/test_erc20_deposit.go | 73 +---- .../test_erc20_multiple_deposits.go | 77 +++++ .../test_erc20_multiple_withdraws.go | 78 ++++++ .../smoketest/smoketests/test_erc20_refund.go | 1 + .../smoketests/test_erc20_withdraw.go | 76 +---- ...est_deposit_eth.go => test_eth_deposit.go} | 9 + .../smoketest/smoketests/test_eth_withdraw.go | 46 +++ .../smoketests/test_ether_deposit.go | 7 - .../smoketests/test_message_passing.go | 21 +- .../smoketests/test_stress_btc_deposit.go | 62 ++++ .../smoketests/test_stress_btc_withdraw.go | 73 +++++ .../smoketests/test_stress_eth_deposit.go | 60 ++++ .../smoketests/test_stress_eth_withdraw.go | 69 +++++ .../smoketest/smoketests/test_zeta_deposit.go | 17 ++ .../smoketests/test_zeta_in_and_out.go | 172 ------------ .../smoketests/test_zeta_withdraw.go | 138 +++++++++ .../smoketest/txserver/zeta_tx_server.go | 44 +-- .../orchestrator/smoketest/utils/evm.go | 4 +- .../orchestrator/smoketest/utils/utils.go | 4 +- .../orchestrator/smoketest/utils/zetacore.go | 49 ++-- .../localnet/scripts/gov-proposals-testing.sh | 21 +- .../scripts/proposals/emissions_change.json | 22 ++ .../proposal_for_consensus_params.json | 15 + 71 files changed, 2261 insertions(+), 1522 deletions(-) create mode 100644 cmd/zetae2e/balances.go create mode 100644 cmd/zetae2e/bitcoin_address.go create mode 100644 cmd/zetae2e/config/example.yml create mode 100644 cmd/zetae2e/list_tests.go create mode 100644 cmd/zetae2e/readme.md create mode 100644 cmd/zetae2e/show_tss.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/accounts.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/admin.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/erc20.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/misc.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/zeta.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/main.go delete mode 100644 contrib/localnet/orchestrator/smoketest/cmd/smoketest/root.go create mode 100644 contrib/localnet/orchestrator/smoketest/runner/balances.go create mode 100644 contrib/localnet/orchestrator/smoketest/runner/report.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_deposit.go rename contrib/localnet/orchestrator/smoketest/smoketests/{test_bitcoin.go => test_bitcoin_withdraw.go} (100%) create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_donation.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_deposits.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_withdraws.go rename contrib/localnet/orchestrator/smoketest/smoketests/{test_deposit_eth.go => test_eth_deposit.go} (96%) create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_eth_withdraw.go delete mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_ether_deposit.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_deposit.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_withdraw.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_deposit.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_withdraw.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_deposit.go delete mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_in_and_out.go create mode 100644 contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_withdraw.go create mode 100644 contrib/localnet/scripts/proposals/emissions_change.json create mode 100644 contrib/localnet/scripts/proposals/proposal_for_consensus_params.json diff --git a/.gitignore b/.gitignore index 6a53c9be7b..080a8030b2 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ contrib/meta.pem.pub dispatch_payload.json .github/workflows/local-testing.yml - # Hardhat files cache localnet/artifacts @@ -53,4 +52,7 @@ contrib/localnet/blockscout/services/logs/* contrib/localnet/blockscout/services/redis-data/* contrib/localnet/blockscout/services/stats-db-data/* contrib/localnet/grafana/addresses.txt -contrib/localnet/addresses.txt \ No newline at end of file +contrib/localnet/addresses.txt + +# Config for e2e tests +e2e_conf* \ No newline at end of file diff --git a/Makefile b/Makefile index 2fe0da31cd..946d7a566b 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,7 @@ generate: proto openapi specs typescript docs-zetacored ############################################################################### install-zetae2e: go.sum - @echo "--> Installing orchestrator" + @echo "--> Installing zetae2e" @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetae2e .PHONY: install-zetae2e diff --git a/changelog.md b/changelog.md index 6481dd7b36..5f608c7b2f 100644 --- a/changelog.md +++ b/changelog.md @@ -18,9 +18,14 @@ * [1667](https://github.com/zeta-chain/node/issues/1667) - estimate SegWit tx size in uinit of vByte * [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module +### Tests + +* [1584](https://github.com/zeta-chain/node/pull/1584) - allow to run E2E tests on any networks + ## Version: v12.1.0 ### Tests + * [1577](https://github.com/zeta-chain/node/pull/1577) - add chain header tests in E2E tests and fix admin tests ### Features diff --git a/cmd/zetae2e/balances.go b/cmd/zetae2e/balances.go new file mode 100644 index 0000000000..d1643dab53 --- /dev/null +++ b/cmd/zetae2e/balances.go @@ -0,0 +1,89 @@ +package main + +import ( + "context" + "errors" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/app" + zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" +) + +const flagSkipBTC = "skip-btc" + +// NewBalancesCmd returns the balances command +// which shows from the key and rpc, the balance of the account on different network +func NewBalancesCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "balances [config-file]", + Short: "Show account balances on networks for E2E tests", + RunE: runBalances, + Args: cobra.ExactArgs(1), + } + cmd.Flags().Bool( + flagSkipBTC, + false, + "skip the BTC network", + ) + return cmd +} + +func runBalances(cmd *cobra.Command, args []string) error { + // read the config file + conf, err := config.ReadConfig(args[0]) + if err != nil { + return err + } + + skipBTC, err := cmd.Flags().GetBool(flagSkipBTC) + if err != nil { + return err + } + + // initialize logger + logger := runner.NewLogger(false, color.FgHiCyan, "") + + // set config + app.SetConfig() + + // initialize context + ctx, cancel := context.WithCancel(context.Background()) + + // get EVM address from config + evmAddr := conf.Accounts.EVMAddress + if !ethcommon.IsHexAddress(evmAddr) { + cancel() + return errors.New("invalid EVM address") + } + + // initialize deployer runner with config + r, err := zetae2econfig.RunnerFromConfig( + ctx, + "e2e", + cancel, + conf, + ethcommon.HexToAddress(evmAddr), + conf.Accounts.EVMPrivKey, + utils.FungibleAdminName, // placeholder value, not used + FungibleAdminMnemonic, // placeholder value, not used + logger, + ) + if err != nil { + cancel() + return err + } + + balances, err := r.GetAccountBalances(skipBTC) + if err != nil { + cancel() + return err + } + r.PrintAccountBalances(balances) + + return nil +} diff --git a/cmd/zetae2e/bitcoin_address.go b/cmd/zetae2e/bitcoin_address.go new file mode 100644 index 0000000000..f1728e584b --- /dev/null +++ b/cmd/zetae2e/bitcoin_address.go @@ -0,0 +1,92 @@ +package main + +import ( + "context" + "errors" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/app" + zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" +) + +const flagPrivKey = "privkey" + +// NewBitcoinAddressCmd returns the bitcoin address command +// which shows from the used config file, the bitcoin address that can be used to receive funds for the E2E tests +func NewBitcoinAddressCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "bitcoin-address [config-file] ", + Short: "Show Bitcoin address to receive funds for E2E tests", + RunE: runBitcoinAddress, + Args: cobra.ExactArgs(1), + } + cmd.Flags().Bool( + flagPrivKey, + false, + "show the priv key in WIF format", + ) + return cmd +} + +func runBitcoinAddress(cmd *cobra.Command, args []string) error { + showPrivKey, err := cmd.Flags().GetBool(flagPrivKey) + if err != nil { + return err + } + + // read the config file + conf, err := config.ReadConfig(args[0]) + if err != nil { + return err + } + + // initialize logger + logger := runner.NewLogger(false, color.FgHiYellow, "") + + // set config + app.SetConfig() + + // initialize context + ctx, cancel := context.WithCancel(context.Background()) + + // get EVM address from config + evmAddr := conf.Accounts.EVMAddress + if !ethcommon.IsHexAddress(evmAddr) { + cancel() + return errors.New("invalid EVM address") + } + + // initialize deployer runner with config + r, err := zetae2econfig.RunnerFromConfig( + ctx, + "e2e", + cancel, + conf, + ethcommon.HexToAddress(evmAddr), + conf.Accounts.EVMPrivKey, + utils.FungibleAdminName, // placeholder value, not used + FungibleAdminMnemonic, // placeholder value, not used + logger, + ) + if err != nil { + cancel() + return err + } + + addr, privKey, err := r.GetBtcAddress() + if err != nil { + return err + } + + logger.Print("* BTC address: %s", addr) + if showPrivKey { + logger.Print("* BTC privkey: %s", privKey) + } + + return nil +} diff --git a/cmd/zetae2e/config/clients.go b/cmd/zetae2e/config/clients.go index e3b8fcebc2..99752648e4 100644 --- a/cmd/zetae2e/config/clients.go +++ b/cmd/zetae2e/config/clients.go @@ -2,6 +2,7 @@ package config import ( "context" + "fmt" "google.golang.org/grpc" @@ -33,19 +34,19 @@ func getClientsFromConfig(ctx context.Context, conf config.Config, evmPrivKey st ) { btcRPCClient, err := getBtcClient(conf.RPCs.Bitcoin) if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("failed to get btc client: %w", err) } goerliClient, goerliAuth, err := getEVMClient(ctx, conf.RPCs.EVM, evmPrivKey) if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("failed to get evm client: %w", err) } cctxClient, fungibleClient, authClient, bankClient, observerClient, err := getZetaClients(conf.RPCs.ZetaCoreGRPC) if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("failed to get zeta clients: %w", err) } zevmClient, zevmAuth, err := getEVMClient(ctx, conf.RPCs.Zevm, evmPrivKey) if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("failed to get zevm client: %w", err) } return btcRPCClient, goerliClient, @@ -61,14 +62,26 @@ func getClientsFromConfig(ctx context.Context, conf config.Config, evmPrivKey st } // getBtcClient get btc client -func getBtcClient(rpc string) (*rpcclient.Client, error) { +func getBtcClient(rpcConf config.BitcoinRPC) (*rpcclient.Client, error) { + var param string + switch rpcConf.Params { + case config.Regnet: + case config.Testnet3: + param = "testnet3" + case config.Mainnet: + param = "mainnet" + default: + return nil, fmt.Errorf("invalid bitcoin params %s", rpcConf.Params) + } + connCfg := &rpcclient.ConnConfig{ - Host: rpc, - User: "smoketest", - Pass: "123", - HTTPPostMode: true, - DisableTLS: true, - Params: "testnet3", + Host: rpcConf.Host, + User: rpcConf.User, + Pass: rpcConf.Pass, + HTTPPostMode: rpcConf.HTTPPostMode, + DisableTLS: rpcConf.DisableTLS, + Params: param, + //Endpoint: "/wallet/user", } return rpcclient.New(connCfg, nil) } diff --git a/cmd/zetae2e/config/config.go b/cmd/zetae2e/config/config.go index f307afa02e..d9a4f17edc 100644 --- a/cmd/zetae2e/config/config.go +++ b/cmd/zetae2e/config/config.go @@ -2,6 +2,7 @@ package config import ( "context" + "fmt" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" @@ -34,7 +35,7 @@ func RunnerFromConfig( zevmAuth, err := getClientsFromConfig(ctx, conf, evmUserPrivKey) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get clients from config: %w", err) } // initialize client to send messages to ZetaChain zetaTxServer, err := txserver.NewZetaTxServer( @@ -44,7 +45,7 @@ func RunnerFromConfig( conf.ZetaChainID, ) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to initialize ZetaChain tx server: %w", err) } // initialize smoke test runner @@ -71,6 +72,16 @@ func RunnerFromConfig( // set contracts err = setContractsFromConfig(sm, conf) + if err != nil { + return nil, fmt.Errorf("failed to set contracts from config: %w", err) + } + + // set bitcoin params + chainParams, err := conf.RPCs.Bitcoin.Params.GetParams() + if err != nil { + return nil, fmt.Errorf("failed to get bitcoin params: %w", err) + } + sm.BitcoinParams = &chainParams return sm, err } diff --git a/cmd/zetae2e/config/contracts.go b/cmd/zetae2e/config/contracts.go index c49ce98f8b..0b80d44c4c 100644 --- a/cmd/zetae2e/config/contracts.go +++ b/cmd/zetae2e/config/contracts.go @@ -7,7 +7,9 @@ import ( "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/erc20custody.sol" zetaeth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zeta.eth.sol" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-core/contracts/uniswapv2factory.sol" uniswapv2router "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" @@ -135,6 +137,26 @@ func setContractsFromConfig(r *runner.SmokeTestRunner, conf config.Config) error return err } } + if c := conf.Contracts.ZEVM.ConnectorZEVMAddr; c != "" { + if !ethcommon.IsHexAddress(c) { + return fmt.Errorf("invalid ConnectorZEVMAddr: %s", c) + } + r.ConnectorZEVMAddr = ethcommon.HexToAddress(c) + r.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(r.ConnectorZEVMAddr, r.ZevmClient) + if err != nil { + return err + } + } + if c := conf.Contracts.ZEVM.WZetaAddr; c != "" { + if !ethcommon.IsHexAddress(c) { + return fmt.Errorf("invalid WZetaAddr: %s", c) + } + r.WZetaAddr = ethcommon.HexToAddress(c) + r.WZeta, err = wzeta.NewWETH9(r.WZetaAddr, r.ZevmClient) + if err != nil { + return err + } + } if c := conf.Contracts.ZEVM.ZEVMSwapAppAddr; c != "" { if !ethcommon.IsHexAddress(c) { return fmt.Errorf("invalid ZEVMSwapAppAddr: %s", c) diff --git a/cmd/zetae2e/config/example.yml b/cmd/zetae2e/config/example.yml new file mode 100644 index 0000000000..af38812323 --- /dev/null +++ b/cmd/zetae2e/config/example.yml @@ -0,0 +1,35 @@ +zeta_chain_id: "athens_7001-1" +accounts: + evm_address: "" + evm_priv_key: "" +rpcs: + zevm: ", generally using port 8545" + evm: ", generally using port 8545" + bitcoin: + host: "" + user: "" + pass: "" + http_post_mode: true + disable_tls: true + params: "" + zetacore_grpc: ", generally using port 9090" + zetacore_rpc: ", generally using port 26657" +contracts: + zevm: + system_contract: "0xEdf1c3275d13489aCdC6cD6eD246E72458B8795B" + eth_zrc20: "0x13A0c5930C028511Dc02665E7285134B6d11A5f4" + usdt_zrc20: "0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a" + btc_zrc20: "0x65a45c57636f9BcCeD4fe193A602008578BcA90b" + uniswap_factory: "0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c" + uniswap_router: "0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe" + evm: + zeta_eth: "0x0000c304d2934c00db1d51995b9f6996affd17c0" + connector_eth: "0x00005e3125aba53c5652f9f0ce1a4cf91d8b15ea" + custody: "0x000047f11c6e42293f433c82473532e869ce4ec5" + usdt: "0x07865c6e87b9f70255377e024ace6630c1eaa37f" +test_list: +# - "erc20_deposit" +# - "erc20_withdraw" +# - "eth_deposit" +# - "eth_withdraw" + diff --git a/cmd/zetae2e/init.go b/cmd/zetae2e/init.go index 66d7e4fd3f..eb112c98e2 100644 --- a/cmd/zetae2e/init.go +++ b/cmd/zetae2e/init.go @@ -23,7 +23,7 @@ func NewInitCmd() *cobra.Command { InitCmd.Flags().StringVar(&initConf.RPCs.ZetaCoreGRPC, "grpcURL", "zetacore0:9090", "--grpcURL zetacore0:9090") InitCmd.Flags().StringVar(&initConf.RPCs.ZetaCoreRPC, "rpcURL", "http://zetacore0:26657", "--rpcURL http://zetacore0:26657") InitCmd.Flags().StringVar(&initConf.RPCs.Zevm, "zevmURL", "http://zetacore0:8545", "--zevmURL http://zetacore0:8545") - InitCmd.Flags().StringVar(&initConf.RPCs.Bitcoin, "btcURL", "bitcoin:18443", "--grpcURL bitcoin:18443") + InitCmd.Flags().StringVar(&initConf.RPCs.Bitcoin.Host, "btcURL", "bitcoin:18443", "--grpcURL bitcoin:18443") InitCmd.Flags().StringVar(&initConf.ZetaChainID, "chainID", "athens_101-1", "--chainID athens_101-1") InitCmd.Flags().StringVar(&configFile, local.FlagConfigFile, "smoketest.config", "--cfg ./smoketest.config") diff --git a/cmd/zetae2e/list_tests.go b/cmd/zetae2e/list_tests.go new file mode 100644 index 0000000000..5e23da7090 --- /dev/null +++ b/cmd/zetae2e/list_tests.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" +) + +// NewListTestsCmd returns the list test cmd +// which list the available tests +func NewListTestsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-tests", + Short: "List available tests", + RunE: runListTests, + Args: cobra.NoArgs, + } + return cmd +} + +func runListTests(_ *cobra.Command, _ []string) error { + logger := runner.NewLogger(false, color.FgHiGreen, "") + + logger.Print("Available tests:") + renderTests(logger, smoketests.AllSmokeTests) + + return nil +} + +func renderTests(logger *runner.Logger, tests []runner.SmokeTest) { + // Find the maximum length of the Name field + maxNameLength := 0 + for _, test := range tests { + if len(test.Name) > maxNameLength { + maxNameLength = len(test.Name) + } + } + + // Formatting and printing the table + formatString := fmt.Sprintf("%%-%ds | %%s", maxNameLength) + logger.Print(formatString, "Name", "Description") + for _, test := range tests { + logger.Print(formatString, test.Name, test.Description) + } +} diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index eaf700465e..908b02b13b 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -67,7 +67,7 @@ func bitcoinTestRoutine( if err := bitcoinRunner.RunSmokeTestsFromNames( smoketests.AllSmokeTests, smoketests.TestBitcoinWithdrawName, - smoketests.TestSendZetaOutBTCRevertName, + smoketests.TestZetaWithdrawBTCRevertName, smoketests.TestCrosschainSwapName, ); err != nil { return fmt.Errorf("bitcoin tests failed: %v", err) diff --git a/cmd/zetae2e/local/erc20.go b/cmd/zetae2e/local/erc20.go index 66703121e8..ed82b80308 100644 --- a/cmd/zetae2e/local/erc20.go +++ b/cmd/zetae2e/local/erc20.go @@ -62,7 +62,7 @@ func erc20TestRoutine( // run erc20 test if err := erc20Runner.RunSmokeTestsFromNames( smoketests.AllSmokeTests, - smoketests.TestWithdrawERC20Name, + smoketests.TestERC20WithdrawName, smoketests.TestMultipleWithdrawsName, smoketests.TestERC20DepositAndCallRefundName, smoketests.TestZRC20SwapName, diff --git a/cmd/zetae2e/local/ethereum.go b/cmd/zetae2e/local/ethereum.go index 90d6a35dfb..2b4ffd7eb5 100644 --- a/cmd/zetae2e/local/ethereum.go +++ b/cmd/zetae2e/local/ethereum.go @@ -55,6 +55,7 @@ func ethereumTestRoutine( // to make it faster to catch up with the latest block header if err := ethereumRunner.RunSmokeTestsFromNames( smoketests.AllSmokeTests, + smoketests.TestEtherWithdrawName, smoketests.TestContextUpgradeName, smoketests.TestEtherDepositAndCallName, smoketests.TestDepositAndCallRefundName, diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 92b16526f3..db82a23c85 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -195,7 +195,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } // query and set the TSS - deployerRunner.SetTSSAddresses() + if err := deployerRunner.SetTSSAddresses(); err != nil { + panic(err) + } // setting up the networks if !skipSetup { diff --git a/cmd/zetae2e/local/zeta.go b/cmd/zetae2e/local/zeta.go index cc2bb6dd23..bc0f5a46bc 100644 --- a/cmd/zetae2e/local/zeta.go +++ b/cmd/zetae2e/local/zeta.go @@ -59,7 +59,7 @@ func zetaTestRoutine( // run zeta test if err := zetaRunner.RunSmokeTestsFromNames( smoketests.AllSmokeTests, - smoketests.TestSendZetaOutName, + smoketests.TestZetaWithdrawName, smoketests.TestMessagePassingName, smoketests.TestMessagePassingRevertFailName, smoketests.TestMessagePassingRevertSuccessName, diff --git a/cmd/zetae2e/readme.md b/cmd/zetae2e/readme.md new file mode 100644 index 0000000000..7ef33956e6 --- /dev/null +++ b/cmd/zetae2e/readme.md @@ -0,0 +1,190 @@ +# `zetae2e` + +### Basics + +`zetae2e` is a CLI tool allowing to quickly test ZetaChain functionality. + +`zetae2e` can communicate with ZetaChain, EVM and Bitcoin network to test and track the full workflow of a cross-chain transaction. + +### Getting Started + +`zetae2e` can be installed with the command: + +```go +make install-zetae2e + +zetae2e -h +``` + +### Config + +The command takes a config file as input containing RPC nodes to connect to, hotkey wallet information for interaction with networks, and addresses of the deployed contracts to be used. + +This is an example of config for interaction with Athens3: + +```go +zeta_chain_id: "athens_7001-1" +accounts: + evm_address: "" + evm_priv_key: "" +rpcs: + zevm: ", generally using port 8545" + evm: ", generally using port 8545" + bitcoin: + host: "" + user: "" + pass: "" + http_post_mode: true + disable_tls: true + params: "" + zetacore_grpc: ", generally using port 9090" + zetacore_rpc: ", generally using port 26657" +contracts: + zevm: + system_contract: "0xEdf1c3275d13489aCdC6cD6eD246E72458B8795B" + eth_zrc20: "0x13A0c5930C028511Dc02665E7285134B6d11A5f4" + usdt_zrc20: "0x0cbe0dF132a6c6B4a2974Fa1b7Fb953CF0Cc798a" + btc_zrc20: "0x65a45c57636f9BcCeD4fe193A602008578BcA90b" + uniswap_factory: "0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c" + uniswap_router: "0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe" + evm: + zeta_eth: "0x0000c304d2934c00db1d51995b9f6996affd17c0" + connector_eth: "0x00005e3125aba53c5652f9f0ce1a4cf91d8b15ea" + custody: "0x000047f11c6e42293f433c82473532e869ce4ec5" + usdt: "0x07865c6e87b9f70255377e024ace6630c1eaa37f" +test_list: +# - "erc20_deposit" +# - "erc20_withdraw" +# - "eth_deposit" +# - "eth_withdraw" +``` + +### Bitcoin setup +Interaction with the Bitcoin node will require setting up a specific node tracking the address. It can be set locally following the guide [Using Bitcoin Docker Image for Local Development](https://www.notion.so/Using-Bitcoin-Docker-Image-for-Local-Development-bf7e84c58f22431fb52f17a471997e1f?pvs=21) + +If an error occurs mention that wallets are not loaded. The following commands might need to be run in the Docker container: + +```go +docker exec -it bash + +bitcoin-cli -testnet -rpcuser=${bitcoin_username} -rpcpassword=${bitcoin_password} -named createwallet wallet_name=${WALLET_NAME} disable_private_keys=false load_on_startup=true +bitcoin-cli -testnet -rpcuser=${bitcoin_username} -rpcpassword=${bitcoin_password} importaddress "${WALLET_ADDRESS}" "${WALLET_NAME}" true +bitcoin-cli -testnet -rpcuser=${bitcoin_username} -rpcpassword=${bitcoin_password} importprivkey "your_private_key" "${WALLET_NAME}" false +``` + +### Commands + +Show the balances of the accounts used on the different networks: + +```go +zetae2e balances [config] +``` + +Show the Bitcoin address (the address is derived from the Ethereum private key, this address must therefore be found to perform the Bitcoin test): + +```go +zetae2e bitcoin-address [config] +``` + +The list of tests to be run can be found by running following command: + +```go +zetae2e list-tests +``` + +Run tests: + +```go +zetae2e run [config] --verbose +``` + +Since cctxs might take a longer time to be processed on live networks, it is highly recommended to use `--verbose` flag to see the current status of the cctx workflow. + +### Testing a gas ZRC20 from an EVM chain + +Testing a gas token requires the following values to be defined in the config: + +```go +zeta_chain_id +accounts: + evm_address + evm_priv_key +rpcs: + zevm + evm + zetacore_grpc + zetacore_rpc +contracts: + zevm: + system_contract + eth_zrc20 + uniswap_factory + uniswap_router + evm: + zeta_eth + connector_eth + custody: "0x000047f11c6e42293f433c82473532e869ce4ec5" +test_list: + - "eth_deposit" + - "eth_withdraw" +``` + +One of the tests can be commented out in case only a deposit or a withdrawal is to be tested. +Testing an ERC20 ZRC20 from an EVM chain + +Testing ZRC20 requires the same config as for the gas tokens, but must include the `usdt` field that contains the address of the ERC20 on the evm chain and `usdt_zrc20` on ZetaChain. + +It is currently named USDT because it was the defacto ERC20 tested in local tests, this field will be renamed into a more generic name in the future + +```go +zeta_chain_id +accounts: + evm_address + evm_priv_key +rpcs: + zevm + evm + zetacore_grpc + zetacore_rpc +contracts: + zevm: + usdt_zrc20 + evm: + usdt +test_list: + - "erc20_deposit" + - "erc20_withdraw" +``` + +### Testing a ZRC20 from a Bitcoin chain + +The following values must be set in the config in order to test Bitcoin functionality + +```go +zeta_chain_id +accounts: + evm_address + evm_priv_key +rpcs: + zevm + bitcoin: + host + user + pass + http_post_mode + disable_tls + params + zetacore_grpc + zetacore_rpc +contracts: + zevm: + system_contract + btc_zrc20 + uniswap_factory + uniswap_router +test_list: + - "bitcoin_deposit" + - "bitcoin_withdraw" +``` + +### TODO: message passing \ No newline at end of file diff --git a/cmd/zetae2e/root.go b/cmd/zetae2e/root.go index fb93caa131..ba82430a45 100644 --- a/cmd/zetae2e/root.go +++ b/cmd/zetae2e/root.go @@ -5,13 +5,25 @@ import ( "github.com/zeta-chain/zetacore/cmd/zetae2e/local" ) +var asciiArt = ` + _ ____ + _______| |_ __ _ ___|___ \ ___ +|_ / _ \ __/ _ |/ _ \ __) / _ \ + / / __/ || (_| | __// __/ __/ +/___\___|\__\__,_|\___|_____\___| +` + func NewRootCmd() *cobra.Command { cmd := &cobra.Command{ Use: "zetae2e", - Short: "E2E tests CLI", + Short: asciiArt, } cmd.AddCommand( NewRunCmd(), + NewBalancesCmd(), + NewBitcoinAddressCmd(), + NewListTestsCmd(), + NewShowTSSCmd(), local.NewLocalCmd(), NewStressTestCmd(), NewInitCmd(), diff --git a/cmd/zetae2e/run.go b/cmd/zetae2e/run.go index 9b1945d88e..6f98e78da6 100644 --- a/cmd/zetae2e/run.go +++ b/cmd/zetae2e/run.go @@ -52,7 +52,7 @@ func runE2ETest(cmd *cobra.Command, args []string) error { } // initialize logger - logger := runner.NewLogger(verbose, color.FgWhite, "e2e") + logger := runner.NewLogger(verbose, color.FgHiCyan, "e2e") // set config app.SetConfig() @@ -62,7 +62,7 @@ func runE2ETest(cmd *cobra.Command, args []string) error { // get EVM address from config evmAddr := conf.Accounts.EVMAddress - if ethcommon.IsHexAddress(evmAddr) { + if !ethcommon.IsHexAddress(evmAddr) { cancel() return errors.New("invalid EVM address") } @@ -75,8 +75,8 @@ func runE2ETest(cmd *cobra.Command, args []string) error { conf, ethcommon.HexToAddress(evmAddr), conf.Accounts.EVMPrivKey, - utils.FungibleAdminName, - FungibleAdminMnemonic, + utils.FungibleAdminName, // placeholder value, not used + FungibleAdminMnemonic, // placeholder value, not used logger, ) if err != nil { @@ -88,18 +88,42 @@ func runE2ETest(cmd *cobra.Command, args []string) error { logger.Print("starting tests") // fetch the TSS address - testRunner.SetTSSAddresses() + if err := testRunner.SetTSSAddresses(); err != nil { + return err + } + + // set timeout + testRunner.CctxTimeout = 60 * time.Minute + testRunner.ReceiptTimeout = 60 * time.Minute + + balancesBefore, err := testRunner.GetAccountBalances(true) + if err != nil { + cancel() + return err + } - // run tests - if err := testRunner.RunSmokeTestsFromNames( + //run tests + reports, err := testRunner.RunSmokeTestsFromNamesIntoReport( smoketests.AllSmokeTests, conf.TestList..., - ); err != nil { + ) + if err != nil { + cancel() + return err + } + + balancesAfter, err := testRunner.GetAccountBalances(true) + if err != nil { cancel() return err } + // Print tests completion info logger.Print("tests finished successfully in %s", time.Since(testStartTime).String()) + testRunner.Logger.SetColor(color.FgHiRed) + testRunner.PrintTotalDiff(runner.GetAccountBalancesDiff(balancesBefore, balancesAfter)) + testRunner.Logger.SetColor(color.FgHiGreen) + testRunner.PrintTestReports(reports) return nil } diff --git a/cmd/zetae2e/show_tss.go b/cmd/zetae2e/show_tss.go new file mode 100644 index 0000000000..84938396e3 --- /dev/null +++ b/cmd/zetae2e/show_tss.go @@ -0,0 +1,79 @@ +package main + +import ( + "context" + "errors" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/zeta-chain/zetacore/app" + zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" +) + +// NewShowTSSCmd returns the show TSS command +// which shows the TSS address in the network +func NewShowTSSCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "show-tss [config]", + Short: "Show address of the TSS", + RunE: runShowTSS, + Args: cobra.ExactArgs(1), + } + return cmd +} + +func runShowTSS(_ *cobra.Command, args []string) error { + // read the config file + conf, err := config.ReadConfig(args[0]) + if err != nil { + return err + } + + // initialize logger + logger := runner.NewLogger(true, color.FgHiCyan, "") + + // set config + app.SetConfig() + + // initialize context + ctx, cancel := context.WithCancel(context.Background()) + + // get EVM address from config + evmAddr := conf.Accounts.EVMAddress + if !ethcommon.IsHexAddress(evmAddr) { + cancel() + return errors.New("invalid EVM address") + } + + // initialize deployer runner with config + testRunner, err := zetae2econfig.RunnerFromConfig( + ctx, + "tss", + cancel, + conf, + ethcommon.HexToAddress(evmAddr), + conf.Accounts.EVMPrivKey, + utils.FungibleAdminName, // placeholder value, not used + FungibleAdminMnemonic, // placeholder value, not used + logger, + ) + if err != nil { + cancel() + return err + } + + // fetch the TSS address + if err := testRunner.SetTSSAddresses(); err != nil { + return err + } + + // print the TSS address + logger.Info("TSS EVM address: %s\n", testRunner.TSSAddress.Hex()) + logger.Info("TSS BTC address: %s\n", testRunner.BTCTSSAddress.EncodeAddress()) + + return nil +} diff --git a/cmd/zetae2e/stress.go b/cmd/zetae2e/stress.go index 26a2169b95..1ef3dc6410 100644 --- a/cmd/zetae2e/stress.go +++ b/cmd/zetae2e/stress.go @@ -152,7 +152,9 @@ func StressTest(cmd *cobra.Command, _ []string) { } // setup TSS addresses - smokeTest.SetTSSAddresses() + if err := smokeTest.SetTSSAddresses(); err != nil { + panic(err) + } smokeTest.SetupEVM(stressTestArgs.contractsDeployed) diff --git a/common/chain.go b/common/chain.go index cc3dde3722..303e3a238e 100644 --- a/common/chain.go +++ b/common/chain.go @@ -199,6 +199,19 @@ func GetBTCChainParams(chainID int64) (*chaincfg.Params, error) { } } +func GetBTCChainIDFromChainParams(params *chaincfg.Params) (int64, error) { + switch params.Name { + case chaincfg.RegressionNetParams.Name: + return 18444, nil + case chaincfg.TestNet3Params.Name: + return 18332, nil + case chaincfg.MainNetParams.Name: + return 8332, nil + default: + return 0, fmt.Errorf("error chain %s is not a Bitcoin chain", params.Name) + } +} + // InChainList checks whether the chain is in the chain list func (chain Chain) InChainList(chainList []*Chain) bool { return ChainIDInChainList(chain.ChainId, chainList) diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/accounts.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/accounts.go deleted file mode 100644 index f179e02859..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/accounts.go +++ /dev/null @@ -1,37 +0,0 @@ -package local - -import ( - ethcommon "github.com/ethereum/go-ethereum/common" -) - -var ( - // DeployerAddress is the address of the account for deploying networks - DeployerAddress = ethcommon.HexToAddress("0xE5C5367B8224807Ac2207d350E60e1b6F27a7ecC") - DeployerPrivateKey = "d87baf7bf6dc560a252596678c12e41f7d1682837f05b29d411bc3f78ae2c263" // #nosec G101 - used for testing - - // UserERC20Address is the address of the account for testing ERC20 - UserERC20Address = ethcommon.HexToAddress("0x6F57D5E7c6DBb75e59F1524a3dE38Fc389ec5Fd6") - UserERC20PrivateKey = "fda3be1b1517bdf48615bdadacc1e6463d2865868dc8077d2cdcfa4709a16894" // #nosec G101 - used for testing - - // UserZetaTestAddress is the address of the account for testing Zeta - UserZetaTestAddress = ethcommon.HexToAddress("0x5cC2fBb200A929B372e3016F1925DcF988E081fd") - UserZetaTestPrivateKey = "729a6cdc5c925242e7df92fdeeb94dadbf2d0b9950d4db8f034ab27a3b114ba7" // #nosec G101 - used for testing - - // UserBitcoinAddress is the address of the account for testing Bitcoin - UserBitcoinAddress = ethcommon.HexToAddress("0x283d810090EdF4043E75247eAeBcE848806237fD") - UserBitcoinPrivateKey = "7bb523963ee2c78570fb6113d886a4184d42565e8847f1cb639f5f5e2ef5b37a" // #nosec G101 - used for testing - - // UserEtherAddress is the address of the account for testing Ether - UserEtherAddress = ethcommon.HexToAddress("0x8D47Db7390AC4D3D449Cc20D799ce4748F97619A") - UserEtherPrivateKey = "098e74a1c2261fa3c1b8cfca8ef2b4ff96c73ce36710d208d1f6535aef42545d" // #nosec G101 - used for testing - - // UserMiscAddress is the address of the account for miscellaneous tests - UserMiscAddress = ethcommon.HexToAddress("0x90126d02E41c9eB2a10cfc43aAb3BD3460523Cdf") - UserMiscPrivateKey = "853c0945b8035a501b1161df65a17a0a20fc848bda8975a8b4e9222cc6f84cd4" // #nosec G101 - used for testing - - // UserAdminAddress is the address of the account for testing admin function features - UserAdminAddress = ethcommon.HexToAddress("0xcC8487562AAc220ea4406196Ee902C7c076966af") - UserAdminPrivateKey = "95409f1f0e974871cc26ba98ffd31f613aa1287d40c0aea6a87475fc3521d083" // #nosec G101 - used for testing - - FungibleAdminMnemonic = "snow grace federal cupboard arrive fancy gym lady uniform rotate exercise either leave alien grass" // #nosec G101 - used for testing -) diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/admin.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/admin.go deleted file mode 100644 index bafc639033..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/admin.go +++ /dev/null @@ -1,76 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// adminTestRoutine runs admin functions smoke tests -func adminTestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for erc20 advanced test - adminRunner, err := initTestRunner( - "admin", - conf, - deployerRunner, - UserAdminAddress, - UserAdminPrivateKey, - runner.NewLogger(verbose, color.FgGreen, "admin"), - ) - if err != nil { - return err - } - - adminRunner.Logger.Print("🏃 starting admin tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 1000) - txUSDTSend := deployerRunner.SendUSDTOnEvm(UserAdminAddress, 1000) - adminRunner.WaitForTxReceiptOnEvm(txZetaSend) - adminRunner.WaitForTxReceiptOnEvm(txUSDTSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := adminRunner.DepositZeta() - txEtherDeposit := adminRunner.DepositEther(false) - txERC20Deposit := adminRunner.DepositERC20() - adminRunner.WaitForMinedCCTX(txZetaDeposit) - adminRunner.WaitForMinedCCTX(txEtherDeposit) - adminRunner.WaitForMinedCCTX(txERC20Deposit) - - // run erc20 advanced test - if err := adminRunner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - smoketests.TestPauseZRC20Name, - smoketests.TestUpdateBytecodeName, - smoketests.TestDepositEtherLiquidityCapName, - ); err != nil { - return fmt.Errorf("admim tests failed: %v", err) - } - - adminRunner.Logger.Print("🍾 admin tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go deleted file mode 100644 index f791e1c29b..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/bitcoin.go +++ /dev/null @@ -1,82 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// bitcoinTestRoutine runs Bitcoin related smoke tests -func bitcoinTestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the smoke tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("bitcoin panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for bitcoin test - bitcoinRunner, err := initTestRunner( - "bitcoin", - conf, - deployerRunner, - UserBitcoinAddress, - UserBitcoinPrivateKey, - runner.NewLogger(verbose, color.FgYellow, "bitcoin"), - ) - if err != nil { - return err - } - - bitcoinRunner.Logger.Print("🏃 starting Bitcoin tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserBitcoinAddress, 1000) - txUSDTSend := deployerRunner.SendUSDTOnEvm(UserBitcoinAddress, 1000) - - bitcoinRunner.WaitForTxReceiptOnEvm(txZetaSend) - bitcoinRunner.WaitForTxReceiptOnEvm(txUSDTSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := bitcoinRunner.DepositZeta() - txEtherDeposit := bitcoinRunner.DepositEther(false) - txERC20Deposit := bitcoinRunner.DepositERC20() - bitcoinRunner.SetupBitcoinAccount(true) - bitcoinRunner.DepositBTC(true) - bitcoinRunner.WaitForMinedCCTX(txZetaDeposit) - bitcoinRunner.WaitForMinedCCTX(txEtherDeposit) - bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) - - // run bitcoin test - // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first - // to make it faster to catch up with the latest block header - if err := bitcoinRunner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - smoketests.TestBitcoinWithdrawName, - smoketests.TestSendZetaOutBTCRevertName, - smoketests.TestCrosschainSwapName, - ); err != nil { - return fmt.Errorf("bitcoin tests failed: %v", err) - } - - bitcoinRunner.Logger.Print("🍾 Bitcoin tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/erc20.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/erc20.go deleted file mode 100644 index 18449301ef..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/erc20.go +++ /dev/null @@ -1,83 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// erc20TestRoutine runs erc20 related smoke tests -func erc20TestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the smoke tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("erc20 panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for erc20 test - erc20Runner, err := initTestRunner( - "erc20", - conf, - deployerRunner, - UserERC20Address, - UserERC20PrivateKey, - runner.NewLogger(verbose, color.FgGreen, "erc20"), - ) - if err != nil { - return err - } - - erc20Runner.Logger.Print("🏃 starting erc20 tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserERC20Address, 1000) - txUSDTSend := deployerRunner.SendUSDTOnEvm(UserERC20Address, 10) - - erc20Runner.WaitForTxReceiptOnEvm(txZetaSend) - erc20Runner.WaitForTxReceiptOnEvm(txUSDTSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := erc20Runner.DepositZeta() - txEtherDeposit := erc20Runner.DepositEther(false) - txERC20Deposit := erc20Runner.DepositERC20() - erc20Runner.WaitForMinedCCTX(txZetaDeposit) - erc20Runner.WaitForMinedCCTX(txEtherDeposit) - erc20Runner.WaitForMinedCCTX(txERC20Deposit) - - //erc20Runner.SetupBitcoinAccount() - //erc20Runner.DepositBTC() - - // run erc20 test - if err := erc20Runner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - smoketests.TestMultipleERC20DepositName, - smoketests.TestWithdrawERC20Name, - smoketests.TestMultipleWithdrawsName, - smoketests.TestERC20DepositAndCallRefundName, - smoketests.TestZRC20SwapName, - ); err != nil { - return fmt.Errorf("erc20 tests failed: %v", err) - } - - erc20Runner.Logger.Print("🍾 erc20 tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go deleted file mode 100644 index 7f2eae6792..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/ethereum.go +++ /dev/null @@ -1,75 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// ethereumTestRoutine runs Ethereum related smoke tests -func ethereumTestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the smoke tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("ethereum panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for ether test - ethereumRunner, err := initTestRunner( - "ether", - conf, - deployerRunner, - UserEtherAddress, - UserEtherPrivateKey, - runner.NewLogger(verbose, color.FgMagenta, "ether"), - ) - if err != nil { - return err - } - - ethereumRunner.Logger.Print("🏃 starting Ethereum tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserEtherAddress, 1000) - ethereumRunner.WaitForTxReceiptOnEvm(txZetaSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := ethereumRunner.DepositZeta() - txEtherDeposit := ethereumRunner.DepositEther(true) - ethereumRunner.WaitForMinedCCTX(txZetaDeposit) - ethereumRunner.WaitForMinedCCTX(txEtherDeposit) - - // run ethereum test - // Note: due to the extensive block generation in Ethereum localnet, block header test is run first - // to make it faster to catch up with the latest block header - if err := ethereumRunner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - smoketests.TestContextUpgradeName, - smoketests.TestEtherDepositAndCallName, - smoketests.TestDepositAndCallRefundName, - ); err != nil { - return fmt.Errorf("ethereum tests failed: %v", err) - } - - ethereumRunner.Logger.Print("🍾 Ethereum tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go deleted file mode 100644 index 170e8a644c..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/local.go +++ /dev/null @@ -1,184 +0,0 @@ -package local - -import ( - "context" - "os" - "time" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" - "golang.org/x/sync/errgroup" -) - -const ( - flagContractsDeployed = "deployed" - flagWaitForHeight = "wait-for" - flagConfigFile = "config" - flagVerbose = "verbose" - flagTestAdmin = "test-admin" - flagTestCustom = "test-custom" - flagSkipRegular = "skip-regular" -) - -var ( - SmokeTestTimeout = 30 * time.Minute -) - -// NewLocalCmd returns the local command -// which runs the smoketest locally on the machine with localnet for each blockchain -func NewLocalCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "local", - Short: "Run Local Smoketest", - Run: localSmokeTest, - } - cmd.Flags().Bool( - flagContractsDeployed, - false, - "set to to true if running smoketest again with existing state", - ) - cmd.Flags().Int64( - flagWaitForHeight, - 0, - "block height for smoketest to begin, ex. --wait-for 100", - ) - cmd.Flags().String( - flagConfigFile, - "", - "config file to use for the smoketest", - ) - cmd.Flags().Bool( - flagVerbose, - false, - "set to true to enable verbose logging", - ) - cmd.Flags().Bool( - flagTestAdmin, - false, - "set to true to run admin tests", - ) - cmd.Flags().Bool( - flagTestCustom, - false, - "set to true to run custom tests", - ) - cmd.Flags().Bool( - flagSkipRegular, - false, - "set to true to skip regular tests", - ) - - return cmd -} - -func localSmokeTest(cmd *cobra.Command, _ []string) { - // fetch flags - waitForHeight, err := cmd.Flags().GetInt64(flagWaitForHeight) - if err != nil { - panic(err) - } - contractsDeployed, err := cmd.Flags().GetBool(flagContractsDeployed) - if err != nil { - panic(err) - } - verbose, err := cmd.Flags().GetBool(flagVerbose) - if err != nil { - panic(err) - } - logger := runner.NewLogger(verbose, color.FgWhite, "setup") - testAdmin, err := cmd.Flags().GetBool(flagTestAdmin) - if err != nil { - panic(err) - } - testCustom, err := cmd.Flags().GetBool(flagTestCustom) - if err != nil { - panic(err) - } - skipRegular, err := cmd.Flags().GetBool(flagSkipRegular) - if err != nil { - panic(err) - } - - testStartTime := time.Now() - logger.Print("starting smoke tests") - - // start timer - go func() { - time.Sleep(SmokeTestTimeout) - logger.Error("Smoke test timed out after %s", SmokeTestTimeout.String()) - os.Exit(1) - }() - - // initialize smoke tests config - conf, err := GetConfig(cmd) - if err != nil { - panic(err) - } - - // initialize context - ctx, cancel := context.WithCancel(context.Background()) - - // wait for a specific height on ZetaChain - if waitForHeight != 0 { - utils.WaitForBlockHeight(ctx, waitForHeight, conf.RPCs.ZetaCoreRPC, logger) - } - - // set account prefix to zeta - setCosmosConfig() - - // wait for Genesis - logger.Print("⏳ wait 70s for genesis") - time.Sleep(70 * time.Second) - - // initialize deployer runner with config - deployerRunner, err := runnerFromConfig( - ctx, - "deployer", - cancel, - conf, - DeployerAddress, - DeployerPrivateKey, - logger, - ) - if err != nil { - panic(err) - } - - // wait for keygen to be completed - waitKeygenHeight(ctx, deployerRunner.CctxClient, logger) - - // setting up the networks - logger.Print("⚙️ setting up networks") - startTime := time.Now() - deployerRunner.SetTSSAddresses() - deployerRunner.SetupEVM(contractsDeployed) - deployerRunner.SetZEVMContracts() - deployerRunner.MintUSDTOnEvm(10000) - logger.Print("✅ setup completed in %s", time.Since(startTime)) - - // run tests - var eg errgroup.Group - if !skipRegular { - eg.Go(erc20TestRoutine(conf, deployerRunner, verbose)) - eg.Go(zetaTestRoutine(conf, deployerRunner, verbose)) - eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose)) - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose)) - } - if testAdmin { - eg.Go(adminTestRoutine(conf, deployerRunner, verbose)) - } - if testCustom { - eg.Go(miscTestRoutine(conf, deployerRunner, verbose)) - } - - if err := eg.Wait(); err != nil { - deployerRunner.CtxCancel() - logger.Print("❌ %v", err) - logger.Print("❌ smoke tests failed after %s", time.Since(testStartTime).String()) - os.Exit(1) - } - - logger.Print("✅ smoke tests completed in %s", time.Since(testStartTime).String()) -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/misc.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/misc.go deleted file mode 100644 index a8f316c7a2..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/misc.go +++ /dev/null @@ -1,70 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// miscTestRoutine runs miscellaneous smoke tests -func miscTestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the smoke tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("misc panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for misc test - miscRunner, err := initTestRunner( - "misc", - conf, - deployerRunner, - UserMiscAddress, - UserMiscPrivateKey, - runner.NewLogger(verbose, color.FgCyan, "misc"), - ) - if err != nil { - return err - } - - miscRunner.Logger.Print("🏃 starting miscellaneous tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserMiscAddress, 1000) - miscRunner.WaitForTxReceiptOnEvm(txZetaSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := miscRunner.DepositZeta() - miscRunner.WaitForMinedCCTX(txZetaDeposit) - - // run misc test - if err := miscRunner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - //smoketests.TestBlockHeadersName, - smoketests.TestMyTestName, - ); err != nil { - return fmt.Errorf("misc tests failed: %v", err) - } - - miscRunner.Logger.Print("🍾 miscellaneous tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go deleted file mode 100644 index 3cc27582dc..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/utils.go +++ /dev/null @@ -1,264 +0,0 @@ -package local - -import ( - "context" - "time" - - "github.com/btcsuite/btcd/rpcclient" - 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/ethereum/go-ethereum/accounts/abi/bind" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/app" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/txserver" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" - "google.golang.org/grpc" -) - -// GetConfig returns config from file from the command line flag -func GetConfig(cmd *cobra.Command) (config.Config, error) { - configFile, err := cmd.Flags().GetString(flagConfigFile) - if err != nil { - return config.Config{}, err - } - - // use default config if no config file is specified - if configFile == "" { - return config.DefaultConfig(), nil - } - - return config.ReadConfig(configFile) -} - -// setCosmosConfig set account prefix to zeta -func setCosmosConfig() { - cosmosConf := sdk.GetConfig() - cosmosConf.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) - cosmosConf.Seal() -} - -// initTestRunner initializes a runner for smoke tests -// it creates a runner with an account and copy contracts from deployer runner -func initTestRunner( - name string, - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - userAddress ethcommon.Address, - userPrivKey string, - logger *runner.Logger, -) (*runner.SmokeTestRunner, error) { - // initialize runner for smoke test - testRunner, err := runnerFromConfig( - deployerRunner.Ctx, - name, - deployerRunner.CtxCancel, - conf, - userAddress, - userPrivKey, - logger, - ) - if err != nil { - return nil, err - } - - // copy contracts from deployer runner - if err := testRunner.CopyAddressesFrom(deployerRunner); err != nil { - return nil, err - } - - return testRunner, nil -} - -// runnerFromConfig create test runner from config -func runnerFromConfig( - ctx context.Context, - name string, - ctxCancel context.CancelFunc, - conf config.Config, - userAddr ethcommon.Address, - userPrivKey string, - logger *runner.Logger, -) (*runner.SmokeTestRunner, error) { - // initialize clients - btcRPCClient, - goerliClient, - goerliAuth, - cctxClient, - fungibleClient, - authClient, - bankClient, - observerClient, - zevmClient, - zevmAuth, - err := getClientsFromConfig(ctx, conf, userPrivKey) - if err != nil { - return nil, err - } - // initialize client to send messages to ZetaChain - zetaTxServer, err := txserver.NewZetaTxServer( - conf.RPCs.ZetaCoreRPC, - []string{utils.FungibleAdminName}, - []string{FungibleAdminMnemonic}, - conf.ZetaChainID, - ) - if err != nil { - return nil, err - } - - // initialize smoke test runner - sm := runner.NewSmokeTestRunner( - ctx, - name, - ctxCancel, - userAddr, - userPrivKey, - FungibleAdminMnemonic, - goerliClient, - zevmClient, - cctxClient, - zetaTxServer, - fungibleClient, - authClient, - bankClient, - observerClient, - goerliAuth, - zevmAuth, - btcRPCClient, - logger, - ) - return sm, nil -} - -// getClientsFromConfig get clients from config -func getClientsFromConfig(ctx context.Context, conf config.Config, evmPrivKey string) ( - *rpcclient.Client, - *ethclient.Client, - *bind.TransactOpts, - crosschaintypes.QueryClient, - fungibletypes.QueryClient, - authtypes.QueryClient, - banktypes.QueryClient, - observertypes.QueryClient, - *ethclient.Client, - *bind.TransactOpts, - error, -) { - btcRPCClient, err := getBtcClient(conf.RPCs.Bitcoin) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err - } - goerliClient, goerliAuth, err := getEVMClient(ctx, conf.RPCs.EVM, evmPrivKey) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err - } - cctxClient, fungibleClient, authClient, bankClient, observerClient, err := getZetaClients(conf.RPCs.ZetaCoreGRPC) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err - } - zevmClient, zevmAuth, err := getEVMClient(ctx, conf.RPCs.Zevm, evmPrivKey) - if err != nil { - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err - } - return btcRPCClient, - goerliClient, - goerliAuth, - cctxClient, - fungibleClient, - authClient, - bankClient, - observerClient, - zevmClient, - zevmAuth, - nil -} - -// getBtcClient get btc client -func getBtcClient(rpc string) (*rpcclient.Client, error) { - connCfg := &rpcclient.ConnConfig{ - Host: rpc, - User: "smoketest", - Pass: "123", - HTTPPostMode: true, - DisableTLS: true, - Params: "testnet3", - } - return rpcclient.New(connCfg, nil) -} - -// getEVMClient get goerli client -func getEVMClient(ctx context.Context, rpc, privKey string) (*ethclient.Client, *bind.TransactOpts, error) { - evmClient, err := ethclient.Dial(rpc) - if err != nil { - return nil, nil, err - } - - chainid, err := evmClient.ChainID(ctx) - if err != nil { - return nil, nil, err - } - deployerPrivkey, err := crypto.HexToECDSA(privKey) - if err != nil { - return nil, nil, err - } - evmAuth, err := bind.NewKeyedTransactorWithChainID(deployerPrivkey, chainid) - if err != nil { - return nil, nil, err - } - - return evmClient, evmAuth, nil -} - -// getZetaClients get zeta clients -func getZetaClients(rpc string) ( - crosschaintypes.QueryClient, - fungibletypes.QueryClient, - authtypes.QueryClient, - banktypes.QueryClient, - observertypes.QueryClient, - error, -) { - grpcConn, err := grpc.Dial(rpc, grpc.WithInsecure()) - if err != nil { - return nil, nil, nil, nil, nil, err - } - - cctxClient := crosschaintypes.NewQueryClient(grpcConn) - fungibleClient := fungibletypes.NewQueryClient(grpcConn) - authClient := authtypes.NewQueryClient(grpcConn) - bankClient := banktypes.NewQueryClient(grpcConn) - observerClient := observertypes.NewQueryClient(grpcConn) - - return cctxClient, fungibleClient, authClient, bankClient, observerClient, nil -} - -// waitKeygenHeight waits for keygen height -func waitKeygenHeight( - ctx context.Context, - cctxClient crosschaintypes.QueryClient, - logger *runner.Logger, -) { - // wait for keygen to be completed. ~ height 30 - keygenHeight := int64(60) - logger.Print("⏳ wait height %v for keygen to be completed", keygenHeight) - for { - time.Sleep(2 * time.Second) - response, err := cctxClient.LastZetaHeight(ctx, &crosschaintypes.QueryLastZetaHeightRequest{}) - if err != nil { - logger.Error("cctxClient.LastZetaHeight error: %s", err) - continue - } - if response.Height >= keygenHeight { - break - } - logger.Info("Last ZetaHeight: %d", response.Height) - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/zeta.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/zeta.go deleted file mode 100644 index 6cefb8c615..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local/zeta.go +++ /dev/null @@ -1,74 +0,0 @@ -package local - -import ( - "fmt" - "runtime" - "time" - - "github.com/fatih/color" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/config" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/smoketests" -) - -// zetaTestRoutine runs Zeta transfer and message passing related smoke tests -func zetaTestRoutine( - conf config.Config, - deployerRunner *runner.SmokeTestRunner, - verbose bool, -) func() error { - return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the smoke tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("zeta panic: %v, stack trace %s", r, stack[:n]) - } - }() - - // initialize runner for zeta test - zetaRunner, err := initTestRunner( - "zeta", - conf, - deployerRunner, - UserZetaTestAddress, - UserZetaTestPrivateKey, - runner.NewLogger(verbose, color.FgBlue, "zeta"), - ) - if err != nil { - return err - } - - zetaRunner.Logger.Print("🏃 starting Zeta tests") - startTime := time.Now() - - // funding the account - txZetaSend := deployerRunner.SendZetaOnEvm(UserZetaTestAddress, 1000) - zetaRunner.WaitForTxReceiptOnEvm(txZetaSend) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := zetaRunner.DepositZeta() - txEtherDeposit := zetaRunner.DepositEther(false) - zetaRunner.WaitForMinedCCTX(txZetaDeposit) - zetaRunner.WaitForMinedCCTX(txEtherDeposit) - - // run zeta test - if err := zetaRunner.RunSmokeTestsFromNames( - smoketests.AllSmokeTests, - smoketests.TestSendZetaOutName, - smoketests.TestMessagePassingName, - smoketests.TestMessagePassingRevertFailName, - smoketests.TestMessagePassingRevertSuccessName, - ); err != nil { - return fmt.Errorf("zeta tests failed: %v", err) - } - - zetaRunner.Logger.Print("🍾 Zeta tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/main.go deleted file mode 100644 index 7b8038709c..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/main.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/fatih/color" -) - -func main() { - // enable color output - color.NoColor = false - - // initialize root command - rootCmd := NewRootCmd() - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(-1) - } -} diff --git a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/root.go b/contrib/localnet/orchestrator/smoketest/cmd/smoketest/root.go deleted file mode 100644 index 512f235df5..0000000000 --- a/contrib/localnet/orchestrator/smoketest/cmd/smoketest/root.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/cmd/smoketest/local" -) - -func NewRootCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "smoketest", - Short: "Smoke Test CLI", - } - cmd.AddCommand(local.NewLocalCmd()) - - return cmd -} diff --git a/contrib/localnet/orchestrator/smoketest/config/config.go b/contrib/localnet/orchestrator/smoketest/config/config.go index 097bc58641..442ab6df63 100644 --- a/contrib/localnet/orchestrator/smoketest/config/config.go +++ b/contrib/localnet/orchestrator/smoketest/config/config.go @@ -2,8 +2,11 @@ package config import ( "errors" + "fmt" "os" + "github.com/btcsuite/btcd/chaincfg" + "gopkg.in/yaml.v2" ) @@ -24,11 +27,21 @@ type Accounts struct { // RPCs contains the configuration for the RPC endpoints type RPCs struct { - Zevm string `yaml:"zevm"` - EVM string `yaml:"evm"` - Bitcoin string `yaml:"bitcoin"` - ZetaCoreGRPC string `yaml:"zetacore_grpc"` - ZetaCoreRPC string `yaml:"zetacore_rpc"` + Zevm string `yaml:"zevm"` + EVM string `yaml:"evm"` + Bitcoin BitcoinRPC `yaml:"bitcoin"` + ZetaCoreGRPC string `yaml:"zetacore_grpc"` + ZetaCoreRPC string `yaml:"zetacore_rpc"` +} + +// BitcoinRPC contains the configuration for the Bitcoin RPC endpoint +type BitcoinRPC struct { + User string `yaml:"user"` + Pass string `yaml:"pass"` + Host string `yaml:"host"` + HTTPPostMode bool `yaml:"http_post_mode"` + DisableTLS bool `yaml:"disable_tls"` + Params BitcoinNetworkType `yaml:"params"` } // Contracts contains the addresses of predeployed contracts @@ -53,17 +66,27 @@ type ZEVM struct { BTCZRC20Addr string `yaml:"btc_zrc20"` UniswapFactoryAddr string `yaml:"uniswap_factory"` UniswapRouterAddr string `yaml:"uniswap_router"` + ConnectorZEVMAddr string `yaml:"connector_zevm"` + WZetaAddr string `yaml:"wzeta"` ZEVMSwapAppAddr string `yaml:"zevm_swap_app"` ContextAppAddr string `yaml:"context_app"` TestDappAddr string `yaml:"test_dapp"` } +// DefaultConfig returns the default config using values for localnet testing func DefaultConfig() Config { return Config{ RPCs: RPCs{ - Zevm: "http://zetacore0:8545", - EVM: "http://eth:8545", - Bitcoin: "bitcoin:18443", + Zevm: "http://zetacore0:8545", + EVM: "http://eth:8545", + Bitcoin: BitcoinRPC{ + Host: "bitcoin:18443", + User: "smoketest", + Pass: "123", + HTTPPostMode: true, + DisableTLS: true, + Params: Regnet, + }, ZetaCoreGRPC: "zetacore0:9090", ZetaCoreRPC: "http://zetacore0:26657", }, @@ -91,6 +114,10 @@ func ReadConfig(file string) (config Config, err error) { if err != nil { return Config{}, err } + if err := config.Validate(); err != nil { + return Config{}, err + } + return } @@ -110,3 +137,37 @@ func WriteConfig(file string, config Config) error { } return nil } + +// Validate validates the config +func (c Config) Validate() error { + if c.RPCs.Bitcoin.Params != Mainnet && + c.RPCs.Bitcoin.Params != Testnet3 && + c.RPCs.Bitcoin.Params != Regnet { + return errors.New("invalid bitcoin params") + } + return nil +} + +// BitcoinNetworkType is a custom type to represent allowed network types +type BitcoinNetworkType string + +// Enum values for BitcoinNetworkType +const ( + Mainnet BitcoinNetworkType = "mainnet" + Testnet3 BitcoinNetworkType = "testnet3" + Regnet BitcoinNetworkType = "regnet" +) + +// GetParams returns the chaincfg.Params for the BitcoinNetworkType +func (bnt BitcoinNetworkType) GetParams() (chaincfg.Params, error) { + switch bnt { + case Mainnet: + return chaincfg.MainNetParams, nil + case Testnet3: + return chaincfg.TestNet3Params, nil + case Regnet: + return chaincfg.RegressionNetParams, nil + default: + return chaincfg.Params{}, fmt.Errorf("invalid bitcoin params %s", bnt) + } +} diff --git a/contrib/localnet/orchestrator/smoketest/runner/balances.go b/contrib/localnet/orchestrator/smoketest/runner/balances.go new file mode 100644 index 0000000000..eb86122dc1 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/runner/balances.go @@ -0,0 +1,195 @@ +package runner + +import ( + "fmt" + "math/big" + "strings" + + "github.com/btcsuite/btcutil" + "github.com/ethereum/go-ethereum/accounts/abi/bind" +) + +// AccountBalances is a struct that contains the balances of the accounts used in the smoke test +type AccountBalances struct { + ZetaETH *big.Int + ZetaZETA *big.Int + ZetaWZETA *big.Int + ZetaERC20 *big.Int + ZetaBTC *big.Int + EvmETH *big.Int + EvmZETA *big.Int + EvmERC20 *big.Int + BtcBTC string +} + +// AccountBalancesDiff is a struct that contains the difference in the balances of the accounts used in the smoke test +type AccountBalancesDiff struct { + ETH *big.Int + ZETA *big.Int + ERC20 *big.Int +} + +// GetAccountBalances returns the account balances of the accounts used in the smoke test +func (sm *SmokeTestRunner) GetAccountBalances(skipBTC bool) (AccountBalances, error) { + // zevm + zetaZeta, err := sm.ZevmClient.BalanceAt(sm.Ctx, sm.DeployerAddress, nil) + if err != nil { + return AccountBalances{}, err + } + zetaWZeta, err := sm.WZeta.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + zetaEth, err := sm.ETHZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + zetaErc20, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + zetaBtc, err := sm.BTCZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + + // evm + evmEth, err := sm.GoerliClient.BalanceAt(sm.Ctx, sm.DeployerAddress, nil) + if err != nil { + return AccountBalances{}, err + } + evmZeta, err := sm.ZetaEth.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + evmErc20, err := sm.USDTERC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + return AccountBalances{}, err + } + + // bitcoin + var BtcBTC string + if !skipBTC { + if BtcBTC, err = sm.GetBitcoinBalance(); err != nil { + return AccountBalances{}, err + } + } + + return AccountBalances{ + ZetaETH: zetaEth, + ZetaZETA: zetaZeta, + ZetaWZETA: zetaWZeta, + ZetaERC20: zetaErc20, + ZetaBTC: zetaBtc, + EvmETH: evmEth, + EvmZETA: evmZeta, + EvmERC20: evmErc20, + BtcBTC: BtcBTC, + }, nil +} + +// GetBitcoinBalance returns the spendable BTC balance of the BTC address +func (sm *SmokeTestRunner) GetBitcoinBalance() (string, error) { + addr, _, err := sm.GetBtcAddress() + if err != nil { + return "", fmt.Errorf("failed to get BTC address: %w", err) + } + + address, err := btcutil.DecodeAddress(addr, sm.BitcoinParams) + if err != nil { + return "", fmt.Errorf("failed to decode BTC address: %w", err) + } + + unspentList, err := sm.BtcRPCClient.ListUnspentMinMaxAddresses(1, 9999999, []btcutil.Address{address}) + if err != nil { + return "", fmt.Errorf("failed to list unspent: %w", err) + } + + // calculate total amount + var totalAmount btcutil.Amount + for _, unspent := range unspentList { + if unspent.Spendable { + totalAmount += btcutil.Amount(unspent.Amount * 1e8) + } + } + + return totalAmount.String(), nil +} + +// PrintAccountBalances shows the account balances of the accounts used in the smoke test +// Note: USDT is mentioned as erc20 here because we want to show the balance of any erc20 contract +func (sm *SmokeTestRunner) PrintAccountBalances(balances AccountBalances) { + sm.Logger.Print(" ---💰 Account info %s ---", sm.DeployerAddress.Hex()) + + // zevm + sm.Logger.Print("ZetaChain:") + sm.Logger.Print("* ZETA balance: %s", balances.ZetaZETA.String()) + sm.Logger.Print("* WZETA balance: %s", balances.ZetaWZETA.String()) + sm.Logger.Print("* ETH balance: %s", balances.ZetaETH.String()) + sm.Logger.Print("* ERC20 balance: %s", balances.ZetaERC20.String()) + sm.Logger.Print("* BTC balance: %s", balances.ZetaBTC.String()) + + // evm + sm.Logger.Print("EVM:") + sm.Logger.Print("* ZETA balance: %s", balances.EvmZETA.String()) + sm.Logger.Print("* ETH balance: %s", balances.EvmETH.String()) + sm.Logger.Print("* ERC20 balance: %s", balances.EvmERC20.String()) + + // bitcoin + sm.Logger.Print("Bitcoin:") + sm.Logger.Print("* BTC balance: %s", balances.BtcBTC) + + return +} + +// PrintTotalDiff shows the difference in the account balances of the accounts used in the e2e test from two balances structs +func (sm *SmokeTestRunner) PrintTotalDiff(accoutBalancesDiff AccountBalancesDiff) { + sm.Logger.Print(" ---💰 Total gas spent ---") + + // show the value only if it is not zero + if accoutBalancesDiff.ZETA.Cmp(big.NewInt(0)) != 0 { + sm.Logger.Print("* ZETA spent: %s", accoutBalancesDiff.ZETA.String()) + } + if accoutBalancesDiff.ETH.Cmp(big.NewInt(0)) != 0 { + sm.Logger.Print("* ETH spent: %s", accoutBalancesDiff.ETH.String()) + } + if accoutBalancesDiff.ERC20.Cmp(big.NewInt(0)) != 0 { + sm.Logger.Print("* ERC20 spent: %s", accoutBalancesDiff.ERC20.String()) + } +} + +// GetAccountBalancesDiff returns the difference in the account balances of the accounts used in the smoke test +func GetAccountBalancesDiff(balancesBefore, balancesAfter AccountBalances) AccountBalancesDiff { + balancesBeforeZeta := big.NewInt(0).Add(balancesBefore.ZetaZETA, balancesBefore.EvmZETA) + balancesBeforeEth := big.NewInt(0).Add(balancesBefore.ZetaETH, balancesBefore.EvmETH) + balancesBeforeErc20 := big.NewInt(0).Add(balancesBefore.ZetaERC20, balancesBefore.EvmERC20) + + balancesAfterZeta := big.NewInt(0).Add(balancesAfter.ZetaZETA, balancesAfter.EvmZETA) + balancesAfterEth := big.NewInt(0).Add(balancesAfter.ZetaETH, balancesAfter.EvmETH) + balancesAfterErc20 := big.NewInt(0).Add(balancesAfter.ZetaERC20, balancesAfter.EvmERC20) + + diffZeta := big.NewInt(0).Sub(balancesBeforeZeta, balancesAfterZeta) + diffEth := big.NewInt(0).Sub(balancesBeforeEth, balancesAfterEth) + diffErc20 := big.NewInt(0).Sub(balancesBeforeErc20, balancesAfterErc20) + + return AccountBalancesDiff{ + ETH: diffEth, + ZETA: diffZeta, + ERC20: diffErc20, + } +} + +// formatBalances formats the AccountBalancesDiff into a one-liner string +func formatBalances(balances AccountBalancesDiff) string { + parts := []string{} + if balances.ETH != nil && balances.ETH.Cmp(big.NewInt(0)) > 0 { + parts = append(parts, fmt.Sprintf("ETH:%s", balances.ETH.String())) + } + if balances.ZETA != nil && balances.ZETA.Cmp(big.NewInt(0)) > 0 { + parts = append(parts, fmt.Sprintf("ZETA:%s", balances.ZETA.String())) + } + if balances.ERC20 != nil && balances.ERC20.Cmp(big.NewInt(0)) > 0 { + parts = append(parts, fmt.Sprintf("ERC20:%s", balances.ERC20.String())) + } + return strings.Join(parts, ",") +} diff --git a/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go b/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go index 9ee876a04e..b0ec145039 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go +++ b/contrib/localnet/orchestrator/smoketest/runner/bitcoin.go @@ -26,6 +26,44 @@ import ( var blockHeaderBTCTimeout = 5 * time.Minute +// DepositBTCWithAmount deposits BTC on ZetaChain with a specific amount +func (sm *SmokeTestRunner) DepositBTCWithAmount(amount float64) (txHash *chainhash.Hash) { + sm.Logger.Print("⏳ depositing BTC into ZEVM") + + // fetch utxos + utxos, err := sm.BtcRPCClient.ListUnspentMinMaxAddresses(1, 9999999, []btcutil.Address{sm.BTCDeployerAddress}) + if err != nil { + panic(err) + } + + spendableAmount := 0.0 + spendableUTXOs := 0 + for _, utxo := range utxos { + if utxo.Spendable { + spendableAmount += utxo.Amount + spendableUTXOs++ + } + } + + if spendableAmount < amount { + panic(fmt.Errorf("not enough spendable BTC to run the test; have %f", spendableAmount)) + } + + sm.Logger.Info("ListUnspent:") + sm.Logger.Info(" spendableAmount: %f", spendableAmount) + sm.Logger.Info(" spendableUTXOs: %d", spendableUTXOs) + sm.Logger.Info("Now sending two txs to TSS address...") + + amount = amount + zetaclient.BtcDepositorFeeMin + txHash, err = sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount, utxos, sm.BtcRPCClient, sm.BTCDeployerAddress) + if err != nil { + panic(err) + } + sm.Logger.Info("send BTC to TSS txHash: %s", txHash.String()) + + return txHash +} + // DepositBTC deposits BTC on ZetaChain func (sm *SmokeTestRunner) DepositBTC(testHeader bool) { sm.Logger.Print("⏳ depositing BTC into ZEVM") @@ -127,7 +165,7 @@ func (sm *SmokeTestRunner) SendToTSSFromDeployerWithMemo( to btcutil.Address, amount float64, inputUTXOs []btcjson.ListUnspentResult, - btc *rpcclient.Client, + btcRPC *rpcclient.Client, memo []byte, btcDeployerAddress *btcutil.AddressWitnessPubKeyHash, ) (*chainhash.Hash, error) { @@ -156,8 +194,9 @@ func (sm *SmokeTestRunner) SendToTSSFromDeployerWithMemo( btcDeployerAddress: change, } - // create raw transaction - tx, err := btc.CreateRawTransaction(inputs, amountMap, nil) + // create raw + sm.Logger.Info("ADDRESS: %s, %s", btcDeployerAddress.EncodeAddress(), to.EncodeAddress()) + tx, err := btcRPC.CreateRawTransaction(inputs, amountMap, nil) if err != nil { panic(err) } @@ -200,38 +239,42 @@ func (sm *SmokeTestRunner) SendToTSSFromDeployerWithMemo( } } - stx, signed, err := btc.SignRawTransactionWithWallet2(tx, inputsForSign) + stx, signed, err := btcRPC.SignRawTransactionWithWallet2(tx, inputsForSign) if err != nil { panic(err) } if !signed { panic("btc transaction not signed") } - txid, err := btc.SendRawTransaction(stx, true) + txid, err := btcRPC.SendRawTransaction(stx, true) if err != nil { panic(err) } sm.Logger.Info("txid: %+v", txid) - _, err = btc.GenerateToAddress(6, btcDeployerAddress, nil) + _, err = btcRPC.GenerateToAddress(6, btcDeployerAddress, nil) if err != nil { panic(err) } - gtx, err := btc.GetTransaction(txid) + gtx, err := btcRPC.GetTransaction(txid) if err != nil { panic(err) } sm.Logger.Info("rawtx confirmation: %d", gtx.BlockIndex) - rawtx, err := btc.GetRawTransactionVerbose(txid) + rawtx, err := btcRPC.GetRawTransactionVerbose(txid) if err != nil { panic(err) } + btcChainID, err := common.GetBTCChainIDFromChainParams(sm.BitcoinParams) + if err != nil { + panic(err) + } events := zetaclient.FilterAndParseIncomingTx( []btcjson.TxRawResult{*rawtx}, 0, sm.BTCTSSAddress.EncodeAddress(), &log.Logger, - common.BtcRegtestChain().ChainId, + btcChainID, ) sm.Logger.Info("bitcoin intx events:") for _, event := range events { diff --git a/contrib/localnet/orchestrator/smoketest/runner/evm.go b/contrib/localnet/orchestrator/smoketest/runner/evm.go index f2bb0aaea5..cd922ed673 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/evm.go +++ b/contrib/localnet/orchestrator/smoketest/runner/evm.go @@ -71,16 +71,13 @@ func (sm *SmokeTestRunner) SendUSDTOnEvm(address ethcommon.Address, amountUSDT i func (sm *SmokeTestRunner) DepositERC20() ethcommon.Hash { sm.Logger.Print("⏳ depositing ERC20 into ZEVM") - startTime := time.Now() - defer func() { - sm.Logger.Print("✅ ERC20 deposited in %s", time.Since(startTime)) - }() return sm.DepositERC20WithAmountAndMessage(big.NewInt(1e18), []byte{}) } func (sm *SmokeTestRunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg []byte) ethcommon.Hash { - tx, err := sm.USDTERC20.Approve(sm.GoerliAuth, sm.ERC20CustodyAddr, amount) + // reset allowance, necessary for USDT + tx, err := sm.USDTERC20.Approve(sm.GoerliAuth, sm.ERC20CustodyAddr, big.NewInt(0)) if err != nil { panic(err) } @@ -90,7 +87,18 @@ func (sm *SmokeTestRunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg } sm.Logger.Info("USDT Approve receipt tx hash: %s", tx.Hash().Hex()) + tx, err = sm.USDTERC20.Approve(sm.GoerliAuth, sm.ERC20CustodyAddr, amount) + if err != nil { + panic(err) + } + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("approve failed") + } + sm.Logger.Info("USDT Approve receipt tx hash: %s", tx.Hash().Hex()) + tx, err = sm.ERC20Custody.Deposit(sm.GoerliAuth, sm.DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, msg) + sm.Logger.Print("TX: %v", tx) if err != nil { panic(err) } @@ -115,28 +123,24 @@ func (sm *SmokeTestRunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg // DepositEther sends Ethers into ZEVM func (sm *SmokeTestRunner) DepositEther(testHeader bool) ethcommon.Hash { + return sm.DepositEtherWithAmount(testHeader, big.NewInt(1000000000000000000)) // in wei (1 eth) +} + +// DepositEtherWithAmount sends Ethers into ZEVM +func (sm *SmokeTestRunner) DepositEtherWithAmount(testHeader bool, amount *big.Int) ethcommon.Hash { sm.Logger.Print("⏳ depositing Ethers into ZEVM") - startTime := time.Now() - defer func() { - sm.Logger.Print("✅ Ethers deposited in %s", time.Since(startTime)) - }() - value := big.NewInt(1000000000000000000) // in wei (1 eth) - signedTx, err := sm.SendEther(sm.TSSAddress, value, nil) + signedTx, err := sm.SendEther(sm.TSSAddress, amount, nil) if err != nil { panic(err) } + sm.Logger.EVMTransaction(*signedTx, "send to TSS") - sm.Logger.Info("GOERLI tx sent: %s; to %s, nonce %d", signedTx.Hash().String(), signedTx.To().Hex(), signedTx.Nonce()) receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, signedTx, sm.Logger, sm.ReceiptTimeout) if receipt.Status == 0 { panic("deposit failed") } - sm.Logger.Info("GOERLI tx receipt: %d", receipt.Status) - sm.Logger.Info(" tx hash: %s", receipt.TxHash.String()) - sm.Logger.Info(" to: %s", signedTx.To().String()) - sm.Logger.Info(" value: %d", signedTx.Value()) - sm.Logger.Info(" block num: %d", receipt.BlockNumber) + sm.Logger.EVMReceipt(*receipt, "send to TSS") // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks // to optimize block header proof test, this test is directly executed here on the first deposit instead of having a separate test diff --git a/contrib/localnet/orchestrator/smoketest/runner/logger.go b/contrib/localnet/orchestrator/smoketest/runner/logger.go index 03b22f4671..3a9ed4827c 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/logger.go +++ b/contrib/localnet/orchestrator/smoketest/runner/logger.go @@ -2,6 +2,11 @@ package runner import ( "fmt" + "sync" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" "github.com/fatih/color" ) @@ -16,6 +21,7 @@ type Logger struct { verbose bool logger *color.Color prefix string + mu sync.Mutex } // NewLogger creates a new Logger @@ -32,15 +38,41 @@ func NewLogger(verbose bool, printColor color.Attribute, prefix string) *Logger } } +// SetColor sets the color of the logger +func (l *Logger) SetColor(printColor color.Attribute) { + l.logger = color.New(printColor) +} + +// Prefix returns the prefix of the logger +func (l *Logger) Prefix() string { + return l.getPrefixWithPadding() + loggerSeparator +} + // Print prints a message to the logger func (l *Logger) Print(message string, args ...interface{}) { + l.mu.Lock() + defer l.mu.Unlock() + text := fmt.Sprintf(message, args...) // #nosec G104 - we are not using user input l.logger.Printf(l.getPrefixWithPadding() + loggerSeparator + text + "\n") } +// PrintNoPrefix prints a message to the logger without the prefix +func (l *Logger) PrintNoPrefix(message string, args ...interface{}) { + l.mu.Lock() + defer l.mu.Unlock() + + text := fmt.Sprintf(message, args...) + // #nosec G104 - we are not using user input + l.logger.Printf(text + "\n") +} + // Info prints a message to the logger if verbose is true func (l *Logger) Info(message string, args ...interface{}) { + l.mu.Lock() + defer l.mu.Unlock() + if l.verbose { text := fmt.Sprintf(message, args...) // #nosec G104 - we are not using user input @@ -50,6 +82,9 @@ func (l *Logger) Info(message string, args ...interface{}) { // InfoLoud prints a message to the logger if verbose is true func (l *Logger) InfoLoud(message string, args ...interface{}) { + l.mu.Lock() + defer l.mu.Unlock() + if l.verbose { text := fmt.Sprintf(message, args...) // #nosec G104 - we are not using user input @@ -63,11 +98,107 @@ func (l *Logger) InfoLoud(message string, args ...interface{}) { // Error prints an error message to the logger func (l *Logger) Error(message string, args ...interface{}) { + l.mu.Lock() + defer l.mu.Unlock() + text := fmt.Sprintf(message, args...) // #nosec G104 - we are not using user input l.logger.Printf(l.getPrefixWithPadding() + loggerSeparator + "[ERROR]" + text + "\n") } +// CCTX prints a CCTX +func (l *Logger) CCTX(cctx crosschaintypes.CrossChainTx, name string) { + l.Info(" %s cross-chain transaction: %s", name, cctx.Index) + if cctx.CctxStatus != nil { + l.Info(" CctxStatus:") + l.Info(" Status: %s", cctx.CctxStatus.Status.String()) + if cctx.CctxStatus.StatusMessage != "" { + l.Info(" StatusMessage: %s", cctx.CctxStatus.StatusMessage) + } + } + if cctx.InboundTxParams != nil { + l.Info(" InboundTxParams:") + l.Info(" TxHash: %s", cctx.InboundTxParams.InboundTxObservedHash) + l.Info(" TxHeight: %d", cctx.InboundTxParams.InboundTxObservedExternalHeight) + l.Info(" BallotIndex: %s", cctx.InboundTxParams.InboundTxBallotIndex) + l.Info(" Amount: %s", cctx.InboundTxParams.Amount.String()) + l.Info(" CoinType: %s", cctx.InboundTxParams.CoinType.String()) + l.Info(" SenderChainID: %d", cctx.InboundTxParams.SenderChainId) + l.Info(" Origin: %s", cctx.InboundTxParams.TxOrigin) + if cctx.InboundTxParams.Sender != "" { + l.Info(" Sender: %s", cctx.InboundTxParams.Sender) + } + if cctx.InboundTxParams.Asset != "" { + l.Info(" Asset: %s", cctx.InboundTxParams.Asset) + } + } + if cctx.RelayedMessage != "" { + l.Info(" RelayedMessage: %s", cctx.RelayedMessage) + } + for i, outTxParam := range cctx.OutboundTxParams { + if i == 0 { + l.Info(" OutboundTxParams:") + } else { + l.Info(" RevertTxParams:") + } + l.Info(" TxHash: %s", outTxParam.OutboundTxHash) + l.Info(" TxHeight: %d", outTxParam.OutboundTxObservedExternalHeight) + l.Info(" BallotIndex: %s", outTxParam.OutboundTxBallotIndex) + l.Info(" TSSNonce: %d", outTxParam.OutboundTxTssNonce) + l.Info(" GasLimit: %d", outTxParam.OutboundTxGasLimit) + l.Info(" GasPrice: %s", outTxParam.OutboundTxGasPrice) + l.Info(" GasUsed: %d", outTxParam.OutboundTxGasUsed) + l.Info(" EffectiveGasPrice: %s", outTxParam.OutboundTxEffectiveGasPrice.String()) + l.Info(" EffectiveGasLimit: %d", outTxParam.OutboundTxEffectiveGasLimit) + l.Info(" Amount: %s", outTxParam.Amount.String()) + l.Info(" CoinType: %s", outTxParam.CoinType.String()) + l.Info(" Receiver: %s", outTxParam.Receiver) + l.Info(" ReceiverChainID: %d", outTxParam.ReceiverChainId) + } +} + +// EVMTransaction prints a transaction +func (l *Logger) EVMTransaction(tx ethtypes.Transaction, name string) { + l.Info(" %s EVM transaction: %s", name, tx.Hash().Hex()) + l.Info(" To: %s", tx.To().Hex()) + l.Info(" Value: %d", tx.Value()) + l.Info(" Gas: %d", tx.Gas()) + l.Info(" GasPrice: %d", tx.GasPrice()) +} + +// EVMReceipt prints a receipt +func (l *Logger) EVMReceipt(receipt ethtypes.Receipt, name string) { + l.Info(" %s EVM receipt: %s", name, receipt.TxHash.Hex()) + l.Info(" BlockNumber: %d", receipt.BlockNumber) + l.Info(" GasUsed: %d", receipt.GasUsed) + l.Info(" ContractAddress: %s", receipt.ContractAddress.Hex()) + l.Info(" Status: %d", receipt.Status) +} + +// ZRC20Withdrawal prints a ZRC20Withdrawal event +func (l *Logger) ZRC20Withdrawal( + contract interface { + ParseWithdrawal(ethtypes.Log) (*zrc20.ZRC20Withdrawal, error) + }, + receipt ethtypes.Receipt, + name string, +) { + for _, log := range receipt.Logs { + event, err := contract.ParseWithdrawal(*log) + if err != nil { + continue + } + l.Info( + " %s ZRC20Withdrawal: from %s, to %x, value %d, gasfee %d", + name, + event.From.Hex(), + event.To, + event.Value, + event.Gasfee, + ) + } +} + func (l *Logger) getPrefixWithPadding() string { // add padding to prefix prefix := l.prefix diff --git a/contrib/localnet/orchestrator/smoketest/runner/report.go b/contrib/localnet/orchestrator/smoketest/runner/report.go new file mode 100644 index 0000000000..1c8428a1a9 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/runner/report.go @@ -0,0 +1,55 @@ +package runner + +import ( + "fmt" + "strings" + "text/tabwriter" + "time" +) + +// TestReport is a struct that contains the test report +type TestReport struct { + Name string + Success bool + Time time.Duration + GasSpent AccountBalancesDiff +} + +// TestReports is a slice of TestReport +type TestReports []TestReport + +// String returns the string representation of the test report as a table +// it uses text/tabwriter to format the table +func (tr TestReports) String(prefix string) (string, error) { + var b strings.Builder + writer := tabwriter.NewWriter(&b, 0, 4, 4, ' ', 0) + if _, err := fmt.Fprintln(writer, "Name\tSuccess\tTime\tSpent"); err != nil { + return "", err + } + + for _, report := range tr { + spent := formatBalances(report.GasSpent) + success := "✅" + if !report.Success { + success = "❌" + } + if _, err := fmt.Fprintf(writer, "%s%s\t%s\t%s\t%s\n", prefix, report.Name, success, report.Time, spent); err != nil { + return "", err + } + } + + if err := writer.Flush(); err != nil { + return "", err + } + return b.String(), nil +} + +// PrintTestReports prints the test reports +func (sm *SmokeTestRunner) PrintTestReports(tr TestReports) { + sm.Logger.Print(" ---📈 E2E Test Report ---") + table, err := tr.String("") + if err != nil { + sm.Logger.Print("Error rendering test report: %s", err) + } + sm.Logger.PrintNoPrefix(table) +} diff --git a/contrib/localnet/orchestrator/smoketest/runner/runner.go b/contrib/localnet/orchestrator/smoketest/runner/runner.go index 60698ac114..f968e2d9ec 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/runner.go +++ b/contrib/localnet/orchestrator/smoketest/runner/runner.go @@ -7,6 +7,11 @@ import ( "sync" "time" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcutil" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -80,25 +85,31 @@ type SmokeTestRunner struct { UniswapV2Factory *uniswapv2factory.UniswapV2Factory UniswapV2RouterAddr ethcommon.Address UniswapV2Router *uniswapv2router.UniswapV2Router02 - TestDAppAddr ethcommon.Address - ZEVMSwapAppAddr ethcommon.Address - ZEVMSwapApp *zevmswap.ZEVMSwapApp - ContextAppAddr ethcommon.Address - ContextApp *contextapp.ContextApp - SystemContractAddr ethcommon.Address - SystemContract *systemcontract.SystemContract + ConnectorZEVMAddr ethcommon.Address + ConnectorZEVM *connectorzevm.ZetaConnectorZEVM + WZetaAddr ethcommon.Address + WZeta *wzeta.WETH9 + + TestDAppAddr ethcommon.Address + ZEVMSwapAppAddr ethcommon.Address + ZEVMSwapApp *zevmswap.ZEVMSwapApp + ContextAppAddr ethcommon.Address + ContextApp *contextapp.ContextApp + SystemContractAddr ethcommon.Address + SystemContract *systemcontract.SystemContract // config CctxTimeout time.Duration ReceiptTimeout time.Duration // other - Name string - Ctx context.Context - CtxCancel context.CancelFunc - Logger *Logger - WG sync.WaitGroup - mutex sync.Mutex + Name string + Ctx context.Context + CtxCancel context.CancelFunc + Logger *Logger + WG sync.WaitGroup + BitcoinParams *chaincfg.Params + mutex sync.Mutex } func NewSmokeTestRunner( @@ -167,7 +178,7 @@ func (sm *SmokeTestRunner) RunSmokeTestsFromNames(smokeTests []SmokeTest, smokeT if !ok { return fmt.Errorf("smoke test %s not found", smokeTestName) } - if err := sm.RunSmokeTest(smokeTest); err != nil { + if err := sm.RunSmokeTest(smokeTest, true); err != nil { return err } } @@ -175,10 +186,62 @@ func (sm *SmokeTestRunner) RunSmokeTestsFromNames(smokeTests []SmokeTest, smokeT return nil } +// RunSmokeTestsFromNamesIntoReport runs a list of smoke tests by name in a list of smoke tests and returns a report +// The function doesn't return an error, it returns a report with the error +func (sm *SmokeTestRunner) RunSmokeTestsFromNamesIntoReport(smokeTests []SmokeTest, smokeTestNames ...string) (TestReports, error) { + // get all tests so we can return an error if a test is not found + tests := make([]SmokeTest, 0, len(smokeTestNames)) + for _, smokeTestName := range smokeTestNames { + smokeTest, ok := findSmokeTest(smokeTestName, smokeTests) + if !ok { + return nil, fmt.Errorf("smoke test %s not found", smokeTestName) + } + tests = append(tests, smokeTest) + } + + // go through all tests + reports := make(TestReports, 0, len(smokeTestNames)) + for _, test := range tests { + // get info before test + balancesBefore, err := sm.GetAccountBalances(true) + if err != nil { + return nil, err + } + timeBefore := time.Now() + + // run test + testErr := sm.RunSmokeTest(test, false) + if testErr != nil { + sm.Logger.Print("test %s failed: %s", test.Name, testErr.Error()) + } + + // wait 5 sec to make sure we get updated balances + time.Sleep(5 * time.Second) + + // get info after test + balancesAfter, err := sm.GetAccountBalances(true) + if err != nil { + return nil, err + } + timeAfter := time.Now() + + // create report + report := TestReport{ + Name: test.Name, + Success: testErr == nil, + Time: timeAfter.Sub(timeBefore), + GasSpent: GetAccountBalancesDiff(balancesBefore, balancesAfter), + } + reports = append(reports, report) + } + + return reports, nil +} + // RunSmokeTests runs a list of smoke tests func (sm *SmokeTestRunner) RunSmokeTests(smokeTests []SmokeTest) (err error) { for _, smokeTest := range smokeTests { - if err := sm.RunSmokeTest(smokeTest); err != nil { + if err := sm.RunSmokeTest(smokeTest, true); err != nil { return err } } @@ -186,7 +249,7 @@ func (sm *SmokeTestRunner) RunSmokeTests(smokeTests []SmokeTest) (err error) { } // RunSmokeTest runs a smoke test -func (sm *SmokeTestRunner) RunSmokeTest(smokeTestWithName SmokeTest) (err error) { +func (sm *SmokeTestRunner) RunSmokeTest(smokeTestWithName SmokeTest, checkAccounting bool) (err error) { // return an error on panic // https://github.com/zeta-chain/node/issues/1500 defer func() { @@ -205,8 +268,10 @@ func (sm *SmokeTestRunner) RunSmokeTest(smokeTestWithName SmokeTest) (err error) smokeTestWithName.SmokeTest(sm) //check supplies - if err := sm.CheckZRC20ReserveAndSupply(); err != nil { - return err + if checkAccounting { + if err := sm.CheckZRC20ReserveAndSupply(); err != nil { + return err + } } sm.Logger.Print("✅ completed in %s - %s", time.Since(startTime), smokeTestWithName.Description) @@ -240,6 +305,8 @@ func (sm *SmokeTestRunner) CopyAddressesFrom(other *SmokeTestRunner) (err error) sm.BTCZRC20Addr = other.BTCZRC20Addr sm.UniswapV2FactoryAddr = other.UniswapV2FactoryAddr sm.UniswapV2RouterAddr = other.UniswapV2RouterAddr + sm.ConnectorZEVMAddr = other.ConnectorZEVMAddr + sm.WZetaAddr = other.WZetaAddr sm.TestDAppAddr = other.TestDAppAddr sm.ZEVMSwapAppAddr = other.ZEVMSwapAppAddr sm.ContextAppAddr = other.ContextAppAddr @@ -282,6 +349,15 @@ func (sm *SmokeTestRunner) CopyAddressesFrom(other *SmokeTestRunner) (err error) if err != nil { return err } + sm.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(sm.ConnectorZEVMAddr, sm.ZevmClient) + if err != nil { + return err + } + sm.WZeta, err = wzeta.NewWETH9(sm.WZetaAddr, sm.ZevmClient) + if err != nil { + return err + } + sm.ZEVMSwapApp, err = zevmswap.NewZEVMSwapApp(sm.ZEVMSwapAppAddr, sm.ZevmClient) if err != nil { return err @@ -319,6 +395,9 @@ func (sm *SmokeTestRunner) PrintContractAddresses() { sm.Logger.Print("BTCZRC20: %s", sm.BTCZRC20Addr.Hex()) sm.Logger.Print("UniswapFactory: %s", sm.UniswapV2FactoryAddr.Hex()) sm.Logger.Print("UniswapRouter: %s", sm.UniswapV2RouterAddr.Hex()) + sm.Logger.Print("ConnectorZEVM: %s", sm.ConnectorZEVMAddr.Hex()) + sm.Logger.Print("WZeta: %s", sm.WZetaAddr.Hex()) + sm.Logger.Print("ZEVMSwapApp: %s", sm.ZEVMSwapAppAddr.Hex()) sm.Logger.Print("ContextApp: %s", sm.ContextAppAddr.Hex()) sm.Logger.Print("TestDapp: %s", sm.TestDAppAddr.Hex()) diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go b/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go index 1b4a1ce671..52dfc2549c 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_bitcoin.go @@ -6,7 +6,6 @@ import ( "time" "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcutil" ) @@ -25,7 +24,7 @@ func (sm *SmokeTestRunner) SetupBitcoinAccount(initNetwork bool) { } } - sm.setBtcAddress() + sm.SetBtcAddress(sm.Name, true) if initNetwork { // import the TSS address @@ -47,29 +46,54 @@ func (sm *SmokeTestRunner) SetupBitcoinAccount(initNetwork bool) { } } -// setBtcAddress -func (sm *SmokeTestRunner) setBtcAddress() { +// GetBtcAddress returns the BTC address of the deployer from its EVM private key +func (sm *SmokeTestRunner) GetBtcAddress() (string, string, error) { skBytes, err := hex.DecodeString(sm.DeployerPrivateKey) if err != nil { - panic(err) + return "", "", err } - // TODO: support non regtest chain - // https://github.com/zeta-chain/node/issues/1482 sk, _ := btcec.PrivKeyFromBytes(btcec.S256(), skBytes) - privkeyWIF, err := btcutil.NewWIF(sk, &chaincfg.RegressionNetParams, true) + privkeyWIF, err := btcutil.NewWIF(sk, sm.BitcoinParams, true) + if err != nil { + return "", "", err + } + + address, err := btcutil.NewAddressWitnessPubKeyHash( + btcutil.Hash160(privkeyWIF.SerializePubKey()), + sm.BitcoinParams, + ) + if err != nil { + return "", "", err + } + + // return the string representation of the address + return address.EncodeAddress(), privkeyWIF.String(), nil +} + +// SetBtcAddress imports the deployer's private key into the Bitcoin node +func (sm *SmokeTestRunner) SetBtcAddress(name string, rescan bool) { + skBytes, err := hex.DecodeString(sm.DeployerPrivateKey) if err != nil { panic(err) } - err = sm.BtcRPCClient.ImportPrivKeyRescan(privkeyWIF, sm.Name, true) + sk, _ := btcec.PrivKeyFromBytes(btcec.S256(), skBytes) + privkeyWIF, err := btcutil.NewWIF(sk, sm.BitcoinParams, true) if err != nil { panic(err) } + if rescan { + err = sm.BtcRPCClient.ImportPrivKeyRescan(privkeyWIF, name, true) + if err != nil { + panic(err) + } + } + sm.BTCDeployerAddress, err = btcutil.NewAddressWitnessPubKeyHash( btcutil.Hash160(privkeyWIF.PrivKey.PubKey().SerializeCompressed()), - &chaincfg.RegressionNetParams, + sm.BitcoinParams, ) if err != nil { panic(err) diff --git a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go index 4ce1ba196a..b40056f707 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go +++ b/contrib/localnet/orchestrator/smoketest/runner/setup_zeta.go @@ -2,9 +2,11 @@ package runner import ( "math/big" - "strings" "time" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" + "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" + "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" @@ -16,29 +18,29 @@ import ( "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/contextapp" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/zevmswap" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) // SetTSSAddresses set TSS addresses from information queried from ZetaChain -func (sm *SmokeTestRunner) SetTSSAddresses() { +func (sm *SmokeTestRunner) SetTSSAddresses() error { sm.Logger.Print("⚙️ setting up TSS address") - var err error + btcChainID, err := common.GetBTCChainIDFromChainParams(sm.BitcoinParams) + if err != nil { + return err + } + res := &observertypes.QueryGetTssAddressResponse{} - for { - res, err = sm.ObserverClient.GetTssAddress(sm.Ctx, &observertypes.QueryGetTssAddressRequest{}) + for i := 0; ; i++ { + res, err = sm.ObserverClient.GetTssAddress(sm.Ctx, &observertypes.QueryGetTssAddressRequest{ + BitcoinChainId: btcChainID, + }) if err != nil { - // if error contains unknown method GetTssAddress for service, we might be using an older version of the chain for upgrade test - // we query the TSS address with legacy method - if strings.Contains(err.Error(), "unknown method GetTssAddress for service") { - sm.SetTSSAddressesLegacy() - return + if i%10 == 0 { + sm.Logger.Info("ObserverClient.TSS error %s", err.Error()) + sm.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") } - - sm.Logger.Info("ObserverClient.TSS error %s", err.Error()) - sm.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") time.Sleep(1 * time.Second) continue } @@ -47,13 +49,15 @@ func (sm *SmokeTestRunner) SetTSSAddresses() { tssAddress := ethcommon.HexToAddress(res.Eth) - btcTSSAddress, err := common.DecodeBtcAddress(res.Btc, common.BtcRegtestChain().ChainId) + btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, sm.BitcoinParams) if err != nil { panic(err) } sm.TSSAddress = tssAddress sm.BTCTSSAddress = btcTSSAddress + + return nil } // SetZEVMContracts set contracts for the ZEVM @@ -65,7 +69,7 @@ func (sm *SmokeTestRunner) SetZEVMContracts() { }() // deploy system contracts and ZRC20 contracts on ZetaChain - uniswapV2FactoryAddr, uniswapV2RouterAddr, usdtZRC20Addr, err := sm.ZetaTxServer.DeploySystemContractsAndZRC20( + uniswapV2FactoryAddr, uniswapV2RouterAddr, zevmConnectorAddr, wzetaAddr, usdtZRC20Addr, err := sm.ZetaTxServer.DeploySystemContractsAndZRC20( utils.FungibleAdminName, sm.USDTERC20Addr.Hex(), ) @@ -94,6 +98,20 @@ func (sm *SmokeTestRunner) SetZEVMContracts() { panic(err) } + // ZevmConnectorAddr + sm.ConnectorZEVMAddr = ethcommon.HexToAddress(zevmConnectorAddr) + sm.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(sm.ConnectorZEVMAddr, sm.ZevmClient) + if err != nil { + panic(err) + } + + // WZetaAddr + sm.WZetaAddr = ethcommon.HexToAddress(wzetaAddr) + sm.WZeta, err = wzeta.NewWETH9(sm.WZetaAddr, sm.ZevmClient) + if err != nil { + panic(err) + } + // query system contract address from the chain systemContractRes, err := sm.FungibleClient.SystemContract( sm.Ctx, @@ -151,8 +169,6 @@ func (sm *SmokeTestRunner) SetZEVMContracts() { } func (sm *SmokeTestRunner) SetupETHZRC20() { - // TODO: support non testnet chain - // https://github.com/zeta-chain/node/issues/1482 ethZRC20Addr, err := sm.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.GoerliLocalnetChain().ChainId)) if err != nil { panic(err) @@ -169,8 +185,6 @@ func (sm *SmokeTestRunner) SetupETHZRC20() { } func (sm *SmokeTestRunner) SetupBTCZRC20() { - // TODO: support non testnet chain - // https://github.com/zeta-chain/node/issues/1482 BTCZRC20Addr, err := sm.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(common.BtcRegtestChain().ChainId)) if err != nil { panic(err) @@ -183,29 +197,3 @@ func (sm *SmokeTestRunner) SetupBTCZRC20() { } sm.BTCZRC20 = BTCZRC20 } - -// SetTSSAddressesLegacy set TSS addresses from information queried from ZetaChain using legacy TSS query -// TODO: remove this function after v12 once upgrade testing is no longer needed with v11 -func (sm *SmokeTestRunner) SetTSSAddressesLegacy() { - var err error - res := &crosschaintypes.QueryGetTssAddressResponse{} - for { - res, err = sm.CctxClient.GetTssAddress(sm.Ctx, &crosschaintypes.QueryGetTssAddressRequest{}) - if err != nil { - sm.Logger.Info("cctxClient.TSS (legacy) error %s", err.Error()) - sm.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") - time.Sleep(1 * time.Second) - continue - } - break - } - - tssAddress := ethcommon.HexToAddress(res.Eth) - btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, common.BitcoinRegnetParams) - if err != nil { - panic(err) - } - - sm.TSSAddress = tssAddress - sm.BTCTSSAddress = btcTSSAddress -} diff --git a/contrib/localnet/orchestrator/smoketest/runner/zeta.go b/contrib/localnet/orchestrator/smoketest/runner/zeta.go index bac7f37431..c2405b21de 100644 --- a/contrib/localnet/orchestrator/smoketest/runner/zeta.go +++ b/contrib/localnet/orchestrator/smoketest/runner/zeta.go @@ -3,12 +3,10 @@ package runner import ( "fmt" "math/big" - "time" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" - "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -49,29 +47,36 @@ func (sm *SmokeTestRunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount i // DepositZeta deposits ZETA on ZetaChain from the ZETA smart contract on EVM func (sm *SmokeTestRunner) DepositZeta() ethcommon.Hash { - sm.Logger.Print("⏳ depositing ZETA into ZEVM") - startTime := time.Now() - defer func() { - sm.Logger.Print("✅ ZETA deposited in %s", time.Since(startTime)) - }() - amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(100)) // 100 Zeta + + return sm.DepositZetaWithAmount(amount) +} + +// DepositZetaWithAmount deposits ZETA on ZetaChain from the ZETA smart contract on EVM with the specified amount +func (sm *SmokeTestRunner) DepositZetaWithAmount(amount *big.Int) ethcommon.Hash { tx, err := sm.ZetaEth.Approve(sm.GoerliAuth, sm.ConnectorEthAddr, amount) if err != nil { panic(err) } sm.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "approve") if receipt.Status != 1 { panic("approve tx failed") } - sm.Logger.Info("Approve tx receipt: status %d", receipt.Status) + + // query the chain ID using zevm client + zetaChainID, err := sm.ZevmClient.ChainID(sm.Ctx) + if err != nil { + panic(err) + } tx, err = sm.ConnectorEth.Send(sm.GoerliAuth, zetaconnectoreth.ZetaInterfacesSendInput{ // TODO: allow user to specify destination chain id // https://github.com/zeta-chain/node-private/issues/41 - DestinationChainId: big.NewInt(common.ZetaPrivnetChain().ChainId), + DestinationChainId: zetaChainID, DestinationAddress: sm.DeployerAddress.Bytes(), DestinationGasLimit: big.NewInt(250_000), Message: nil, @@ -81,13 +86,14 @@ func (sm *SmokeTestRunner) DepositZeta() ethcommon.Hash { if err != nil { panic(err) } - sm.Logger.Info("Send tx hash: %s", tx.Hash().Hex()) + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "send") if receipt.Status != 1 { panic(fmt.Sprintf("expected tx receipt status to be 1; got %d", receipt.Status)) } - sm.Logger.Info("Send tx receipt: status %d", receipt.Status) + sm.Logger.Info(" Logs:") for _, log := range receipt.Logs { sentLog, err := sm.ConnectorEth.ParseZetaSent(*log) diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/smoketests.go b/contrib/localnet/orchestrator/smoketest/smoketests/smoketests.go index 869293574a..92d4c97030 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/smoketests.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/smoketests.go @@ -6,10 +6,9 @@ const ( TestContextUpgradeName = "context_upgrade" TestDepositAndCallRefundName = "deposit_and_call_refund" TestMultipleERC20DepositName = "erc20_multiple_deposit" - TestWithdrawERC20Name = "erc20_withdraw" TestMultipleWithdrawsName = "erc20_multiple_withdraw" - TestSendZetaOutName = "send_zeta_out" - TestSendZetaOutBTCRevertName = "send_zeta_out_btc_revert" // #nosec G101 - not a hardcoded password + TestZetaWithdrawName = "zeta_withdraw" + TestZetaWithdrawBTCRevertName = "zeta_withdraw_btc_revert" // #nosec G101 - not a hardcoded password TestMessagePassingName = "message_passing" TestZRC20SwapName = "zrc20_swap" TestBitcoinWithdrawName = "bitcoin_withdraw" @@ -23,8 +22,19 @@ const ( TestDepositEtherLiquidityCapName = "deposit_eth_liquidity_cap" TestMyTestName = "my_test" - TestERC20DepositName = "erc20_deposit" - TestEtherDepositName = "eth_deposit" + TestERC20WithdrawName = "erc20_withdraw" + TestERC20DepositName = "erc20_deposit" + TestEtherDepositName = "eth_deposit" + TestEtherWithdrawName = "eth_withdraw" + TestBitcoinDepositName = "bitcoin_deposit" + TestZetaDepositName = "zeta_deposit" + + TestDonationEtherName = "donation_ether" + + TestStressEtherWithdrawName = "stress_eth_withdraw" + TestStressBTCWithdrawName = "stress_btc_withdraw" + TestStressEtherDepositName = "stress_eth_deposit" + TestStressBTCDepositName = "stress_btc_deposit" ) // AllSmokeTests is an ordered list of all smoke tests @@ -45,24 +55,29 @@ var AllSmokeTests = []runner.SmokeTest{ TestMultipleERC20Deposit, }, { - TestWithdrawERC20Name, - "withdraw USDT ERC20 from ZEVM", - TestWithdrawERC20, + TestERC20WithdrawName, + "withdraw ERC20 from ZEVM", + TestERC20Withdraw, }, { TestMultipleWithdrawsName, - "withdraw USDT ERC20 from ZEVM in multiple deposits", + "withdraw ERC20 from ZEVM in multiple deposits", TestMultipleWithdraws, }, { - TestSendZetaOutName, - "sending ZETA from ZEVM to Ethereum", - TestSendZetaOut, + TestZetaWithdrawName, + "withdraw ZETA from ZEVM to Ethereum", + TestZetaWithdraw, }, { - TestSendZetaOutBTCRevertName, - "sending ZETA from ZEVM to Bitcoin; should revert when ", - TestSendZetaOutBTCRevert, + TestZetaDepositName, + "deposit ZETA from Ethereum to ZEVM", + TestZetaDeposit, + }, + { + TestZetaWithdrawBTCRevertName, + "sending ZETA from ZEVM to Bitcoin with a message that should revert cctxs", + TestZetaWithdrawBTCRevert, }, { TestMessagePassingName, @@ -101,7 +116,7 @@ var AllSmokeTests = []runner.SmokeTest{ }, { TestERC20DepositAndCallRefundName, - "deposit a non-gas ZRC20 into ZEVM and call a contract that reverts; should refund on ZetaChain if no liquidity pool, should refund on origin if liquidity pool", + "deposit a non-gas ZRC20 into ZEVM and call a contract that reverts", TestERC20DepositAndCallRefund, }, { @@ -134,4 +149,39 @@ var AllSmokeTests = []runner.SmokeTest{ "deposit Ether into ZEVM", TestEtherDeposit, }, + { + TestEtherWithdrawName, + "withdraw Ether from ZEVM", + TestEtherWithdraw, + }, + { + TestBitcoinDepositName, + "deposit Bitcoin into ZEVM", + TestBitcoinDeposit, + }, + { + TestDonationEtherName, + "donate Ether to the TSS", + TestDonationEther, + }, + { + TestStressEtherWithdrawName, + "stress test Ether withdrawal", + TestStressEtherWithdraw, + }, + { + TestStressBTCWithdrawName, + "stress test BTC withdrawal", + TestStressBTCWithdraw, + }, + { + TestStressEtherDepositName, + "stress test Ether deposit", + TestStressEtherDeposit, + }, + { + TestStressBTCDepositName, + "stress test BTC deposit", + TestStressBTCDeposit, + }, } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_deposit.go new file mode 100644 index 0000000000..c16834725b --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_deposit.go @@ -0,0 +1,27 @@ +package smoketests + +import ( + "fmt" + + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestBitcoinDeposit(sm *runner.SmokeTestRunner) { + + sm.SetBtcAddress(sm.Name, false) + + txHash := sm.DepositBTCWithAmount(0.001) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, txHash.String(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "deposit") + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + panic(fmt.Sprintf( + "expected mined status; got %s, message: %s", + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage), + ) + } +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_withdraw.go similarity index 100% rename from contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin.go rename to contrib/localnet/orchestrator/smoketest/smoketests/test_bitcoin_withdraw.go diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go index 1a1ce1aa3c..803d5b6a7c 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_crosschain_swap.go @@ -230,7 +230,7 @@ func TestCrosschainSwap(sm *runner.SmokeTestRunner) { sm.Logger.Info(" vout %d", vout.N) sm.Logger.Info(" value %f", vout.Value) sm.Logger.Info(" scriptPubKey %s", vout.ScriptPubKey.Hex) - sm.Logger.Info(" p2wpkh address: %s", utils.ScriptPKToAddress(vout.ScriptPubKey.Hex)) + sm.Logger.Info(" p2wpkh address: %s", utils.ScriptPKToAddress(vout.ScriptPubKey.Hex, sm.BitcoinParams)) } } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_donation.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_donation.go new file mode 100644 index 0000000000..a81af67f3f --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_donation.go @@ -0,0 +1,25 @@ +package smoketests + +import ( + "math/big" + + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + "github.com/zeta-chain/zetacore/zetaclient" +) + +// TestDonationEther tests donation of ether to the tss address +func TestDonationEther(sm *runner.SmokeTestRunner) { + txDonation, err := sm.SendEther(sm.TSSAddress, big.NewInt(100000000000000000), []byte(zetaclient.DonationMessage)) + if err != nil { + panic(err) + } + sm.Logger.EVMTransaction(*txDonation, "donation") + + // check contract deployment receipt + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, txDonation, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "donation") + if receipt.Status != 1 { + panic("donation tx failed") + } +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_deposit.go index d9439331e9..2c3a47eddf 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_deposit.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_deposit.go @@ -1,81 +1,16 @@ package smoketests import ( - "fmt" "math/big" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" - testcontract "github.com/zeta-chain/zetacore/testutil/contracts" ) func TestERC20Deposit(sm *runner.SmokeTestRunner) { - sm.DepositERC20() -} - -func TestMultipleERC20Deposit(sm *runner.SmokeTestRunner) { - initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) - if err != nil { - panic(err) - } - txhash := MultipleDeposits(sm, big.NewInt(1e9), big.NewInt(3)) - cctxs := utils.WaitCctxsMinedByInTxHash(sm.Ctx, txhash.Hex(), sm.CctxClient, 3, sm.Logger, sm.CctxTimeout) - if len(cctxs) != 3 { - panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) - } - - // check new balance is increased by 1e9 * 3 - bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) - if err != nil { - panic(err) - } - diff := big.NewInt(0).Sub(bal, initialBal) - if diff.Int64() != 3e9 { - panic(fmt.Sprintf("balance difference is not correct: %d", diff.Int64())) - } -} - -func MultipleDeposits(sm *runner.SmokeTestRunner, amount, count *big.Int) ethcommon.Hash { - // deploy depositor - depositorAddr, _, depositor, err := testcontract.DeployDepositor(sm.GoerliAuth, sm.GoerliClient, sm.ERC20CustodyAddr) - if err != nil { - panic(err) - } - - fullAmount := big.NewInt(0).Mul(amount, count) - - // approve - tx, err := sm.USDTERC20.Approve(sm.GoerliAuth, depositorAddr, fullAmount) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } - sm.Logger.Info("USDT Approve receipt tx hash: %s", tx.Hash().Hex()) - - // deposit - tx, err = depositor.RunDeposits(sm.GoerliAuth, sm.DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, []byte{}, count) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposits failed") - } - sm.Logger.Info("Deposits receipt tx hash: %s", tx.Hash().Hex()) + hash := sm.DepositERC20WithAmountAndMessage(big.NewInt(100000), []byte{}) - for _, log := range receipt.Logs { - event, err := sm.ERC20Custody.ParseDeposited(*log) - if err != nil { - continue - } - sm.Logger.Info("Multiple deposit event: ") - sm.Logger.Info(" Amount: %d, ", event.Amount) - } - sm.Logger.Info("gas limit %d", sm.ZevmAuth.GasLimit) - return tx.Hash() + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, hash.Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "deposit") } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_deposits.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_deposits.go new file mode 100644 index 0000000000..5af6a9f693 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_deposits.go @@ -0,0 +1,77 @@ +package smoketests + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + testcontract "github.com/zeta-chain/zetacore/testutil/contracts" +) + +func TestMultipleERC20Deposit(sm *runner.SmokeTestRunner) { + initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + panic(err) + } + txhash := MultipleDeposits(sm, big.NewInt(1e9), big.NewInt(3)) + cctxs := utils.WaitCctxsMinedByInTxHash(sm.Ctx, txhash.Hex(), sm.CctxClient, 3, sm.Logger, sm.CctxTimeout) + if len(cctxs) != 3 { + panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) + } + + // check new balance is increased by 1e9 * 3 + bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + panic(err) + } + diff := big.NewInt(0).Sub(bal, initialBal) + if diff.Int64() != 3e9 { + panic(fmt.Sprintf("balance difference is not correct: %d", diff.Int64())) + } +} + +func MultipleDeposits(sm *runner.SmokeTestRunner, amount, count *big.Int) ethcommon.Hash { + // deploy depositor + depositorAddr, _, depositor, err := testcontract.DeployDepositor(sm.GoerliAuth, sm.GoerliClient, sm.ERC20CustodyAddr) + if err != nil { + panic(err) + } + + fullAmount := big.NewInt(0).Mul(amount, count) + + // approve + tx, err := sm.USDTERC20.Approve(sm.GoerliAuth, depositorAddr, fullAmount) + if err != nil { + panic(err) + } + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("approve failed") + } + sm.Logger.Info("USDT Approve receipt tx hash: %s", tx.Hash().Hex()) + + // deposit + tx, err = depositor.RunDeposits(sm.GoerliAuth, sm.DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, []byte{}, count) + if err != nil { + panic(err) + } + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.GoerliClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("deposits failed") + } + sm.Logger.Info("Deposits receipt tx hash: %s", tx.Hash().Hex()) + + for _, log := range receipt.Logs { + event, err := sm.ERC20Custody.ParseDeposited(*log) + if err != nil { + continue + } + sm.Logger.Info("Multiple deposit event: ") + sm.Logger.Info(" Amount: %d, ", event.Amount) + } + sm.Logger.Info("gas limit %d", sm.ZevmAuth.GasLimit) + return tx.Hash() +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_withdraws.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_withdraws.go new file mode 100644 index 0000000000..60fa01e6b4 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_multiple_withdraws.go @@ -0,0 +1,78 @@ +package smoketests + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + testcontract "github.com/zeta-chain/zetacore/testutil/contracts" +) + +func TestMultipleWithdraws(sm *runner.SmokeTestRunner) { + // deploy withdrawer + withdrawerAddr, _, withdrawer, err := testcontract.DeployWithdrawer(sm.ZevmAuth, sm.ZevmClient) + if err != nil { + panic(err) + } + + // approve + tx, err := sm.USDTZRC20.Approve(sm.ZevmAuth, withdrawerAddr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("approve failed") + } + sm.Logger.Info("USDT ZRC20 approve receipt: status %d", receipt.Status) + + // approve gas token + tx, err = sm.ETHZRC20.Approve(sm.ZevmAuth, withdrawerAddr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("approve gas token failed") + } + sm.Logger.Info("eth zrc20 approve receipt: status %d", receipt.Status) + + // check the balance + bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) + if err != nil { + panic(err) + } + sm.Logger.Info("balance of deployer on USDT ZRC20: %d", bal) + + if bal.Int64() < 1000 { + panic("not enough USDT ZRC20 balance!") + } + + // withdraw + tx, err = withdrawer.RunWithdraws( + sm.ZevmAuth, + sm.DeployerAddress.Bytes(), + sm.USDTZRC20Addr, + big.NewInt(100), + big.NewInt(3), + ) + if err != nil { + panic(err) + } + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("withdraw failed") + } + + cctxs := utils.WaitCctxsMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), sm.CctxClient, 3, sm.Logger, sm.CctxTimeout) + if len(cctxs) != 3 { + panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) + } + + // verify the withdraw value + for _, cctx := range cctxs { + verifyTransferAmountFromCCTX(sm, cctx, 100) + } +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_refund.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_refund.go index 7834baacfa..dcfc86acc1 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_refund.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_refund.go @@ -32,6 +32,7 @@ func TestERC20DepositAndCallRefund(sm *runner.SmokeTestRunner) { // There is no liquidity pool, therefore the cctx should abort cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, inTxHash, sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "deposit") if cctx.CctxStatus.Status != types.CctxStatus_Aborted { panic(fmt.Sprintf("expected cctx status to be Aborted; got %s", cctx.CctxStatus.Status)) } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_withdraw.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_withdraw.go index 4dad98d96a..793c718c12 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_withdraw.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_erc20_withdraw.go @@ -1,18 +1,15 @@ package smoketests import ( - "fmt" "math/big" - "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" - testcontract "github.com/zeta-chain/zetacore/testutil/contracts" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) -func TestWithdrawERC20(sm *runner.SmokeTestRunner) { +func TestERC20Withdraw(sm *runner.SmokeTestRunner) { // approve tx, err := sm.ETHZRC20.Approve(sm.ZevmAuth, sm.USDTZRC20Addr, big.NewInt(1e18)) if err != nil { @@ -25,7 +22,7 @@ func TestWithdrawERC20(sm *runner.SmokeTestRunner) { sm.Logger.Info("eth zrc20 approve receipt: status %d", receipt.Status) // withdraw - tx, err = sm.USDTZRC20.Withdraw(sm.ZevmAuth, sm.DeployerAddress.Bytes(), big.NewInt(100)) + tx, err = sm.USDTZRC20.Withdraw(sm.ZevmAuth, sm.DeployerAddress.Bytes(), big.NewInt(1000)) if err != nil { panic(err) } @@ -47,74 +44,7 @@ func TestWithdrawERC20(sm *runner.SmokeTestRunner) { // verify the withdraw value cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, receipt.TxHash.Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) - verifyTransferAmountFromCCTX(sm, cctx, 100) -} - -func TestMultipleWithdraws(sm *runner.SmokeTestRunner) { - // deploy withdrawer - withdrawerAddr, _, withdrawer, err := testcontract.DeployWithdrawer(sm.ZevmAuth, sm.ZevmClient) - if err != nil { - panic(err) - } - - // approve - tx, err := sm.USDTZRC20.Approve(sm.ZevmAuth, withdrawerAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } - sm.Logger.Info("USDT ZRC20 approve receipt: status %d", receipt.Status) - - // approve gas token - tx, err = sm.ETHZRC20.Approve(sm.ZevmAuth, withdrawerAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve gas token failed") - } - sm.Logger.Info("eth zrc20 approve receipt: status %d", receipt.Status) - - // check the balance - bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, sm.DeployerAddress) - if err != nil { - panic(err) - } - sm.Logger.Info("balance of deployer on USDT ZRC20: %d", bal) - - if bal.Int64() < 1000 { - panic("not enough USDT ZRC20 balance!") - } - - // withdraw - tx, err = withdrawer.RunWithdraws( - sm.ZevmAuth, - sm.DeployerAddress.Bytes(), - sm.USDTZRC20Addr, - big.NewInt(100), - big.NewInt(3), - ) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) - if receipt.Status == 0 { - panic("withdraw failed") - } - - cctxs := utils.WaitCctxsMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), sm.CctxClient, 3, sm.Logger, sm.CctxTimeout) - if len(cctxs) != 3 { - panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) - } - - // verify the withdraw value - for _, cctx := range cctxs { - verifyTransferAmountFromCCTX(sm, cctx, 100) - } + verifyTransferAmountFromCCTX(sm, cctx, 1000) } // verifyTransferAmountFromCCTX verifies the transfer amount from the CCTX on Goerli diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_deposit_eth.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_eth_deposit.go similarity index 96% rename from contrib/localnet/orchestrator/smoketest/smoketests/test_deposit_eth.go rename to contrib/localnet/orchestrator/smoketest/smoketests/test_eth_deposit.go index 444009af35..44146e53cd 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_deposit_eth.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_eth_deposit.go @@ -18,6 +18,15 @@ import ( fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" ) +// TestEtherDeposit tests deposit of ethers +func TestEtherDeposit(sm *runner.SmokeTestRunner) { + hash := sm.DepositEtherWithAmount(false, big.NewInt(10000000000000000)) // in wei (0.01 eth) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, hash.Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "deposit") +} + // TestEtherDepositAndCall tests deposit of ethers calling a example contract func TestEtherDepositAndCall(sm *runner.SmokeTestRunner) { sm.Logger.Info("Deploying example contract") diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_eth_withdraw.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_eth_withdraw.go new file mode 100644 index 0000000000..1629eede7e --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_eth_withdraw.go @@ -0,0 +1,46 @@ +package smoketests + +import ( + "math/big" + + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +// TestEtherWithdraw tests the withdraw of ether +func TestEtherWithdraw(sm *runner.SmokeTestRunner) { + // approve + tx, err := sm.ETHZRC20.Approve(sm.ZevmAuth, sm.ETHZRC20Addr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + sm.Logger.EVMTransaction(*tx, "approve") + + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("approve failed") + } + sm.Logger.EVMReceipt(*receipt, "approve") + + // withdraw + tx, err = sm.ETHZRC20.Withdraw(sm.ZevmAuth, sm.DeployerAddress.Bytes(), big.NewInt(100000)) + if err != nil { + panic(err) + } + sm.Logger.EVMTransaction(*tx, "withdraw") + + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + panic("withdraw failed") + } + sm.Logger.EVMReceipt(*receipt, "withdraw") + sm.Logger.ZRC20Withdrawal(sm.ETHZRC20, *receipt, "withdraw") + + // verify the withdraw value + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, receipt.TxHash.Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "withdraw") + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + panic("cctx status is not outbound mined") + } +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_ether_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_ether_deposit.go deleted file mode 100644 index 4a600ffc84..0000000000 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_ether_deposit.go +++ /dev/null @@ -1,7 +0,0 @@ -package smoketests - -import "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - -func TestEtherDeposit(sm *runner.SmokeTestRunner) { - sm.DepositEther(false) -} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_message_passing.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_message_passing.go index 0ca5ae987b..ea6b5473bd 100644 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_message_passing.go +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_message_passing.go @@ -14,6 +14,11 @@ import ( ) func TestMessagePassing(sm *runner.SmokeTestRunner) { + chainID, err := sm.GoerliClient.ChainID(sm.Ctx) + if err != nil { + panic(err) + } + sm.Logger.Info("Approving ConnectorEth to spend deployer's ZetaEth") amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(10)) // 10 Zeta @@ -31,7 +36,7 @@ func TestMessagePassing(sm *runner.SmokeTestRunner) { sm.Logger.Info("Approve tx receipt: %d", receipt.Status) sm.Logger.Info("Calling ConnectorEth.Send") tx, err = sm.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ - DestinationChainId: big.NewInt(1337), // in dev mode, GOERLI has chainid 1337 + DestinationChainId: chainID, DestinationAddress: sm.DeployerAddress.Bytes(), DestinationGasLimit: big.NewInt(400_000), Message: nil, @@ -92,7 +97,10 @@ func TestMessagePassing(sm *runner.SmokeTestRunner) { } func TestMessagePassingRevertFail(sm *runner.SmokeTestRunner) { - sm.Logger.Info("Approving ConnectorEth to spend deployer's ZetaEth") + chainID, err := sm.GoerliClient.ChainID(sm.Ctx) + if err != nil { + panic(err) + } amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(10)) // 10 Zeta @@ -109,7 +117,7 @@ func TestMessagePassingRevertFail(sm *runner.SmokeTestRunner) { sm.Logger.Info("Approve tx receipt: %d", receipt.Status) sm.Logger.Info("Calling ConnectorEth.Send") tx, err = sm.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ - DestinationChainId: big.NewInt(1337), // in dev mode, GOERLI has chainid 1337 + DestinationChainId: chainID, DestinationAddress: sm.DeployerAddress.Bytes(), DestinationGasLimit: big.NewInt(400_000), Message: []byte("revert"), // non-empty message will cause revert, because the dest address is not a contract @@ -152,7 +160,10 @@ func TestMessagePassingRevertFail(sm *runner.SmokeTestRunner) { } func TestMessagePassingRevertSuccess(sm *runner.SmokeTestRunner) { - sm.Logger.Info("Approving TestDApp to spend deployer's ZetaEth") + chainID, err := sm.GoerliClient.ChainID(sm.Ctx) + if err != nil { + panic(err) + } amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(10)) // 10 Zeta @@ -184,7 +195,7 @@ func TestMessagePassingRevertSuccess(sm *runner.SmokeTestRunner) { } sm.Logger.Info("$$$ Before: SUPPLY OF AZETA: %d", res2.Amount.Amount) - tx, err = testDApp.SendHelloWorld(auth, sm.TestDAppAddr, big.NewInt(1337), amount, true) + tx, err = testDApp.SendHelloWorld(auth, sm.TestDAppAddr, chainID, amount, true) if err != nil { panic(err) } diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_deposit.go new file mode 100644 index 0000000000..7c4e3d680c --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_deposit.go @@ -0,0 +1,62 @@ +package smoketests + +import ( + "fmt" + "time" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "golang.org/x/sync/errgroup" +) + +// TestStressBTCDeposit tests the stressing deposit of BTC +func TestStressBTCDeposit(sm *runner.SmokeTestRunner) { + // number of deposits to perform + numDeposits := 100 + + sm.SetBtcAddress(sm.Name, false) + + sm.Logger.Print("starting stress test of %d deposits", numDeposits) + + // create a wait group to wait for all the deposits to complete + var eg errgroup.Group + + // send the deposits + for i := 0; i < numDeposits; i++ { + i := i + txHash := sm.DepositBTCWithAmount(0.001) + sm.Logger.Print("index %d: starting deposit, tx hash: %s", i, txHash.String()) + + eg.Go(func() error { + return MonitorBTCDeposit(sm, txHash, i, time.Now()) + }) + } + + // wait for all the deposits to complete + if err := eg.Wait(); err != nil { + panic(err) + } + + sm.Logger.Print("all deposits completed") +} + +// MonitorBTCDeposit monitors the deposit of BTC, returns once the deposit is complete +func MonitorBTCDeposit(sm *runner.SmokeTestRunner, hash *chainhash.Hash, index int, startTime time.Time) error { + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, hash.String(), sm.CctxClient, sm.Logger, sm.ReceiptTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + return fmt.Errorf( + "index %d: deposit cctx failed with status %s, message %s, cctx index %s", + index, + cctx.CctxStatus.Status, + cctx.CctxStatus.StatusMessage, + cctx.Index, + ) + } + timeToComplete := time.Now().Sub(startTime) + sm.Logger.Print("index %d: deposit cctx success in %s", index, timeToComplete.String()) + + return nil +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_withdraw.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_withdraw.go new file mode 100644 index 0000000000..38b692a7e9 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_btc_withdraw.go @@ -0,0 +1,73 @@ +package smoketests + +import ( + "fmt" + "math/big" + "time" + + "github.com/btcsuite/btcutil" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "golang.org/x/sync/errgroup" +) + +// TestStressBTCWithdraw tests the stressing withdraw of btc +func TestStressBTCWithdraw(sm *runner.SmokeTestRunner) { + // number of withdraws to perform + numWithdraws := 100 + + sm.Logger.Print("starting stress test of %d withdraws", numWithdraws) + + // create a wait group to wait for all the withdraws to complete + var eg errgroup.Group + + // send the withdraws + for i := 0; i < numWithdraws; i++ { + i := i + tx, err := sm.BTCZRC20.Withdraw( + sm.ZevmAuth, + []byte(sm.BTCDeployerAddress.EncodeAddress()), + big.NewInt(0.01*btcutil.SatoshiPerBitcoin), + ) + if err != nil { + panic(err) + } + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + //sm.Logger.Info("index %d: withdraw evm tx failed", index) + panic(fmt.Sprintf("index %d: withdraw btc tx %s failed", i, tx.Hash().Hex())) + } + sm.Logger.Print("index %d: starting withdraw, tx hash: %s", i, tx.Hash().Hex()) + + eg.Go(func() error { + return MonitorBTCWithdraw(sm, tx, i, time.Now()) + }) + } + + // wait for all the withdraws to complete + if err := eg.Wait(); err != nil { + panic(err) + } + + sm.Logger.Print("all withdraws completed") +} + +// MonitorBTCWithdraw monitors the withdraw of BTC, returns once the withdraw is complete +func MonitorBTCWithdraw(sm *runner.SmokeTestRunner, tx *ethtypes.Transaction, index int, startTime time.Time) error { + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), sm.CctxClient, sm.Logger, sm.ReceiptTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + return fmt.Errorf( + "index %d: withdraw cctx failed with status %s, message %s, cctx index %s", + index, + cctx.CctxStatus.Status, + cctx.CctxStatus.StatusMessage, + cctx.Index, + ) + } + timeToComplete := time.Now().Sub(startTime) + sm.Logger.Print("index %d: withdraw cctx success in %s", index, timeToComplete.String()) + + return nil +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_deposit.go new file mode 100644 index 0000000000..d12ba4efde --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_deposit.go @@ -0,0 +1,60 @@ +package smoketests + +import ( + "fmt" + "math/big" + "time" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "golang.org/x/sync/errgroup" +) + +// TestStressEtherDeposit tests the stressing deposit of ether +func TestStressEtherDeposit(sm *runner.SmokeTestRunner) { + // number of deposits to perform + numDeposits := 100 + + sm.Logger.Print("starting stress test of %d deposits", numDeposits) + + // create a wait group to wait for all the deposits to complete + var eg errgroup.Group + + // send the deposits + for i := 0; i < numDeposits; i++ { + i := i + hash := sm.DepositERC20WithAmountAndMessage(big.NewInt(100000), []byte{}) + sm.Logger.Print("index %d: starting deposit, tx hash: %s", i, hash.Hex()) + + eg.Go(func() error { + return MonitorEtherDeposit(sm, hash, i, time.Now()) + }) + } + + // wait for all the deposits to complete + if err := eg.Wait(); err != nil { + panic(err) + } + + sm.Logger.Print("all deposits completed") +} + +// MonitorEtherDeposit monitors the deposit of ether, returns once the deposit is complete +func MonitorEtherDeposit(sm *runner.SmokeTestRunner, hash ethcommon.Hash, index int, startTime time.Time) error { + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, hash.Hex(), sm.CctxClient, sm.Logger, sm.ReceiptTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + return fmt.Errorf( + "index %d: deposit cctx failed with status %s, message %s, cctx index %s", + index, + cctx.CctxStatus.Status, + cctx.CctxStatus.StatusMessage, + cctx.Index, + ) + } + timeToComplete := time.Now().Sub(startTime) + sm.Logger.Print("index %d: deposit cctx success in %s", index, timeToComplete.String()) + + return nil +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_withdraw.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_withdraw.go new file mode 100644 index 0000000000..a8802a0f8f --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_stress_eth_withdraw.go @@ -0,0 +1,69 @@ +package smoketests + +import ( + "fmt" + "math/big" + "time" + + "golang.org/x/sync/errgroup" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +// TestStressEtherWithdraw tests the stressing withdraw of ether +func TestStressEtherWithdraw(sm *runner.SmokeTestRunner) { + // number of withdraws to perform + numWithdraws := 100 + + sm.Logger.Print("starting stress test of %d withdraws", numWithdraws) + + // create a wait group to wait for all the withdraws to complete + var eg errgroup.Group + + // send the withdraws + for i := 0; i < numWithdraws; i++ { + i := i + tx, err := sm.ETHZRC20.Withdraw(sm.ZevmAuth, sm.DeployerAddress.Bytes(), big.NewInt(100000)) + if err != nil { + panic(err) + } + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + if receipt.Status == 0 { + //sm.Logger.Info("index %d: withdraw evm tx failed", index) + panic(fmt.Sprintf("index %d: withdraw evm tx %s failed", i, tx.Hash().Hex())) + } + sm.Logger.Print("index %d: starting withdraw, tx hash: %s", i, tx.Hash().Hex()) + + eg.Go(func() error { + return MonitorEtherWithdraw(sm, tx, i, time.Now()) + }) + } + + // wait for all the withdraws to complete + if err := eg.Wait(); err != nil { + panic(err) + } + + sm.Logger.Print("all withdraws completed") +} + +// MonitorEtherWithdraw monitors the withdraw of ether, returns once the withdraw is complete +func MonitorEtherWithdraw(sm *runner.SmokeTestRunner, tx *ethtypes.Transaction, index int, startTime time.Time) error { + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), sm.CctxClient, sm.Logger, sm.ReceiptTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + return fmt.Errorf( + "index %d: withdraw cctx failed with status %s, message %s, cctx index %s", + index, + cctx.CctxStatus.Status, + cctx.CctxStatus.StatusMessage, + cctx.Index, + ) + } + timeToComplete := time.Now().Sub(startTime) + sm.Logger.Print("index %d: withdraw cctx success in %s", index, timeToComplete.String()) + + return nil +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_deposit.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_deposit.go new file mode 100644 index 0000000000..886103b32f --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_deposit.go @@ -0,0 +1,17 @@ +package smoketests + +import ( + "math/big" + + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" +) + +func TestZetaDeposit(sm *runner.SmokeTestRunner) { + // Deposit 1 Zeta + hash := sm.DepositZetaWithAmount(big.NewInt(1e18)) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, hash.Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "deposit") +} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_in_and_out.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_in_and_out.go deleted file mode 100644 index 7db514951a..0000000000 --- a/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_in_and_out.go +++ /dev/null @@ -1,172 +0,0 @@ -package smoketests - -import ( - "fmt" - "math/big" - - cctxtypes "github.com/zeta-chain/zetacore/x/crosschain/types" - - ethcommon "github.com/ethereum/go-ethereum/common" - connectorzevm "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" - wzeta "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" - "github.com/zeta-chain/zetacore/common" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" -) - -func TestSendZetaOut(sm *runner.SmokeTestRunner) { - zevmClient := sm.ZevmClient - cctxClient := sm.CctxClient - - ConnectorZEVMAddr := ethcommon.HexToAddress("0x239e96c8f17C85c30100AC26F635Ea15f23E9c67") - ConnectorZEVM, err := connectorzevm.NewZetaConnectorZEVM(ConnectorZEVMAddr, zevmClient) - if err != nil { - panic(err) - } - - wzetaAddr := ethcommon.HexToAddress("0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf") - wZeta, err := wzeta.NewWETH9(wzetaAddr, zevmClient) - if err != nil { - panic(err) - } - zchainid, err := zevmClient.ChainID(sm.Ctx) - if err != nil { - panic(err) - } - sm.Logger.Info("zevm chainid: %d", zchainid) - - // 10 Zeta - amount := big.NewInt(1e18) - amount = amount.Mul(amount, big.NewInt(10)) - - zauth := sm.ZevmAuth - zauth.Value = amount - tx, err := wZeta.Deposit(zauth) - if err != nil { - panic(err) - } - zauth.Value = big.NewInt(0) - sm.Logger.Info("Deposit tx hash: %s", tx.Hash().Hex()) - - receipt := utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("Deposit tx receipt: status %d", receipt.Status) - - tx, err = wZeta.Approve(zauth, ConnectorZEVMAddr, amount) - if err != nil { - panic(err) - } - sm.Logger.Info("wzeta.approve tx hash: %s", tx.Hash().Hex()) - receipt = utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("approve tx receipt: status %d", receipt.Status) - tx, err = ConnectorZEVM.Send(zauth, connectorzevm.ZetaInterfacesSendInput{ - DestinationChainId: big.NewInt(1337), - DestinationAddress: sm.DeployerAddress.Bytes(), - DestinationGasLimit: big.NewInt(400_000), - Message: nil, - ZetaValueAndGas: amount, - ZetaParams: nil, - }) - if err != nil { - panic(err) - } - sm.Logger.Info("send tx hash: %s", tx.Hash().Hex()) - receipt = utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("send tx receipt: status %d", receipt.Status) - sm.Logger.Info(" Logs:") - for _, log := range receipt.Logs { - sentLog, err := ConnectorZEVM.ParseZetaSent(*log) - if err == nil { - sm.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) - sm.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) - sm.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) - sm.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) - } - } - sm.Logger.Info("waiting for cctx status to change to final...") - - cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), cctxClient, sm.Logger, sm.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { - panic(fmt.Errorf( - "expected cctx status to be %s; got %s, message %s", - cctxtypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } - receipt, err = sm.GoerliClient.TransactionReceipt(sm.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutTxParam().OutboundTxHash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic(fmt.Errorf("tx failed")) - } - for _, log := range receipt.Logs { - event, err := sm.ConnectorEth.ParseZetaReceived(*log) - if err == nil { - sm.Logger.Info(" Dest Addr: %s", event.DestinationAddress.Hex()) - sm.Logger.Info(" sender addr: %x", event.ZetaTxSenderAddress) - sm.Logger.Info(" Zeta Value: %d", event.ZetaValue) - if event.ZetaValue.Cmp(amount) != -1 { - panic("wrong zeta value, gas should be paid in the amount") - } - } - } -} - -func TestSendZetaOutBTCRevert(sm *runner.SmokeTestRunner) { - zevmClient := sm.ZevmClient - - ConnectorZEVMAddr := ethcommon.HexToAddress("0x239e96c8f17C85c30100AC26F635Ea15f23E9c67") - ConnectorZEVM, err := connectorzevm.NewZetaConnectorZEVM(ConnectorZEVMAddr, zevmClient) - if err != nil { - panic(err) - } - - wzetaAddr := ethcommon.HexToAddress("0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf") - wZeta, err := wzeta.NewWETH9(wzetaAddr, zevmClient) - if err != nil { - panic(err) - } - zchainid, err := zevmClient.ChainID(sm.Ctx) - if err != nil { - panic(err) - } - sm.Logger.Info("zevm chainid: %d", zchainid) - - zauth := sm.ZevmAuth - zauth.Value = big.NewInt(1e18) - tx, err := wZeta.Deposit(zauth) - if err != nil { - panic(err) - } - zauth.Value = big.NewInt(0) - - sm.Logger.Info("Deposit tx hash: %s", tx.Hash().Hex()) - receipt := utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("Deposit tx receipt: status %d", receipt.Status) - - tx, err = wZeta.Approve(zauth, ConnectorZEVMAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } - sm.Logger.Info("wzeta.approve tx hash: %s", tx.Hash().Hex()) - receipt = utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("approve tx receipt: status %d", receipt.Status) - tx, err = ConnectorZEVM.Send(zauth, connectorzevm.ZetaInterfacesSendInput{ - DestinationChainId: big.NewInt(common.BtcRegtestChain().ChainId), - DestinationAddress: sm.DeployerAddress.Bytes(), - DestinationGasLimit: big.NewInt(400_000), - Message: nil, - ZetaValueAndGas: big.NewInt(1e17), - ZetaParams: nil, - }) - if err != nil { - panic(err) - } - sm.Logger.Info("send tx hash: %s", tx.Hash().Hex()) - receipt = utils.MustWaitForTxReceipt(sm.Ctx, zevmClient, tx, sm.Logger, sm.ReceiptTimeout) - sm.Logger.Info("send tx receipt: status %d", receipt.Status) - if receipt.Status != 0 { - panic("Was able to send ZETA to BTC") - } -} diff --git a/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_withdraw.go b/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_withdraw.go new file mode 100644 index 0000000000..8f9fa959ec --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/smoketests/test_zeta_withdraw.go @@ -0,0 +1,138 @@ +package smoketests + +import ( + "fmt" + "math/big" + + cctxtypes "github.com/zeta-chain/zetacore/x/crosschain/types" + + ethcommon "github.com/ethereum/go-ethereum/common" + connectorzevm "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/connectorzevm.sol" + "github.com/zeta-chain/zetacore/common" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/runner" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/utils" +) + +func TestZetaWithdraw(sm *runner.SmokeTestRunner) { + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10 Zeta + + sm.ZevmAuth.Value = amount + tx, err := sm.WZeta.Deposit(sm.ZevmAuth) + if err != nil { + panic(err) + } + sm.ZevmAuth.Value = big.NewInt(0) + sm.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) + + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "wzeta deposit") + if receipt.Status == 0 { + panic("deposit failed") + } + + chainID, err := sm.GoerliClient.ChainID(sm.Ctx) + if err != nil { + panic(err) + } + + tx, err = sm.WZeta.Approve(sm.ZevmAuth, sm.ConnectorZEVMAddr, amount) + if err != nil { + panic(err) + } + sm.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) + + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "wzeta approve") + if receipt.Status == 0 { + panic(fmt.Sprintf("approve failed, logs: %+v", receipt.Logs)) + } + + tx, err = sm.ConnectorZEVM.Send(sm.ZevmAuth, connectorzevm.ZetaInterfacesSendInput{ + DestinationChainId: chainID, + DestinationAddress: sm.DeployerAddress.Bytes(), + DestinationGasLimit: big.NewInt(400_000), + Message: nil, + ZetaValueAndGas: amount, + ZetaParams: nil, + }) + if err != nil { + panic(err) + } + sm.Logger.Info("send tx hash: %s", tx.Hash().Hex()) + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "send") + if receipt.Status == 0 { + panic(fmt.Sprintf("send failed, logs: %+v", receipt.Logs)) + + } + + sm.Logger.Info(" Logs:") + for _, log := range receipt.Logs { + sentLog, err := sm.ConnectorZEVM.ParseZetaSent(*log) + if err == nil { + sm.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) + sm.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) + sm.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) + sm.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) + } + } + sm.Logger.Info("waiting for cctx status to change to final...") + + cctx := utils.WaitCctxMinedByInTxHash(sm.Ctx, tx.Hash().Hex(), sm.CctxClient, sm.Logger, sm.CctxTimeout) + sm.Logger.CCTX(*cctx, "zeta withdraw") + if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { + panic(fmt.Errorf( + "expected cctx status to be %s; got %s, message %s", + cctxtypes.CctxStatus_OutboundMined, + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage, + )) + } +} + +func TestZetaWithdrawBTCRevert(sm *runner.SmokeTestRunner) { + sm.ZevmAuth.Value = big.NewInt(1e18) // 1 Zeta + tx, err := sm.WZeta.Deposit(sm.ZevmAuth) + if err != nil { + panic(err) + } + sm.ZevmAuth.Value = big.NewInt(0) + sm.Logger.Info("Deposit tx hash: %s", tx.Hash().Hex()) + + receipt := utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "Deposit") + if receipt.Status != 1 { + panic("Deposit failed") + } + + tx, err = sm.WZeta.Approve(sm.ZevmAuth, sm.ConnectorZEVMAddr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + sm.Logger.Info("wzeta.approve tx hash: %s", tx.Hash().Hex()) + + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "Approve") + if receipt.Status != 1 { + panic("Approve failed") + } + + tx, err = sm.ConnectorZEVM.Send(sm.ZevmAuth, connectorzevm.ZetaInterfacesSendInput{ + DestinationChainId: big.NewInt(common.BtcRegtestChain().ChainId), + DestinationAddress: sm.DeployerAddress.Bytes(), + DestinationGasLimit: big.NewInt(400_000), + Message: nil, + ZetaValueAndGas: big.NewInt(1e17), + ZetaParams: nil, + }) + if err != nil { + panic(err) + } + sm.Logger.Info("send tx hash: %s", tx.Hash().Hex()) + + receipt = utils.MustWaitForTxReceipt(sm.Ctx, sm.ZevmClient, tx, sm.Logger, sm.ReceiptTimeout) + sm.Logger.EVMReceipt(*receipt, "send") + if receipt.Status != 0 { + panic("Was able to send ZETA to BTC") + } +} diff --git a/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go b/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go index f742641b38..d43cbd7fe6 100644 --- a/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go +++ b/contrib/localnet/orchestrator/smoketest/txserver/zeta_tx_server.go @@ -168,42 +168,54 @@ func (zts ZetaTxServer) BroadcastTx(account string, msg sdktypes.Msg) (*sdktypes // DeploySystemContractsAndZRC20 deploys the system contracts and ZRC20 contracts // returns the addresses of uniswap factory, router and usdt zrc20 -func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr string) (string, string, string, error) { +func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr string) (string, string, string, string, string, error) { // retrieve account acc, err := zts.clientCtx.Keyring.Key(account) if err != nil { - return "", "", "", err + return "", "", "", "", "", err } addr, err := acc.GetAddress() if err != nil { - return "", "", "", err + return "", "", "", "", "", err } // deploy new system contracts res, err := zts.BroadcastTx(account, fungibletypes.NewMsgDeploySystemContracts(addr.String())) if err != nil { - return "", "", "", fmt.Errorf("failed to deploy system contracts: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to deploy system contracts: %s", err.Error()) } systemContractAddress, err := fetchAttribute(res, "system_contract") if err != nil { - return "", "", "", fmt.Errorf("failed to fetch system contract address: %s; rawlog %s", err.Error(), res.RawLog) + return "", "", "", "", "", fmt.Errorf("failed to fetch system contract address: %s; rawlog %s", err.Error(), res.RawLog) } - // set system contract + // get system contract _, err = zts.BroadcastTx(account, fungibletypes.NewMsgUpdateSystemContract(addr.String(), systemContractAddress)) if err != nil { - return "", "", "", fmt.Errorf("failed to set system contract: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to set system contract: %s", err.Error()) } - // set uniswap contract addresses + // get uniswap contract addresses uniswapV2FactoryAddr, err := fetchAttribute(res, "uniswap_v2_factory") if err != nil { - return "", "", "", fmt.Errorf("failed to fetch uniswap v2 factory address: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to fetch uniswap v2 factory address: %s", err.Error()) } uniswapV2RouterAddr, err := fetchAttribute(res, "uniswap_v2_router") if err != nil { - return "", "", "", fmt.Errorf("failed to fetch uniswap v2 router address: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to fetch uniswap v2 router address: %s", err.Error()) + } + + // get zevm connector address + zevmConnectorAddr, err := fetchAttribute(res, "connector_zevm") + if err != nil { + return "", "", "", "", "", fmt.Errorf("failed to fetch zevm connector address: %s, txResponse: %s", err.Error(), res.String()) + } + + // get wzeta address + wzetaAddr, err := fetchAttribute(res, "wzeta") + if err != nil { + return "", "", "", "", "", fmt.Errorf("failed to fetch wzeta address: %s, txResponse: %s", err.Error(), res.String()) } // deploy eth zrc20 @@ -218,7 +230,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr str 100000, )) if err != nil { - return "", "", "", fmt.Errorf("failed to deploy eth zrc20: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to deploy eth zrc20: %s", err.Error()) } // deploy btc zrc20 @@ -233,7 +245,7 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr str 100000, )) if err != nil { - return "", "", "", fmt.Errorf("failed to deploy btc zrc20: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to deploy btc zrc20: %s", err.Error()) } // deploy usdt zrc20 @@ -248,18 +260,18 @@ func (zts ZetaTxServer) DeploySystemContractsAndZRC20(account, usdtERC20Addr str 100000, )) if err != nil { - return "", "", "", fmt.Errorf("failed to deploy usdt zrc20: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to deploy usdt zrc20: %s", err.Error()) } // fetch the usdt zrc20 contract address and remove the quotes usdtZRC20Addr, err := fetchAttribute(res, "Contract") if err != nil { - return "", "", "", fmt.Errorf("failed to fetch usdt zrc20 contract address: %s", err.Error()) + return "", "", "", "", "", fmt.Errorf("failed to fetch usdt zrc20 contract address: %s", err.Error()) } if !ethcommon.IsHexAddress(usdtZRC20Addr) { - return "", "", "", fmt.Errorf("invalid address in event: %s", usdtZRC20Addr) + return "", "", "", "", "", fmt.Errorf("invalid address in event: %s", usdtZRC20Addr) } - return uniswapV2FactoryAddr, uniswapV2RouterAddr, usdtZRC20Addr, nil + return uniswapV2FactoryAddr, uniswapV2RouterAddr, zevmConnectorAddr, wzetaAddr, usdtZRC20Addr, nil } // newCodec returns the codec for msg server diff --git a/contrib/localnet/orchestrator/smoketest/utils/evm.go b/contrib/localnet/orchestrator/smoketest/utils/evm.go index ec1273bcd4..d3f34f818c 100644 --- a/contrib/localnet/orchestrator/smoketest/utils/evm.go +++ b/contrib/localnet/orchestrator/smoketest/utils/evm.go @@ -48,13 +48,13 @@ func MustWaitForTxReceipt( } start := time.Now() - for { + for i := 0; ; i++ { if time.Since(start) > timeout { panic("waiting tx receipt timeout") } receipt, err := client.TransactionReceipt(ctx, tx.Hash()) if err != nil { - if !errors.Is(err, ethereum.NotFound) { + if !errors.Is(err, ethereum.NotFound) && i%10 == 0 { logger.Info("fetching tx receipt error: ", err.Error()) } time.Sleep(1 * time.Second) diff --git a/contrib/localnet/orchestrator/smoketest/utils/utils.go b/contrib/localnet/orchestrator/smoketest/utils/utils.go index c0ee15acde..bfa3d509b3 100644 --- a/contrib/localnet/orchestrator/smoketest/utils/utils.go +++ b/contrib/localnet/orchestrator/smoketest/utils/utils.go @@ -8,10 +8,10 @@ import ( ) // ScriptPKToAddress is a hex string for P2WPKH script -func ScriptPKToAddress(scriptPKHex string) string { +func ScriptPKToAddress(scriptPKHex string, params *chaincfg.Params) string { pkh, err := hex.DecodeString(scriptPKHex[4:]) if err == nil { - addr, err := btcutil.NewAddressWitnessPubKeyHash(pkh, &chaincfg.RegressionNetParams) + addr, err := btcutil.NewAddressWitnessPubKeyHash(pkh, params) if err == nil { return addr.EncodeAddress() } diff --git a/contrib/localnet/orchestrator/smoketest/utils/zetacore.go b/contrib/localnet/orchestrator/smoketest/utils/zetacore.go index 2ec8074354..6a491d1ebd 100644 --- a/contrib/localnet/orchestrator/smoketest/utils/zetacore.go +++ b/contrib/localnet/orchestrator/smoketest/utils/zetacore.go @@ -48,36 +48,45 @@ func WaitCctxsMinedByInTxHash( } // fetch cctxs by inTxHash - for { + for i := 0; ; i++ { time.Sleep(1 * time.Second) res, err := cctxClient.InTxHashToCctxData(ctx, &crosschaintypes.QueryInTxHashToCctxDataRequest{ InTxHash: inTxHash, }) if err != nil { - logger.Info("Error getting cctx by inTxHash: %s", err.Error()) + // prevent spamming logs + if i%10 == 0 { + logger.Info("Error getting cctx by inTxHash: %s", err.Error()) + } continue } if len(res.CrossChainTxs) < cctxsCount { - logger.Info( - "not enough cctxs found by inTxHash: %s, expected: %d, found: %d", - inTxHash, - cctxsCount, - len(res.CrossChainTxs), - ) + // prevent spamming logs + if i%10 == 0 { + logger.Info( + "not enough cctxs found by inTxHash: %s, expected: %d, found: %d", + inTxHash, + cctxsCount, + len(res.CrossChainTxs), + ) + } continue } cctxs := make([]*crosschaintypes.CrossChainTx, 0, len(res.CrossChainTxs)) allFound := true - for i, cctx := range res.CrossChainTxs { + for j, cctx := range res.CrossChainTxs { cctx := cctx if !IsTerminalStatus(cctx.CctxStatus.Status) { - logger.Info( - "waiting for cctx index %d to be mined by inTxHash: %s, cctx status: %s, message: %s", - i, - inTxHash, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - ) + // prevent spamming logs + if i%10 == 0 { + logger.Info( + "waiting for cctx index %d to be mined by inTxHash: %s, cctx status: %s, message: %s", + j, + inTxHash, + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage, + ) + } allFound = false break } @@ -116,12 +125,16 @@ func WaitForBlockHeight( panic(err) } status := &coretypes.ResultStatus{} - for status.SyncInfo.LatestBlockHeight < height { + for i := 0; status.SyncInfo.LatestBlockHeight < height; i++ { status, err = rpc.Status(ctx) if err != nil { panic(err) } time.Sleep(1 * time.Second) - logger.Info("waiting for block: %d, current height: %d\n", height, status.SyncInfo.LatestBlockHeight) + + // prevent spamming logs + if i%10 == 0 { + logger.Info("waiting for block: %d, current height: %d\n", height, status.SyncInfo.LatestBlockHeight) + } } } diff --git a/contrib/localnet/scripts/gov-proposals-testing.sh b/contrib/localnet/scripts/gov-proposals-testing.sh index 6d7147536a..a984fa9250 100755 --- a/contrib/localnet/scripts/gov-proposals-testing.sh +++ b/contrib/localnet/scripts/gov-proposals-testing.sh @@ -7,17 +7,17 @@ WALLET_NAME=operator # Create a few short lived proposals for variety of testing zetacored tx gov submit-proposal proposals/proposal_for_failure.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 1 VOTE_OPTION_NO --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 1 VOTE_OPTION_NO --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 zetacored tx gov submit-proposal proposals/proposal_for_success.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 2 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 2 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 zetacored tx gov submit-proposal proposals/v100.0.0_proposal.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 3 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 3 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 # Increase the length of the voting period to 1 week zetacored tx gov submit-proposal proposals/proposal_voting_period.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 4 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 4 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 # Create a few long lived proposals for variety of testing @@ -25,14 +25,17 @@ echo "Sleeping for 3 minutes to allow the voting period to end and the voting pe sleep 180 zetacored tx gov submit-proposal proposals/proposal_voting_period.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 5 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 5 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 zetacored tx gov submit-proposal proposals/v100.0.0_proposal.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 6 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +zetacored tx gov vote 6 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 zetacored tx gov submit-proposal proposals/proposal_for_deposit.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 -zetacored tx gov vote 7 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 - - +zetacored tx gov vote 7 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +# Consensus param test +#zetacored tx gov submit-legacy-proposal param-change proposals/proposal_for_consensus_params.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +#zetacored tx gov vote 1 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 +#zetacored tx gov submit-legacy-proposal param-change proposals/emissions_change.json --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --gas 1000000 --yes && sleep 12 +#zetacored tx gov vote 1 VOTE_OPTION_YES --from $WALLET_NAME --keyring-backend test --chain-id athens_101-1 --fees 2000000000000000azeta --yes && sleep 12 diff --git a/contrib/localnet/scripts/proposals/emissions_change.json b/contrib/localnet/scripts/proposals/emissions_change.json new file mode 100644 index 0000000000..5572e4e0a7 --- /dev/null +++ b/contrib/localnet/scripts/proposals/emissions_change.json @@ -0,0 +1,22 @@ +{ + "title": "Emissions Distribution", + "description": "Update emissions distribution", + "changes": [ + { + "subspace": "emissions", + "key": "ValidatorEmissionPercentage", + "value": "0.75" + }, + { + "subspace": "emissions", + "key": "ObserverEmissionPercentage", + "value": "0.125" + }, + { + "subspace": "emissions", + "key": "SignerEmissionPercentage", + "value": "0.125" + } + ], + "deposit": "10000000azeta" +} \ No newline at end of file diff --git a/contrib/localnet/scripts/proposals/proposal_for_consensus_params.json b/contrib/localnet/scripts/proposals/proposal_for_consensus_params.json new file mode 100644 index 0000000000..1e0aae79b5 --- /dev/null +++ b/contrib/localnet/scripts/proposals/proposal_for_consensus_params.json @@ -0,0 +1,15 @@ +{ + "title": "Change Max Gas Limit", + "description": "This proposal is to change the max gas limit per block.", + "changes": [ + { + "subspace": "baseapp", + "key": "BlockParams", + "value": { + "max_bytes": "22020096", + "max_gas": "500000000" + } + } + ], + "deposit": "100000000000000000azeta" +} \ No newline at end of file From 375cb967f08be535ca8f26d941624b32b932a442 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Sat, 3 Feb 2024 18:01:46 -0800 Subject: [PATCH 66/67] fix(`crosschain`): only use EVM supported chains for gas stability pool and prevent errors to stop iterating other chains (#1687) * use supported chain and skip bitcoin * skip error handling in abci * changelogs * lint * add nosec * add test for iterate function * fix lint * fix lint * add event --- changelog.md | 6 + proto/crosschain/events.proto | 6 + typescript/crosschain/events_pb.d.ts | 34 ++ x/crosschain/keeper/abci.go | 84 +++-- x/crosschain/keeper/abci_test.go | 96 +++++- x/crosschain/keeper/grpc_query_cctx_test.go | 20 +- x/crosschain/module.go | 10 +- x/crosschain/types/events.pb.go | 352 +++++++++++++++++--- 8 files changed, 533 insertions(+), 75 deletions(-) diff --git a/changelog.md b/changelog.md index 5f608c7b2f..56f8373f26 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,12 @@ ### Fixes +* [1687](https://github.com/zeta-chain/node/pull/1687) - only use EVM supported chains for gas stability pool + +## Version: v12.2.4 + +### Fixes + * [1638](https://github.com/zeta-chain/node/issues/1638) - additional check to make sure external chain height always increases * [1672](https://github.com/zeta-chain/node/pull/1672) - paying 50% more than base gas price to buffer EIP1559 gas price increase * [1642](https://github.com/zeta-chain/node/pull/1642) - Change WhitelistERC20 authorization from group1 to group2 diff --git a/proto/crosschain/events.proto b/proto/crosschain/events.proto index 90fff428fb..6497fd147e 100644 --- a/proto/crosschain/events.proto +++ b/proto/crosschain/events.proto @@ -58,3 +58,9 @@ message EventOutboundSuccess { string new_status = 4; string value_received = 5; } + +message EventCCTXGasPriceIncreased { + string cctx_index = 1; + string gas_price_increase = 2; + string additional_fees = 3; +} diff --git a/typescript/crosschain/events_pb.d.ts b/typescript/crosschain/events_pb.d.ts index 4bcfde46e6..285f476b30 100644 --- a/typescript/crosschain/events_pb.d.ts +++ b/typescript/crosschain/events_pb.d.ts @@ -291,3 +291,37 @@ export declare class EventOutboundSuccess extends Message static equals(a: EventOutboundSuccess | PlainMessage | undefined, b: EventOutboundSuccess | PlainMessage | undefined): boolean; } +/** + * @generated from message zetachain.zetacore.crosschain.EventCCTXGasPriceIncreased + */ +export declare class EventCCTXGasPriceIncreased extends Message { + /** + * @generated from field: string cctx_index = 1; + */ + cctxIndex: string; + + /** + * @generated from field: string gas_price_increase = 2; + */ + gasPriceIncrease: string; + + /** + * @generated from field: string additional_fees = 3; + */ + additionalFees: string; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.crosschain.EventCCTXGasPriceIncreased"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): EventCCTXGasPriceIncreased; + + static fromJson(jsonValue: JsonValue, options?: Partial): EventCCTXGasPriceIncreased; + + static fromJsonString(jsonString: string, options?: Partial): EventCCTXGasPriceIncreased; + + static equals(a: EventCCTXGasPriceIncreased | PlainMessage | undefined, b: EventCCTXGasPriceIncreased | PlainMessage | undefined): boolean; +} + diff --git a/x/crosschain/keeper/abci.go b/x/crosschain/keeper/abci.go index 78959be37c..dac6bcacc3 100644 --- a/x/crosschain/keeper/abci.go +++ b/x/crosschain/keeper/abci.go @@ -4,10 +4,11 @@ import ( "fmt" "time" + "github.com/zeta-chain/zetacore/common" + cosmoserrors "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -17,8 +18,21 @@ const ( RemainingFeesToStabilityPoolPercent = 95 ) +// CheckAndUpdateCctxGasPriceFunc is a function type for checking and updating the gas price of a cctx +type CheckAndUpdateCctxGasPriceFunc func( + ctx sdk.Context, + k Keeper, + cctx types.CrossChainTx, + flags observertypes.GasPriceIncreaseFlags, +) (math.Uint, math.Uint, error) + // IterateAndUpdateCctxGasPrice iterates through all cctx and updates the gas price if pending for too long -func (k Keeper) IterateAndUpdateCctxGasPrice(ctx sdk.Context) error { +// The function returns the number of cctxs updated and the gas price increase flags used +func (k Keeper) IterateAndUpdateCctxGasPrice( + ctx sdk.Context, + chains []*common.Chain, + updateFunc CheckAndUpdateCctxGasPriceFunc, +) (int, observertypes.GasPriceIncreaseFlags) { // fetch the gas price increase flags or use default gasPriceIncreaseFlags := observertypes.DefaultGasPriceIncreaseFlags crosschainFlags, found := k.zetaObserverKeeper.GetCrosschainFlags(ctx) @@ -28,38 +42,66 @@ func (k Keeper) IterateAndUpdateCctxGasPrice(ctx sdk.Context) error { // skip if haven't reached epoch end if ctx.BlockHeight()%gasPriceIncreaseFlags.EpochLength != 0 { - return nil + return 0, gasPriceIncreaseFlags } - // iterate all chains' pending cctx - chains := common.DefaultChainsList() + cctxCount := 0 + +IterateChains: for _, chain := range chains { - res, err := k.CctxListPending(sdk.UnwrapSDKContext(ctx), &types.QueryListCctxPendingRequest{ - ChainId: chain.ChainId, - Limit: gasPriceIncreaseFlags.MaxPendingCctxs, - }) - if err != nil { - return err - } + // support only external evm chains + if common.IsEVMChain(chain.ChainId) && !common.IsZetaChain(chain.ChainId) { + res, err := k.CctxListPending(sdk.UnwrapSDKContext(ctx), &types.QueryListCctxPendingRequest{ + ChainId: chain.ChainId, + Limit: gasPriceIncreaseFlags.MaxPendingCctxs, + }) + if err != nil { + ctx.Logger().Info("GasStabilityPool: fetching pending cctx failed", + "chainID", chain.ChainId, + "err", err.Error(), + ) + continue IterateChains + } - // iterate through all pending cctx - for _, pendingCctx := range res.CrossChainTx { - if pendingCctx != nil { - _, _, err := k.CheckAndUpdateCctxGasPrice(ctx, *pendingCctx, gasPriceIncreaseFlags) - if err != nil { - return err + // iterate through all pending cctx + for _, pendingCctx := range res.CrossChainTx { + if pendingCctx != nil { + gasPriceIncrease, additionalFees, err := updateFunc(ctx, k, *pendingCctx, gasPriceIncreaseFlags) + if err != nil { + ctx.Logger().Info("GasStabilityPool: updating gas price for pending cctx failed", + "cctxIndex", pendingCctx.Index, + "err", err.Error(), + ) + continue IterateChains + } + if !gasPriceIncrease.IsNil() && !gasPriceIncrease.IsZero() { + // Emit typed event for gas price increase + if err := ctx.EventManager().EmitTypedEvent( + &types.EventCCTXGasPriceIncreased{ + CctxIndex: pendingCctx.Index, + GasPriceIncrease: gasPriceIncrease.String(), + AdditionalFees: additionalFees.String(), + }); err != nil { + ctx.Logger().Error( + "GasStabilityPool: failed to emit EventCCTXGasPriceIncreased", + "err", err.Error(), + ) + } + cctxCount++ + } } } } } - return nil + return cctxCount, gasPriceIncreaseFlags } // CheckAndUpdateCctxGasPrice checks if the retry interval is reached and updates the gas price if so // The function returns the gas price increase and the additional fees paid from the gas stability pool -func (k Keeper) CheckAndUpdateCctxGasPrice( +func CheckAndUpdateCctxGasPrice( ctx sdk.Context, + k Keeper, cctx types.CrossChainTx, flags observertypes.GasPriceIncreaseFlags, ) (math.Uint, math.Uint, error) { @@ -108,7 +150,7 @@ func (k Keeper) CheckAndUpdateCctxGasPrice( if err := k.fungibleKeeper.WithdrawFromGasStabilityPool(ctx, chainID, additionalFees.BigInt()); err != nil { return math.ZeroUint(), math.ZeroUint(), cosmoserrors.Wrap( types.ErrNotEnoughFunds, - fmt.Sprintf("cannot withdraw %s from gas stability pool", additionalFees.String()), + fmt.Sprintf("cannot withdraw %s from gas stability pool, error: %s", additionalFees.String(), err.Error()), ) } diff --git a/x/crosschain/keeper/abci_test.go b/x/crosschain/keeper/abci_test.go index 12263a3587..ea46e70dc4 100644 --- a/x/crosschain/keeper/abci_test.go +++ b/x/crosschain/keeper/abci_test.go @@ -6,13 +6,105 @@ import ( "time" "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/common" testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestKeeper_CheckAndUpdateCctxGasPrice(t *testing.T) { +func TestKeeper_IterateAndUpdateCctxGasPrice(t *testing.T) { + k, ctx, _, zk := testkeeper.CrosschainKeeper(t) + + // updateFuncMap tracks the calls done with cctx index + updateFuncMap := make(map[string]struct{}) + + // failMap gives the cctx index that should fail + failMap := make(map[string]struct{}) + + // updateFunc mocks the update function and keep track of the calls done with cctx index + updateFunc := func( + ctx sdk.Context, + k keeper.Keeper, + cctx types.CrossChainTx, + flags observertypes.GasPriceIncreaseFlags, + ) (math.Uint, math.Uint, error) { + if _, ok := failMap[cctx.Index]; ok { + return math.NewUint(0), math.NewUint(0), errors.New("failed") + } + + updateFuncMap[cctx.Index] = struct{}{} + return math.NewUint(10), math.NewUint(10), nil + } + + // add some evm and non-evm chains + supportedChains := []*common.Chain{ + {ChainId: common.EthChain().ChainId}, + {ChainId: common.BtcMainnetChain().ChainId}, + {ChainId: common.BscMainnetChain().ChainId}, + {ChainId: common.ZetaChainMainnet().ChainId}, + } + + // set pending cctx + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + createCctxWithNonceRange(t, ctx, *k, 10, 15, common.EthChain().ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 20, 25, common.BtcMainnetChain().ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 30, 35, common.BscMainnetChain().ChainId, tss, zk) + createCctxWithNonceRange(t, ctx, *k, 40, 45, common.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["1-12"] = struct{}{} + + // test that the default crosschain flags are used when not set and the epoch length is not reached + ctx = ctx.WithBlockHeight(observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags.EpochLength + 1) + + cctxCount, flags := k.IterateAndUpdateCctxGasPrice(ctx, supportedChains, updateFunc) + require.Equal(t, 0, cctxCount) + require.Equal(t, *observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags, flags) + + // test that custom crosschain flags are used when set and the epoch length is reached + customFlags := observertypes.GasPriceIncreaseFlags{ + EpochLength: 100, + RetryInterval: time.Minute * 10, + GasPriceIncreasePercent: 100, + GasPriceIncreaseMax: 200, + MaxPendingCctxs: 10, + } + crosschainFlags := sample.CrosschainFlags() + crosschainFlags.GasPriceIncreaseFlags = &customFlags + zk.ObserverKeeper.SetCrosschainFlags(ctx, *crosschainFlags) + + cctxCount, flags = k.IterateAndUpdateCctxGasPrice(ctx, supportedChains, updateFunc) + require.Equal(t, 0, cctxCount) + require.Equal(t, customFlags, flags) + + // test that cctx are iterated and updated when the epoch length is reached + + ctx = ctx.WithBlockHeight(observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags.EpochLength * 2) + cctxCount, flags = k.IterateAndUpdateCctxGasPrice(ctx, supportedChains, updateFunc) + + // 2 eth + 5 bsc = 7 + require.Equal(t, 7, cctxCount) + require.Equal(t, customFlags, flags) + + // check that the update function was called with the cctx index + require.Equal(t, 7, len(updateFuncMap)) + require.Contains(t, updateFuncMap, "1-10") + require.Contains(t, updateFuncMap, "1-11") + + require.Contains(t, updateFuncMap, "56-30") + require.Contains(t, updateFuncMap, "56-31") + require.Contains(t, updateFuncMap, "56-32") + require.Contains(t, updateFuncMap, "56-33") + require.Contains(t, updateFuncMap, "56-34") +} + +func TestCheckAndUpdateCctxGasPrice(t *testing.T) { sampleTimestamp := time.Now() retryIntervalReached := sampleTimestamp.Add(observertypes.DefaultGasPriceIncreaseFlags.RetryInterval + time.Second) retryIntervalNotReached := sampleTimestamp.Add(observertypes.DefaultGasPriceIncreaseFlags.RetryInterval - time.Second) @@ -282,7 +374,7 @@ func TestKeeper_CheckAndUpdateCctxGasPrice(t *testing.T) { } // check and update gas price - gasPriceIncrease, feesPaid, err := k.CheckAndUpdateCctxGasPrice(ctx, tc.cctx, tc.flags) + gasPriceIncrease, feesPaid, err := keeper.CheckAndUpdateCctxGasPrice(ctx, *k, tc.cctx, tc.flags) if tc.isError { require.Error(t, err) diff --git a/x/crosschain/keeper/grpc_query_cctx_test.go b/x/crosschain/keeper/grpc_query_cctx_test.go index cd5d1e3c14..c326f41a42 100644 --- a/x/crosschain/keeper/grpc_query_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_cctx_test.go @@ -22,14 +22,14 @@ func createCctxWithNonceRange( t *testing.T, ctx sdk.Context, k keeper.Keeper, - low int, - high int, + lowPending int, + highPending int, chainID int64, tss observertypes.TSS, zk keepertest.ZetaKeepers, ) (cctxs []*types.CrossChainTx) { - for i := 0; i < low; i++ { - cctx := sample.CrossChainTx(t, fmt.Sprintf("%d", i)) + for i := 0; i < lowPending; i++ { + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, i)) cctx.CctxStatus.Status = types.CctxStatus_OutboundMined cctx.InboundTxParams.SenderChainId = chainID k.SetCrossChainTx(ctx, *cctx) @@ -40,8 +40,8 @@ func createCctxWithNonceRange( Tss: tss.TssPubkey, }) } - for i := low; i < high; i++ { - cctx := sample.CrossChainTx(t, fmt.Sprintf("%d", i)) + for i := lowPending; i < highPending; i++ { + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, i)) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound cctx.InboundTxParams.SenderChainId = chainID k.SetCrossChainTx(ctx, *cctx) @@ -55,8 +55,8 @@ func createCctxWithNonceRange( } zk.ObserverKeeper.SetPendingNonces(ctx, observertypes.PendingNonces{ ChainId: chainID, - NonceLow: int64(low), - NonceHigh: int64(high), + NonceLow: int64(lowPending), + NonceHigh: int64(highPending), Tss: tss.TssPubkey, }) @@ -135,12 +135,12 @@ func TestKeeper_CctxListPending(t *testing.T) { cctxs := createCctxWithNonceRange(t, ctx, *k, 1000, 2000, chainID, tss, zk) // set some cctxs as pending below nonce - cctx1, found := k.GetCrossChainTx(ctx, "940") + cctx1, found := k.GetCrossChainTx(ctx, "1337-940") require.True(t, found) cctx1.CctxStatus.Status = types.CctxStatus_PendingOutbound k.SetCrossChainTx(ctx, cctx1) - cctx2, found := k.GetCrossChainTx(ctx, "955") + cctx2, found := k.GetCrossChainTx(ctx, "1337-955") require.True(t, found) cctx2.CctxStatus.Status = types.CctxStatus_PendingOutbound k.SetCrossChainTx(ctx, cctx2) diff --git a/x/crosschain/module.go b/x/crosschain/module.go index 9e2e4ec81b..421f92c895 100644 --- a/x/crosschain/module.go +++ b/x/crosschain/module.go @@ -188,10 +188,12 @@ func (AppModule) ConsensusVersion() uint64 { return 4 } // BeginBlock executes all ABCI BeginBlock logic respective to the crosschain module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - err := am.keeper.IterateAndUpdateCctxGasPrice(ctx) - if err != nil { - ctx.Logger().Info("Error iterating and updating pending cctx gas price", "err", err.Error()) - } + // get all supported chains + supportedChains := am.keeper.GetObserverKeeper().GetSupportedChains(ctx) + + // iterate and update gas price for cctx that are pending for too long + // error is logged in the function + am.keeper.IterateAndUpdateCctxGasPrice(ctx, supportedChains, keeper.CheckAndUpdateCctxGasPrice) } // EndBlock executes all ABCI EndBlock logic respective to the crosschain module. It diff --git a/x/crosschain/types/events.pb.go b/x/crosschain/types/events.pb.go index 3fbc7f3fa3..68c05a18f0 100644 --- a/x/crosschain/types/events.pb.go +++ b/x/crosschain/types/events.pb.go @@ -509,55 +509,120 @@ func (m *EventOutboundSuccess) GetValueReceived() string { return "" } +type EventCCTXGasPriceIncreased struct { + CctxIndex string `protobuf:"bytes,1,opt,name=cctx_index,json=cctxIndex,proto3" json:"cctx_index,omitempty"` + GasPriceIncrease string `protobuf:"bytes,2,opt,name=gas_price_increase,json=gasPriceIncrease,proto3" json:"gas_price_increase,omitempty"` + AdditionalFees string `protobuf:"bytes,3,opt,name=additional_fees,json=additionalFees,proto3" json:"additional_fees,omitempty"` +} + +func (m *EventCCTXGasPriceIncreased) Reset() { *m = EventCCTXGasPriceIncreased{} } +func (m *EventCCTXGasPriceIncreased) String() string { return proto.CompactTextString(m) } +func (*EventCCTXGasPriceIncreased) ProtoMessage() {} +func (*EventCCTXGasPriceIncreased) Descriptor() ([]byte, []int) { + return fileDescriptor_7398db8b12b87b9e, []int{5} +} +func (m *EventCCTXGasPriceIncreased) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventCCTXGasPriceIncreased) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventCCTXGasPriceIncreased.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventCCTXGasPriceIncreased) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventCCTXGasPriceIncreased.Merge(m, src) +} +func (m *EventCCTXGasPriceIncreased) XXX_Size() int { + return m.Size() +} +func (m *EventCCTXGasPriceIncreased) XXX_DiscardUnknown() { + xxx_messageInfo_EventCCTXGasPriceIncreased.DiscardUnknown(m) +} + +var xxx_messageInfo_EventCCTXGasPriceIncreased proto.InternalMessageInfo + +func (m *EventCCTXGasPriceIncreased) GetCctxIndex() string { + if m != nil { + return m.CctxIndex + } + return "" +} + +func (m *EventCCTXGasPriceIncreased) GetGasPriceIncrease() string { + if m != nil { + return m.GasPriceIncrease + } + return "" +} + +func (m *EventCCTXGasPriceIncreased) GetAdditionalFees() string { + if m != nil { + return m.AdditionalFees + } + return "" +} + func init() { proto.RegisterType((*EventInboundFinalized)(nil), "zetachain.zetacore.crosschain.EventInboundFinalized") proto.RegisterType((*EventZrcWithdrawCreated)(nil), "zetachain.zetacore.crosschain.EventZrcWithdrawCreated") proto.RegisterType((*EventZetaWithdrawCreated)(nil), "zetachain.zetacore.crosschain.EventZetaWithdrawCreated") proto.RegisterType((*EventOutboundFailure)(nil), "zetachain.zetacore.crosschain.EventOutboundFailure") proto.RegisterType((*EventOutboundSuccess)(nil), "zetachain.zetacore.crosschain.EventOutboundSuccess") + proto.RegisterType((*EventCCTXGasPriceIncreased)(nil), "zetachain.zetacore.crosschain.EventCCTXGasPriceIncreased") } func init() { proto.RegisterFile("crosschain/events.proto", fileDescriptor_7398db8b12b87b9e) } var fileDescriptor_7398db8b12b87b9e = []byte{ - // 586 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xdd, 0x6a, 0xd4, 0x40, - 0x14, 0x6e, 0xda, 0xdd, 0xed, 0xee, 0xf4, 0x0f, 0x62, 0xb5, 0x63, 0xb1, 0xa1, 0x2e, 0xf8, 0x73, - 0xe3, 0x06, 0xf1, 0x0d, 0x5a, 0x94, 0x16, 0x91, 0x42, 0x5b, 0x11, 0x7a, 0x33, 0xcc, 0x26, 0x87, - 0x64, 0x30, 0x99, 0x59, 0x66, 0x26, 0xbb, 0xd9, 0x3e, 0x85, 0x2f, 0x22, 0xf8, 0x00, 0x3e, 0x80, - 0x97, 0xbd, 0xf0, 0xc2, 0x4b, 0xd9, 0x7d, 0x11, 0x99, 0x99, 0x44, 0xbb, 0xa9, 0xe8, 0x85, 0x28, - 0x78, 0x95, 0x73, 0xbe, 0x73, 0x72, 0xf2, 0xcd, 0xf7, 0x4d, 0x0e, 0xda, 0x89, 0xa4, 0x50, 0x2a, - 0x4a, 0x29, 0xe3, 0x21, 0x8c, 0x81, 0x6b, 0x35, 0x18, 0x49, 0xa1, 0x85, 0xbf, 0x77, 0x09, 0x9a, - 0x5a, 0x7c, 0x60, 0x23, 0x21, 0x61, 0xf0, 0xa3, 0x77, 0xf7, 0x56, 0x24, 0xf2, 0x5c, 0xf0, 0xd0, - 0x3d, 0xdc, 0x3b, 0xbb, 0xdb, 0x89, 0x48, 0x84, 0x0d, 0x43, 0x13, 0x39, 0xb4, 0xff, 0x79, 0x05, - 0xdd, 0x7e, 0x6e, 0x46, 0x1f, 0xf3, 0xa1, 0x28, 0x78, 0xfc, 0x82, 0x71, 0x9a, 0xb1, 0x4b, 0x88, - 0xfd, 0x7d, 0xb4, 0x9e, 0xab, 0x84, 0xe8, 0xe9, 0x08, 0x48, 0x21, 0x33, 0xec, 0xed, 0x7b, 0x8f, - 0x7b, 0xa7, 0x28, 0x57, 0xc9, 0xf9, 0x74, 0x04, 0xaf, 0x65, 0xe6, 0xef, 0x21, 0x14, 0x45, 0xba, - 0x24, 0x8c, 0xc7, 0x50, 0xe2, 0x65, 0x5b, 0xef, 0x19, 0xe4, 0xd8, 0x00, 0xfe, 0x1d, 0xd4, 0x51, - 0xc0, 0x63, 0x90, 0x78, 0xc5, 0x96, 0xaa, 0xcc, 0xbf, 0x8b, 0xba, 0xba, 0x24, 0x42, 0x26, 0x8c, - 0xe3, 0x96, 0xad, 0xac, 0xea, 0xf2, 0xc4, 0xa4, 0xfe, 0x36, 0x6a, 0x53, 0xa5, 0x40, 0xe3, 0xb6, - 0xc5, 0x5d, 0xe2, 0xdf, 0x43, 0x88, 0x71, 0xa2, 0x4b, 0x92, 0x52, 0x95, 0xe2, 0x8e, 0x2d, 0x75, - 0x19, 0x3f, 0x2f, 0x8f, 0xa8, 0x4a, 0xfd, 0x87, 0x68, 0x8b, 0x71, 0x32, 0xcc, 0x44, 0xf4, 0x96, - 0xa4, 0xc0, 0x92, 0x54, 0xe3, 0x55, 0xdb, 0xb2, 0xc1, 0xf8, 0x81, 0x41, 0x8f, 0x2c, 0xe8, 0xef, - 0xa2, 0xae, 0x84, 0x08, 0xd8, 0x18, 0x24, 0xee, 0xba, 0x19, 0x75, 0xee, 0x3f, 0x40, 0x9b, 0x75, - 0x4c, 0xac, 0x84, 0xb8, 0xe7, 0x46, 0xd4, 0xe8, 0xa1, 0x01, 0xcd, 0x89, 0x68, 0x2e, 0x0a, 0xae, - 0x31, 0x72, 0x27, 0x72, 0x99, 0xff, 0x08, 0x6d, 0x49, 0xc8, 0xe8, 0x14, 0x62, 0x92, 0x83, 0x52, - 0x34, 0x01, 0xbc, 0x66, 0x1b, 0x36, 0x2b, 0xf8, 0x95, 0x43, 0x8d, 0x62, 0x1c, 0x26, 0x44, 0x69, - 0xaa, 0x0b, 0x85, 0xd7, 0x9d, 0x62, 0x1c, 0x26, 0x67, 0x16, 0x30, 0x34, 0x5c, 0xe9, 0xfb, 0x98, - 0x0d, 0x47, 0xc3, 0xa1, 0xf5, 0x94, 0xfb, 0x68, 0xdd, 0x49, 0x59, 0x71, 0xdd, 0xb4, 0x4d, 0x6b, - 0x0e, 0xb3, 0x4c, 0xfb, 0xef, 0x97, 0xd1, 0x8e, 0xb5, 0xf5, 0x42, 0x46, 0x6f, 0x98, 0x4e, 0x63, - 0x49, 0x27, 0x87, 0x12, 0xa8, 0xfe, 0x9b, 0xc6, 0x36, 0x79, 0xb5, 0x6e, 0xf0, 0x6a, 0x58, 0xd9, - 0x6e, 0x58, 0x79, 0xdd, 0xa2, 0xce, 0x6f, 0x2d, 0x5a, 0xfd, 0xb5, 0x45, 0xdd, 0x05, 0x8b, 0x16, - 0x95, 0xef, 0x35, 0x94, 0xef, 0x7f, 0xf0, 0x10, 0x76, 0x7a, 0x81, 0xa6, 0xff, 0x4c, 0xb0, 0x45, - 0x35, 0x5a, 0x0d, 0x35, 0x16, 0x29, 0xb7, 0x9b, 0x94, 0x3f, 0x7a, 0x68, 0xdb, 0x52, 0x3e, 0x29, - 0xb4, 0xfb, 0x75, 0x29, 0xcb, 0x0a, 0x09, 0x7f, 0x4e, 0x77, 0x0f, 0x21, 0x91, 0xc5, 0xf5, 0x87, - 0x1d, 0xe5, 0x9e, 0xc8, 0xe2, 0xea, 0x96, 0x2e, 0xf2, 0x6a, 0xfd, 0xe4, 0x12, 0x8f, 0x69, 0x56, - 0x00, 0xa9, 0x8c, 0x89, 0x2b, 0xea, 0x1b, 0x16, 0x3d, 0xad, 0xc0, 0x9b, 0xf4, 0xcf, 0x8a, 0x28, - 0x02, 0xa5, 0xfe, 0x0f, 0xfa, 0x07, 0x2f, 0x3f, 0xcd, 0x02, 0xef, 0x6a, 0x16, 0x78, 0x5f, 0x67, - 0x81, 0xf7, 0x6e, 0x1e, 0x2c, 0x5d, 0xcd, 0x83, 0xa5, 0x2f, 0xf3, 0x60, 0xe9, 0xe2, 0x69, 0xc2, - 0x74, 0x5a, 0x0c, 0x07, 0x91, 0xc8, 0x43, 0xb3, 0x9c, 0x9f, 0xb8, 0xfd, 0x5d, 0xef, 0xe9, 0xb0, - 0x0c, 0xaf, 0x6d, 0x75, 0x73, 0x4a, 0x35, 0xec, 0xd8, 0x5d, 0xfc, 0xec, 0x5b, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xee, 0x0c, 0x96, 0x59, 0xf0, 0x05, 0x00, 0x00, + // 654 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x95, 0xcf, 0x6e, 0x13, 0x3b, + 0x14, 0xc6, 0x3b, 0x6d, 0x92, 0x26, 0x6e, 0x9b, 0x5e, 0xcd, 0xed, 0xbd, 0xf5, 0x8d, 0x6e, 0xa3, + 0x52, 0x89, 0x3f, 0x0b, 0x48, 0x84, 0x78, 0x83, 0x46, 0x94, 0x56, 0x08, 0x15, 0xb5, 0x45, 0xa0, + 0x6e, 0x2c, 0xc7, 0x73, 0x98, 0xb1, 0x98, 0xb1, 0x23, 0xdb, 0xd3, 0x4e, 0xfb, 0x14, 0x88, 0xf7, + 0x40, 0xe2, 0x01, 0x78, 0x00, 0x96, 0x5d, 0xb0, 0x60, 0x89, 0xda, 0x17, 0x41, 0xb6, 0x67, 0x68, + 0x33, 0x45, 0xb0, 0x40, 0x20, 0xb1, 0x8a, 0xcf, 0x77, 0xec, 0x93, 0x9f, 0xbf, 0xe3, 0xe4, 0xa0, + 0x55, 0xa6, 0xa4, 0xd6, 0x2c, 0xa1, 0x5c, 0x0c, 0xe1, 0x08, 0x84, 0xd1, 0x83, 0x89, 0x92, 0x46, + 0x86, 0x6b, 0xa7, 0x60, 0xa8, 0xd3, 0x07, 0x6e, 0x25, 0x15, 0x0c, 0x2e, 0xf7, 0xf6, 0xfe, 0x66, + 0x32, 0xcb, 0xa4, 0x18, 0xfa, 0x0f, 0x7f, 0xa6, 0xb7, 0x12, 0xcb, 0x58, 0xba, 0xe5, 0xd0, 0xae, + 0xbc, 0xba, 0xf1, 0x71, 0x0e, 0xfd, 0xf3, 0xd0, 0x96, 0xde, 0x11, 0x63, 0x99, 0x8b, 0x68, 0x8b, + 0x0b, 0x9a, 0xf2, 0x53, 0x88, 0xc2, 0x75, 0xb4, 0x98, 0xe9, 0x98, 0x98, 0x93, 0x09, 0x90, 0x5c, + 0xa5, 0x38, 0x58, 0x0f, 0xee, 0x74, 0xf6, 0x50, 0xa6, 0xe3, 0x83, 0x93, 0x09, 0x3c, 0x53, 0x69, + 0xb8, 0x86, 0x10, 0x63, 0xa6, 0x20, 0x5c, 0x44, 0x50, 0xe0, 0x59, 0x97, 0xef, 0x58, 0x65, 0xc7, + 0x0a, 0xe1, 0xbf, 0xa8, 0xa5, 0x41, 0x44, 0xa0, 0xf0, 0x9c, 0x4b, 0x95, 0x51, 0xf8, 0x1f, 0x6a, + 0x9b, 0x82, 0x48, 0x15, 0x73, 0x81, 0x1b, 0x2e, 0x33, 0x6f, 0x8a, 0x5d, 0x1b, 0x86, 0x2b, 0xa8, + 0x49, 0xb5, 0x06, 0x83, 0x9b, 0x4e, 0xf7, 0x41, 0xf8, 0x3f, 0x42, 0x5c, 0x10, 0x53, 0x90, 0x84, + 0xea, 0x04, 0xb7, 0x5c, 0xaa, 0xcd, 0xc5, 0x41, 0xb1, 0x4d, 0x75, 0x12, 0xde, 0x42, 0xcb, 0x5c, + 0x90, 0x71, 0x2a, 0xd9, 0x2b, 0x92, 0x00, 0x8f, 0x13, 0x83, 0xe7, 0xdd, 0x96, 0x25, 0x2e, 0x36, + 0xad, 0xba, 0xed, 0xc4, 0xb0, 0x87, 0xda, 0x0a, 0x18, 0xf0, 0x23, 0x50, 0xb8, 0xed, 0x6b, 0x54, + 0x71, 0x78, 0x13, 0x75, 0xab, 0x35, 0x71, 0x16, 0xe2, 0x8e, 0x2f, 0x51, 0xa9, 0x23, 0x2b, 0xda, + 0x1b, 0xd1, 0x4c, 0xe6, 0xc2, 0x60, 0xe4, 0x6f, 0xe4, 0xa3, 0xf0, 0x36, 0x5a, 0x56, 0x90, 0xd2, + 0x13, 0x88, 0x48, 0x06, 0x5a, 0xd3, 0x18, 0xf0, 0x82, 0xdb, 0xd0, 0x2d, 0xe5, 0x27, 0x5e, 0xb5, + 0x8e, 0x09, 0x38, 0x26, 0xda, 0x50, 0x93, 0x6b, 0xbc, 0xe8, 0x1d, 0x13, 0x70, 0xbc, 0xef, 0x04, + 0x8b, 0xe1, 0x53, 0x5f, 0xcb, 0x2c, 0x79, 0x0c, 0xaf, 0x56, 0x55, 0x6e, 0xa0, 0x45, 0x6f, 0x65, + 0xc9, 0xda, 0x75, 0x9b, 0x16, 0xbc, 0xe6, 0x48, 0x37, 0xde, 0xce, 0xa2, 0x55, 0xd7, 0xd6, 0x43, + 0xc5, 0x9e, 0x73, 0x93, 0x44, 0x8a, 0x1e, 0x8f, 0x14, 0x50, 0xf3, 0x2b, 0x1b, 0x5b, 0xe7, 0x6a, + 0x5c, 0xe3, 0xaa, 0xb5, 0xb2, 0x59, 0x6b, 0xe5, 0xd5, 0x16, 0xb5, 0x7e, 0xd8, 0xa2, 0xf9, 0xef, + 0xb7, 0xa8, 0x3d, 0xd5, 0xa2, 0x69, 0xe7, 0x3b, 0x35, 0xe7, 0x37, 0xde, 0x05, 0x08, 0x7b, 0xbf, + 0xc0, 0xd0, 0xdf, 0x66, 0xd8, 0xb4, 0x1b, 0x8d, 0x9a, 0x1b, 0xd3, 0xc8, 0xcd, 0x3a, 0xf2, 0xfb, + 0x00, 0xad, 0x38, 0xe4, 0xdd, 0xdc, 0xf8, 0x9f, 0x2e, 0xe5, 0x69, 0xae, 0xe0, 0xe7, 0x71, 0xd7, + 0x10, 0x92, 0x69, 0x54, 0x7d, 0xb1, 0x47, 0xee, 0xc8, 0x34, 0x2a, 0x5f, 0xe9, 0x34, 0x57, 0xe3, + 0x1b, 0x8f, 0xf8, 0x88, 0xa6, 0x39, 0x90, 0xb2, 0x31, 0x51, 0x89, 0xbe, 0xe4, 0xd4, 0xbd, 0x52, + 0xbc, 0x8e, 0xbf, 0x9f, 0x33, 0x06, 0x5a, 0xff, 0x21, 0xf8, 0x6f, 0x02, 0xd4, 0x73, 0xf8, 0xa3, + 0xd1, 0xc1, 0x8b, 0x47, 0x54, 0x3f, 0x55, 0x9c, 0xc1, 0x8e, 0x60, 0x0a, 0xa8, 0x86, 0xa8, 0x86, + 0x18, 0xd4, 0x11, 0xef, 0xa2, 0x30, 0xa6, 0x9a, 0x4c, 0xec, 0x21, 0xc2, 0xcb, 0x53, 0xe5, 0x4d, + 0xfe, 0x8a, 0x6b, 0xd5, 0xec, 0xdf, 0x0b, 0x8d, 0x22, 0x6e, 0xb8, 0x14, 0x34, 0x25, 0x2f, 0x01, + 0xaa, 0x5b, 0x75, 0x2f, 0xe5, 0x2d, 0x00, 0xbd, 0xf9, 0xf8, 0xc3, 0x79, 0x3f, 0x38, 0x3b, 0xef, + 0x07, 0x9f, 0xcf, 0xfb, 0xc1, 0xeb, 0x8b, 0xfe, 0xcc, 0xd9, 0x45, 0x7f, 0xe6, 0xd3, 0x45, 0x7f, + 0xe6, 0xf0, 0x7e, 0xcc, 0x4d, 0x92, 0x8f, 0x07, 0x4c, 0x66, 0x43, 0x3b, 0x31, 0xee, 0xf9, 0xa1, + 0x52, 0x0d, 0x8f, 0x61, 0x31, 0xbc, 0x32, 0x6a, 0xac, 0xf5, 0x7a, 0xdc, 0x72, 0x03, 0xe2, 0xc1, + 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0x66, 0xf0, 0x4d, 0x85, 0x06, 0x00, 0x00, } func (m *EventInboundFinalized) Marshal() (dAtA []byte, err error) { @@ -941,6 +1006,50 @@ func (m *EventOutboundSuccess) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *EventCCTXGasPriceIncreased) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventCCTXGasPriceIncreased) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventCCTXGasPriceIncreased) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AdditionalFees) > 0 { + i -= len(m.AdditionalFees) + copy(dAtA[i:], m.AdditionalFees) + i = encodeVarintEvents(dAtA, i, uint64(len(m.AdditionalFees))) + i-- + dAtA[i] = 0x1a + } + if len(m.GasPriceIncrease) > 0 { + i -= len(m.GasPriceIncrease) + copy(dAtA[i:], m.GasPriceIncrease) + i = encodeVarintEvents(dAtA, i, uint64(len(m.GasPriceIncrease))) + i-- + dAtA[i] = 0x12 + } + if len(m.CctxIndex) > 0 { + i -= len(m.CctxIndex) + copy(dAtA[i:], m.CctxIndex) + i = encodeVarintEvents(dAtA, i, uint64(len(m.CctxIndex))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -1149,6 +1258,27 @@ func (m *EventOutboundSuccess) Size() (n int) { return n } +func (m *EventCCTXGasPriceIncreased) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CctxIndex) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + l = len(m.GasPriceIncrease) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + l = len(m.AdditionalFees) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2621,6 +2751,152 @@ func (m *EventOutboundSuccess) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventCCTXGasPriceIncreased) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventCCTXGasPriceIncreased: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventCCTXGasPriceIncreased: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CctxIndex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CctxIndex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GasPriceIncrease", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GasPriceIncrease = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AdditionalFees", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AdditionalFees = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipEvents(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 4d47d4f3e74a6c01c1f8d58007790a4c479a5b31 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Mon, 5 Feb 2024 20:54:39 -0600 Subject: [PATCH 67/67] fix: cherry-picked fixes, double watched gas price and fix btc scheduler (#1693) * double watched gas price and fix btc scheduler * update changelog --------- Co-authored-by: Lucas Bertrand --- changelog.md | 17 +++++++++++------ zetaclient/tx.go | 2 ++ zetaclient/zetacore_observer.go | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 56f8373f26..b7bb34d3dd 100644 --- a/changelog.md +++ b/changelog.md @@ -1,13 +1,23 @@ # CHANGELOG ## Unreleased + +* `zetaclientd start` : 2 inputs required from stdin + +### Refactor + * [1630](https://github.com/zeta-chain/node/pull/1630) added password prompts for hotkey and tss keyshare in zetaclient Starting zetaclient now requires two passwords to be input; one for the hotkey and another for the tss key-share. -* `zetaclientd start` : 2 inputs required from stdin ### Fixes +* [1690](https://github.com/zeta-chain/node/issues/1690) - double watched gas prices and fix btc scheduler * [1687](https://github.com/zeta-chain/node/pull/1687) - only use EVM supported chains for gas stability pool +* [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module + +### Tests + +* [1584](https://github.com/zeta-chain/node/pull/1584) - allow to run E2E tests on any networks ## Version: v12.2.4 @@ -22,11 +32,6 @@ * [1663](https://github.com/zeta-chain/node/issues/1663) - skip Mumbai empty block if ethclient sanity check fails * [1661](https://github.com/zeta-chain/node/issues/1661) - use estimated SegWit tx size for Bitcoin gas fee calculation * [1667](https://github.com/zeta-chain/node/issues/1667) - estimate SegWit tx size in uinit of vByte -* [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module - -### Tests - -* [1584](https://github.com/zeta-chain/node/pull/1584) - allow to run E2E tests on any networks ## Version: v12.1.0 diff --git a/zetaclient/tx.go b/zetaclient/tx.go index 491b76d133..f422a3e026 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -51,6 +51,8 @@ func (b *ZetaCoreBridge) WrapMessageWithAuthz(msg sdk.Msg) (sdk.Msg, AuthZSigner } func (b *ZetaCoreBridge) PostGasPrice(chain common.Chain, gasPrice uint64, supply string, blockNum uint64) (string, error) { + // double the gas price to avoid gas price spike + gasPrice = gasPrice * 2 signerAddress := b.keys.GetOperatorAddress().String() msg := types.NewMsgGasPriceVoter(signerAddress, chain.ChainId, gasPrice, supply, blockNum) diff --git a/zetaclient/zetacore_observer.go b/zetaclient/zetacore_observer.go index 6fae898ece..dbce742826 100644 --- a/zetaclient/zetacore_observer.go +++ b/zetaclient/zetacore_observer.go @@ -342,7 +342,7 @@ func (co *CoreObserver) scheduleCctxBTC( } if included || confirmed { co.logger.ZetaChainWatcher.Info().Msgf("scheduleCctxBTC: outtx %s already included; do not schedule keysign", outTxID) - return + continue } // stop if the nonce being processed is higher than the pending nonce