From a9c613ba25df7245dc5f8938f0a837333e600753 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 11 Jan 2024 12:59:20 -0800 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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)