From 09f2018230724c355db1cfa1735c4c3929e81cc7 Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 3 Apr 2024 17:41:53 +0100 Subject: [PATCH 1/2] test: improve crosschain module coverage (#1967) --- changelog.md | 1 + codecov.yml | 2 + .../zetacored/zetacored_query_crosschain.md | 1 - .../zetacored_query_crosschain_params.md | 33 - docs/openapi/openapi.swagger.yaml | 28 - proto/crosschain/genesis.proto | 18 +- proto/crosschain/params.proto | 12 - proto/crosschain/query.proto | 15 - testutil/keeper/crosschain.go | 4 +- testutil/network/genesis_state.go | 1 - testutil/sample/crosschain.go | 10 + typescript/crosschain/genesis_pb.d.ts | 22 +- typescript/crosschain/index.d.ts | 1 - typescript/crosschain/params_pb.d.ts | 34 - typescript/crosschain/query_pb.d.ts | 50 -- x/crosschain/client/cli/cli_params.go | 34 - x/crosschain/client/cli/query.go | 1 - x/crosschain/genesis.go | 4 - x/crosschain/genesis_test.go | 11 +- x/crosschain/keeper/cctx_test.go | 10 + x/crosschain/keeper/cctx_utils.go | 4 +- x/crosschain/keeper/cctx_utils_test.go | 158 +++++ x/crosschain/keeper/evm_deposit_test.go | 152 ++++- x/crosschain/keeper/foreign_coins_test.go | 20 + x/crosschain/keeper/grpc_query_cctx_test.go | 130 +++- .../keeper/grpc_query_gas_price_test.go | 10 +- .../keeper/grpc_query_in_tx_tracker_test.go | 49 ++ .../keeper/grpc_query_last_block_height.go | 6 +- .../grpc_query_last_block_height_test.go | 34 + .../keeper/grpc_query_last_zeta_height.go | 3 +- .../grpc_query_last_zeta_height_test.go | 39 ++ .../keeper/grpc_query_out_tx_tracker_test.go | 192 +++--- .../grpc_query_zeta_conversion_rate_test.go | 120 ++++ .../msg_server_add_to_intx_tracker_test.go | 25 +- .../msg_server_add_to_outtx_tracker_test.go | 109 ++- .../keeper/msg_server_gas_price_voter.go | 5 +- .../keeper/msg_server_gas_price_voter_test.go | 204 ++++++ .../keeper/msg_server_migrate_tss_funds.go | 4 + .../msg_server_migrate_tss_funds_test.go | 212 +++++- .../msg_server_refund_aborted_tx_test.go | 64 ++ .../msg_server_remove_out_tx_tracker_test.go | 66 ++ .../keeper/msg_server_update_tss_test.go | 36 + .../keeper/msg_server_vote_inbound_tx_test.go | 88 +++ .../msg_server_vote_outbound_tx_test.go | 4 +- x/crosschain/keeper/params.go | 31 - x/crosschain/keeper/process_inbound.go | 12 +- x/crosschain/keeper/process_inbound_test.go | 102 ++- x/crosschain/keeper/process_outbound_test.go | 56 +- x/crosschain/keeper/refund_test.go | 188 ++++++ x/crosschain/keeper/verify_proof_test.go | 393 +++++++++++ x/crosschain/keeper/zeta_accounting_test.go | 13 +- x/crosschain/module.go | 7 +- x/crosschain/module_simulation.go | 4 +- x/crosschain/types/client_ctx.go | 14 - x/crosschain/types/genesis.pb.go | 167 ++--- x/crosschain/types/genesis_test.go | 20 + x/crosschain/types/params.go | 44 -- x/crosschain/types/params.pb.go | 307 --------- x/crosschain/types/query.pb.go | 628 ++++-------------- x/crosschain/types/query.pb.gw.go | 65 -- x/crosschain/types/status.go | 1 - x/crosschain/types/status_test.go | 75 +++ 62 files changed, 2676 insertions(+), 1477 deletions(-) delete mode 100644 docs/cli/zetacored/zetacored_query_crosschain_params.md delete mode 100644 proto/crosschain/params.proto delete mode 100644 typescript/crosschain/params_pb.d.ts delete mode 100644 x/crosschain/client/cli/cli_params.go create mode 100644 x/crosschain/keeper/foreign_coins_test.go create mode 100644 x/crosschain/keeper/grpc_query_in_tx_tracker_test.go create mode 100644 x/crosschain/keeper/grpc_query_last_zeta_height_test.go create mode 100644 x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go create mode 100644 x/crosschain/keeper/msg_server_gas_price_voter_test.go create mode 100644 x/crosschain/keeper/msg_server_remove_out_tx_tracker_test.go delete mode 100644 x/crosschain/keeper/params.go create mode 100644 x/crosschain/keeper/verify_proof_test.go delete mode 100644 x/crosschain/types/client_ctx.go delete mode 100644 x/crosschain/types/params.go delete mode 100644 x/crosschain/types/params.pb.go diff --git a/changelog.md b/changelog.md index 055e9f9283..8fe144056a 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,7 @@ * [1879](https://github.com/zeta-chain/node/pull/1879) - full coverage for messages in types packages * [1899](https://github.com/zeta-chain/node/pull/1899) - add empty test files so packages are included in coverage * [1903](https://github.com/zeta-chain/node/pull/1903) - common package tests +* [1967](https://github.com/zeta-chain/node/pull/1967) - improve crosschain module coverage * [1955](https://github.com/zeta-chain/node/pull/1955) - improve emissions module coverage ### Fixes diff --git a/codecov.yml b/codecov.yml index 1a9ba2063d..aab4d9ab68 100644 --- a/codecov.yml +++ b/codecov.yml @@ -49,6 +49,8 @@ ignore: - "x/**/types/types.go" - "x/**/types/expected_keepers.go" - "x/**/module.go" + - "x/**/events.go" + - "x/**/migrator.go" - "x/**/module_simulation.go" - "x/**/simulation/**/*" - "**/*.proto" diff --git a/docs/cli/zetacored/zetacored_query_crosschain.md b/docs/cli/zetacored/zetacored_query_crosschain.md index 0f973fe712..db80778e2a 100644 --- a/docs/cli/zetacored/zetacored_query_crosschain.md +++ b/docs/cli/zetacored/zetacored_query_crosschain.md @@ -35,7 +35,6 @@ zetacored query crosschain [flags] * [zetacored query crosschain list-in-tx-tracker](zetacored_query_crosschain_list-in-tx-tracker.md) - shows a list of in tx tracker by chainId * [zetacored query crosschain list-out-tx-tracker](zetacored_query_crosschain_list-out-tx-tracker.md) - list all OutTxTracker * [zetacored query crosschain list-pending-cctx](zetacored_query_crosschain_list-pending-cctx.md) - shows pending CCTX -* [zetacored query crosschain params](zetacored_query_crosschain_params.md) - shows the parameters of the module * [zetacored query crosschain show-cctx](zetacored_query_crosschain_show-cctx.md) - shows a CCTX * [zetacored query crosschain show-gas-price](zetacored_query_crosschain_show-gas-price.md) - shows a gasPrice * [zetacored query crosschain show-in-tx-hash-to-cctx](zetacored_query_crosschain_show-in-tx-hash-to-cctx.md) - shows a inTxHashToCctx diff --git a/docs/cli/zetacored/zetacored_query_crosschain_params.md b/docs/cli/zetacored/zetacored_query_crosschain_params.md deleted file mode 100644 index e10e8cb5b1..0000000000 --- a/docs/cli/zetacored/zetacored_query_crosschain_params.md +++ /dev/null @@ -1,33 +0,0 @@ -# query crosschain params - -shows the parameters of the module - -``` -zetacored query crosschain params [flags] -``` - -### Options - -``` - --grpc-addr string the gRPC endpoint to use for this chain - --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS - --height int Use a specific height to query state at (this can error if the node is pruning state) - -h, --help help for params - --node string [host]:[port] to Tendermint RPC interface for this chain - -o, --output string Output format (text|json) -``` - -### Options inherited from parent commands - -``` - --chain-id string The network chain ID - --home string directory for config and data - --log_format string The logging format (json|plain) - --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) - --trace print out full stack trace on errors -``` - -### SEE ALSO - -* [zetacored query crosschain](zetacored_query_crosschain.md) - Querying commands for the crosschain module - diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 2dd9812b64..faf3e60692 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -27173,21 +27173,6 @@ paths: type: boolean tags: - Query - /zeta-chain/crosschain/params: - get: - summary: Parameters queries the parameters of the module. - operationId: Query_Params - responses: - "200": - description: A successful response. - schema: - $ref: '#/definitions/zetacorecrosschainQueryParamsResponse' - default: - description: An unexpected error response. - schema: - $ref: '#/definitions/googlerpcStatus' - tags: - - Query /zeta-chain/crosschain/protocolFee: get: operationId: Query_ProtocolFee @@ -54738,19 +54723,6 @@ definitions: repeated Bar results = 1; PageResponse page = 2; } - zetacorecrosschainParams: - type: object - properties: - enabled: - type: boolean - description: Params defines the parameters for the module. - zetacorecrosschainQueryParamsResponse: - type: object - properties: - params: - $ref: '#/definitions/zetacorecrosschainParams' - description: params holds all the parameters of this module. - description: QueryParamsResponse is response type for the Query/Params RPC method. zetacorecrosschainStatus: type: object properties: diff --git a/proto/crosschain/genesis.proto b/proto/crosschain/genesis.proto index 016fc38aee..87c3875b14 100644 --- a/proto/crosschain/genesis.proto +++ b/proto/crosschain/genesis.proto @@ -7,20 +7,18 @@ import "crosschain/in_tx_hash_to_cctx.proto"; import "crosschain/in_tx_tracker.proto"; import "crosschain/last_block_height.proto"; import "crosschain/out_tx_tracker.proto"; -import "crosschain/params.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; // GenesisState defines the metacore module's genesis state. message GenesisState { - Params params = 1 [(gogoproto.nullable) = false]; - repeated OutTxTracker outTxTrackerList = 2 [(gogoproto.nullable) = false]; - repeated GasPrice gasPriceList = 5; - repeated CrossChainTx CrossChainTxs = 7; - repeated LastBlockHeight lastBlockHeightList = 8; - 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; + repeated OutTxTracker outTxTrackerList = 1 [(gogoproto.nullable) = false]; + repeated GasPrice gasPriceList = 2; + repeated CrossChainTx CrossChainTxs = 3; + repeated LastBlockHeight lastBlockHeightList = 4; + repeated InTxHashToCctx inTxHashToCctxList = 5 [(gogoproto.nullable) = false]; + repeated InTxTracker in_tx_tracker_list = 6 [(gogoproto.nullable) = false]; + ZetaAccounting zeta_accounting = 7 [(gogoproto.nullable) = false]; + repeated string FinalizedInbounds = 8; } diff --git a/proto/crosschain/params.proto b/proto/crosschain/params.proto deleted file mode 100644 index 5df98b9a28..0000000000 --- a/proto/crosschain/params.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; -package zetachain.zetacore.crosschain; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; - -// Params defines the parameters for the module. -message Params { - option (gogoproto.goproto_stringer) = false; - bool enabled = 1; -} diff --git a/proto/crosschain/query.proto b/proto/crosschain/query.proto index c9eee26378..99ad6b4b72 100644 --- a/proto/crosschain/query.proto +++ b/proto/crosschain/query.proto @@ -8,7 +8,6 @@ import "crosschain/in_tx_hash_to_cctx.proto"; import "crosschain/in_tx_tracker.proto"; import "crosschain/last_block_height.proto"; import "crosschain/out_tx_tracker.proto"; -import "crosschain/params.proto"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; @@ -16,11 +15,6 @@ option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types"; // Query defines the gRPC querier service. service Query { - // Parameters queries the parameters of the module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/zeta-chain/crosschain/params"; - } - // Queries a OutTxTracker by index. rpc OutTxTracker(QueryGetOutTxTrackerRequest) returns (QueryGetOutTxTrackerResponse) { option (google.api.http).get = "/zeta-chain/crosschain/outTxTracker/{chainID}/{nonce}"; @@ -120,15 +114,6 @@ message QueryZetaAccountingResponse { string aborted_zeta_amount = 1; } -// QueryParamsRequest is request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is response type for the Query/Params RPC method. -message QueryParamsResponse { - // params holds all the parameters of this module. - Params params = 1 [(gogoproto.nullable) = false]; -} - message QueryGetOutTxTrackerRequest { int64 chainID = 1; uint64 nonce = 2; diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index 04bbcf7ac9..3fb8f81823 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -198,13 +198,13 @@ func MockGetSupportedChainFromChainID(m *crosschainmocks.CrosschainObserverKeepe Return(senderChain).Once() } -func MockGetRevertGasLimitForERC20(m *crosschainmocks.CrosschainFungibleKeeper, asset string, senderChain chains.Chain) { +func MockGetRevertGasLimitForERC20(m *crosschainmocks.CrosschainFungibleKeeper, asset string, senderChain chains.Chain, returnVal int64) { m.On("GetForeignCoinFromAsset", mock.Anything, asset, senderChain.ChainId). Return(fungibletypes.ForeignCoins{ Zrc20ContractAddress: sample.EthAddress().String(), }, true).Once() m.On("QueryGasLimit", mock.Anything, mock.Anything). - Return(big.NewInt(100), nil).Once() + Return(big.NewInt(returnVal), nil).Once() } func MockPayGasAndUpdateCCTX(m *crosschainmocks.CrosschainFungibleKeeper, m2 *crosschainmocks.CrosschainObserverKeeper, ctx sdk.Context, k keeper.Keeper, senderChain chains.Chain, asset string) { diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index 3fdb627b22..dfa3364cfe 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -34,7 +34,6 @@ func SetupZetaGenesisState(t *testing.T, genesisState map[string]json.RawMessage } } - crossChainGenesis.Params.Enabled = true require.NoError(t, crossChainGenesis.Validate()) crossChainGenesisBz, err := codec.MarshalJSON(&crossChainGenesis) require.NoError(t, err) diff --git a/testutil/sample/crosschain.go b/testutil/sample/crosschain.go index 0fe91e0c2e..0040a7fc3a 100644 --- a/testutil/sample/crosschain.go +++ b/testutil/sample/crosschain.go @@ -24,6 +24,16 @@ func OutTxTracker(t *testing.T, index string) types.OutTxTracker { } } +func InTxTracker(t *testing.T, index string) types.InTxTracker { + r := newRandFromStringSeed(t, index) + + return types.InTxTracker{ + ChainId: r.Int63(), + CoinType: coin.CoinType_Zeta, + TxHash: Hash().Hex(), + } +} + func GasPrice(t *testing.T, index string) *types.GasPrice { r := newRandFromStringSeed(t, index) diff --git a/typescript/crosschain/genesis_pb.d.ts b/typescript/crosschain/genesis_pb.d.ts index e8c8d5dcf0..bec622e2af 100644 --- a/typescript/crosschain/genesis_pb.d.ts +++ b/typescript/crosschain/genesis_pb.d.ts @@ -5,7 +5,6 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; -import type { Params } from "./params_pb.js"; import type { OutTxTracker } from "./out_tx_tracker_pb.js"; import type { GasPrice } from "./gas_price_pb.js"; import type { CrossChainTx, ZetaAccounting } from "./cross_chain_tx_pb.js"; @@ -20,47 +19,42 @@ import type { InTxTracker } from "./in_tx_tracker_pb.js"; */ export declare class GenesisState extends Message { /** - * @generated from field: zetachain.zetacore.crosschain.Params params = 1; - */ - params?: Params; - - /** - * @generated from field: repeated zetachain.zetacore.crosschain.OutTxTracker outTxTrackerList = 2; + * @generated from field: repeated zetachain.zetacore.crosschain.OutTxTracker outTxTrackerList = 1; */ outTxTrackerList: OutTxTracker[]; /** - * @generated from field: repeated zetachain.zetacore.crosschain.GasPrice gasPriceList = 5; + * @generated from field: repeated zetachain.zetacore.crosschain.GasPrice gasPriceList = 2; */ gasPriceList: GasPrice[]; /** - * @generated from field: repeated zetachain.zetacore.crosschain.CrossChainTx CrossChainTxs = 7; + * @generated from field: repeated zetachain.zetacore.crosschain.CrossChainTx CrossChainTxs = 3; */ CrossChainTxs: CrossChainTx[]; /** - * @generated from field: repeated zetachain.zetacore.crosschain.LastBlockHeight lastBlockHeightList = 8; + * @generated from field: repeated zetachain.zetacore.crosschain.LastBlockHeight lastBlockHeightList = 4; */ lastBlockHeightList: LastBlockHeight[]; /** - * @generated from field: repeated zetachain.zetacore.crosschain.InTxHashToCctx inTxHashToCctxList = 9; + * @generated from field: repeated zetachain.zetacore.crosschain.InTxHashToCctx inTxHashToCctxList = 5; */ inTxHashToCctxList: InTxHashToCctx[]; /** - * @generated from field: repeated zetachain.zetacore.crosschain.InTxTracker in_tx_tracker_list = 11; + * @generated from field: repeated zetachain.zetacore.crosschain.InTxTracker in_tx_tracker_list = 6; */ inTxTrackerList: InTxTracker[]; /** - * @generated from field: zetachain.zetacore.crosschain.ZetaAccounting zeta_accounting = 12; + * @generated from field: zetachain.zetacore.crosschain.ZetaAccounting zeta_accounting = 7; */ zetaAccounting?: ZetaAccounting; /** - * @generated from field: repeated string FinalizedInbounds = 16; + * @generated from field: repeated string FinalizedInbounds = 8; */ FinalizedInbounds: string[]; diff --git a/typescript/crosschain/index.d.ts b/typescript/crosschain/index.d.ts index 4c073541bc..e357b4b8b3 100644 --- a/typescript/crosschain/index.d.ts +++ b/typescript/crosschain/index.d.ts @@ -6,6 +6,5 @@ export * from "./in_tx_hash_to_cctx_pb"; export * from "./in_tx_tracker_pb"; export * from "./last_block_height_pb"; export * from "./out_tx_tracker_pb"; -export * from "./params_pb"; export * from "./query_pb"; export * from "./tx_pb"; diff --git a/typescript/crosschain/params_pb.d.ts b/typescript/crosschain/params_pb.d.ts deleted file mode 100644 index e3c135725c..0000000000 --- a/typescript/crosschain/params_pb.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -// @generated by protoc-gen-es v1.3.0 with parameter "target=dts" -// @generated from file crosschain/params.proto (package zetachain.zetacore.crosschain, syntax proto3) -/* eslint-disable */ -// @ts-nocheck - -import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; -import { Message, proto3 } from "@bufbuild/protobuf"; - -/** - * Params defines the parameters for the module. - * - * @generated from message zetachain.zetacore.crosschain.Params - */ -export declare class Params extends Message { - /** - * @generated from field: bool enabled = 1; - */ - enabled: boolean; - - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.crosschain.Params"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): Params; - - static fromJson(jsonValue: JsonValue, options?: Partial): Params; - - static fromJsonString(jsonString: string, options?: Partial): Params; - - static equals(a: Params | PlainMessage | undefined, b: Params | PlainMessage | undefined): boolean; -} - diff --git a/typescript/crosschain/query_pb.d.ts b/typescript/crosschain/query_pb.d.ts index 17bb54ef27..370926427e 100644 --- a/typescript/crosschain/query_pb.d.ts +++ b/typescript/crosschain/query_pb.d.ts @@ -5,7 +5,6 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; -import type { Params } from "./params_pb.js"; import type { OutTxTracker } from "./out_tx_tracker_pb.js"; import type { PageRequest, PageResponse } from "../cosmos/base/query/v1beta1/pagination_pb.js"; import type { InTxTracker } from "./in_tx_tracker_pb.js"; @@ -57,55 +56,6 @@ export declare class QueryZetaAccountingResponse extends Message | undefined, b: QueryZetaAccountingResponse | PlainMessage | undefined): boolean; } -/** - * QueryParamsRequest is request type for the Query/Params RPC method. - * - * @generated from message zetachain.zetacore.crosschain.QueryParamsRequest - */ -export declare class QueryParamsRequest extends Message { - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.crosschain.QueryParamsRequest"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): QueryParamsRequest; - - static fromJson(jsonValue: JsonValue, options?: Partial): QueryParamsRequest; - - static fromJsonString(jsonString: string, options?: Partial): QueryParamsRequest; - - static equals(a: QueryParamsRequest | PlainMessage | undefined, b: QueryParamsRequest | PlainMessage | undefined): boolean; -} - -/** - * QueryParamsResponse is response type for the Query/Params RPC method. - * - * @generated from message zetachain.zetacore.crosschain.QueryParamsResponse - */ -export declare class QueryParamsResponse extends Message { - /** - * params holds all the parameters of this module. - * - * @generated from field: zetachain.zetacore.crosschain.Params params = 1; - */ - params?: Params; - - constructor(data?: PartialMessage); - - static readonly runtime: typeof proto3; - static readonly typeName = "zetachain.zetacore.crosschain.QueryParamsResponse"; - static readonly fields: FieldList; - - static fromBinary(bytes: Uint8Array, options?: Partial): QueryParamsResponse; - - static fromJson(jsonValue: JsonValue, options?: Partial): QueryParamsResponse; - - static fromJsonString(jsonString: string, options?: Partial): QueryParamsResponse; - - static equals(a: QueryParamsResponse | PlainMessage | undefined, b: QueryParamsResponse | PlainMessage | undefined): boolean; -} - /** * @generated from message zetachain.zetacore.crosschain.QueryGetOutTxTrackerRequest */ diff --git a/x/crosschain/client/cli/cli_params.go b/x/crosschain/client/cli/cli_params.go deleted file mode 100644 index 6a42068cfa..0000000000 --- a/x/crosschain/client/cli/cli_params.go +++ /dev/null @@ -1,34 +0,0 @@ -package cli - -import ( - "context" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - "github.com/zeta-chain/zetacore/x/crosschain/types" -) - -func CmdQueryParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "shows the parameters of the module", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/crosschain/client/cli/query.go b/x/crosschain/client/cli/query.go index 633e76e143..cd966e55af 100644 --- a/x/crosschain/client/cli/query.go +++ b/x/crosschain/client/cli/query.go @@ -37,7 +37,6 @@ func GetQueryCmd(_ string) *cobra.Command { CmdInTxHashToCctxData(), CmdListInTxHashToCctx(), CmdShowInTxHashToCctx(), - CmdQueryParams(), CmdPendingCctx(), CmdListInTxTrackerByChain(), diff --git a/x/crosschain/genesis.go b/x/crosschain/genesis.go index d152c32bb3..c2603532a6 100644 --- a/x/crosschain/genesis.go +++ b/x/crosschain/genesis.go @@ -9,9 +9,6 @@ import ( // InitGenesis initializes the crosschain module's state from a provided genesis // state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { - // Params - k.SetParams(ctx, genState.Params) - k.SetZetaAccounting(ctx, genState.ZetaAccounting) // Set all the outTxTracker for _, elem := range genState.OutTxTrackerList { @@ -59,7 +56,6 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { var genesis types.GenesisState - genesis.Params = k.GetParams(ctx) genesis.OutTxTrackerList = k.GetAllOutTxTracker(ctx) genesis.InTxHashToCctxList = k.GetAllInTxHashToCctx(ctx) genesis.InTxTrackerList = k.GetAllInTxTracker(ctx) diff --git a/x/crosschain/genesis_test.go b/x/crosschain/genesis_test.go index 3ce6a94875..470d07b09b 100644 --- a/x/crosschain/genesis_test.go +++ b/x/crosschain/genesis_test.go @@ -13,13 +13,22 @@ import ( func TestGenesis(t *testing.T) { genesisState := types.GenesisState{ - Params: types.DefaultParams(), ZetaAccounting: sample.ZetaAccounting(t, "sample"), OutTxTrackerList: []types.OutTxTracker{ sample.OutTxTracker(t, "0"), sample.OutTxTracker(t, "1"), sample.OutTxTracker(t, "2"), }, + InTxTrackerList: []types.InTxTracker{ + sample.InTxTracker(t, "0"), + sample.InTxTracker(t, "1"), + sample.InTxTracker(t, "2"), + }, + FinalizedInbounds: []string{ + sample.Hash().String(), + sample.Hash().String(), + sample.Hash().String(), + }, GasPriceList: []*types.GasPrice{ sample.GasPrice(t, "0"), sample.GasPrice(t, "1"), diff --git a/x/crosschain/keeper/cctx_test.go b/x/crosschain/keeper/cctx_test.go index 3f8c3fe4d4..3a7fb7fe5b 100644 --- a/x/crosschain/keeper/cctx_test.go +++ b/x/crosschain/keeper/cctx_test.go @@ -243,3 +243,13 @@ func TestSendQueryPaginated(t *testing.T) { require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) }) } + +func TestKeeper_RemoveCrossChainTx(t *testing.T) { + keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) + zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) + txs := createNCctx(keeper, ctx, 5) + + keeper.RemoveCrossChainTx(ctx, txs[0].Index) + txs = keeper.GetAllCrossChainTx(ctx) + require.Equal(t, 4, len(txs)) +} diff --git a/x/crosschain/keeper/cctx_utils.go b/x/crosschain/keeper/cctx_utils.go index 0fde2fb2e6..6ae826f9ed 100644 --- a/x/crosschain/keeper/cctx_utils.go +++ b/x/crosschain/keeper/cctx_utils.go @@ -18,7 +18,7 @@ import ( // UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state. // It also updates the PendingNonces that is used to track the unfulfilled outbound txs. func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error { - chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, receiveChainID) + chain := k.GetObserverKeeper().GetSupportedChainFromChainID(ctx, receiveChainID) if chain == nil { return zetaObserverTypes.ErrSupportedChains } @@ -30,7 +30,7 @@ func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.C // SET nonce cctx.GetCurrentOutTxParam().OutboundTxTssNonce = nonce.Nonce - tss, found := k.zetaObserverKeeper.GetTSS(ctx) + tss, found := k.GetObserverKeeper().GetTSS(ctx) if !found { return cosmoserrors.Wrap(types.ErrCannotFindTSSKeys, fmt.Sprintf("Chain(%s) | Identifiers : %s ", chain.ChainName.String(), cctx.LogIdentifierForCCTX())) } diff --git a/x/crosschain/keeper/cctx_utils_test.go b/x/crosschain/keeper/cctx_utils_test.go index 888b3bf445..1c807a97c1 100644 --- a/x/crosschain/keeper/cctx_utils_test.go +++ b/x/crosschain/keeper/cctx_utils_test.go @@ -6,13 +6,16 @@ import ( "testing" sdkmath "cosmossdk.io/math" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" crosschainkeeper "github.com/zeta-chain/zetacore/x/crosschain/keeper" "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) func TestGetRevertGasLimit(t *testing.T) { @@ -216,3 +219,158 @@ func Test_IsPending(t *testing.T) { }) } } + +func TestKeeper_UpdateNonce(t *testing.T) { + t.Run("should error if supported chain is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(nil) + + err := k.UpdateNonce(ctx, 5, nil) + require.Error(t, err) + }) + + t.Run("should error if chain nonces not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainName: 5, + ChainId: 5, + }) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observertypes.ChainNonces{}, false) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + Amount: sdkmath.ZeroUint(), + }, + OutboundTxParams: []*types.OutboundTxParams{ + {Amount: sdkmath.NewUint(1)}, + }, + } + err := k.UpdateNonce(ctx, 5, &cctx) + require.Error(t, err) + }) + + t.Run("should error if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainName: 5, + ChainId: 5, + }) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observertypes.ChainNonces{ + Nonce: 100, + }, true) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, false) + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + Amount: sdkmath.ZeroUint(), + }, + OutboundTxParams: []*types.OutboundTxParams{ + {Amount: sdkmath.NewUint(1)}, + }, + } + err := k.UpdateNonce(ctx, 5, &cctx) + require.Error(t, err) + require.Equal(t, uint64(100), cctx.GetCurrentOutTxParam().OutboundTxTssNonce) + }) + + t.Run("should error if pending nonces not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainName: 5, + ChainId: 5, + }) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observertypes.ChainNonces{ + Nonce: 100, + }, true) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observertypes.PendingNonces{}, false) + + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + Amount: sdkmath.ZeroUint(), + }, + OutboundTxParams: []*types.OutboundTxParams{ + {Amount: sdkmath.NewUint(1)}, + }, + } + err := k.UpdateNonce(ctx, 5, &cctx) + require.Error(t, err) + }) + + t.Run("should error if nonces not equal", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainName: 5, + ChainId: 5, + }) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observertypes.ChainNonces{ + Nonce: 100, + }, true) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observertypes.PendingNonces{ + NonceHigh: 99, + }, true) + + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + Amount: sdkmath.ZeroUint(), + }, + OutboundTxParams: []*types.OutboundTxParams{ + {Amount: sdkmath.NewUint(1)}, + }, + } + err := k.UpdateNonce(ctx, 5, &cctx) + require.Error(t, err) + }) + + t.Run("should update nonces", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainName: 5, + ChainId: 5, + }) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observertypes.ChainNonces{ + Nonce: 100, + }, true) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observertypes.PendingNonces{ + NonceHigh: 100, + }, true) + + observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Once() + observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Once() + + cctx := types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + Amount: sdkmath.ZeroUint(), + }, + OutboundTxParams: []*types.OutboundTxParams{ + {Amount: sdkmath.NewUint(1)}, + }, + } + err := k.UpdateNonce(ctx, 5, &cctx) + require.NoError(t, err) + }) +} diff --git a/x/crosschain/keeper/evm_deposit_test.go b/x/crosschain/keeper/evm_deposit_test.go index bcb7b684e8..f82872566a 100644 --- a/x/crosschain/keeper/evm_deposit_test.go +++ b/x/crosschain/keeper/evm_deposit_test.go @@ -117,6 +117,152 @@ func TestMsgServer_HandleEVMDeposit(t *testing.T) { fungibleMock.AssertExpectations(t) }) + t.Run("should error on processing ERC20 deposit calling fungible method for contract call if process logs fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + senderChain := getValidEthChainID(t) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + receiver := sample.EthAddress() + amount := big.NewInt(42) + + // expect DepositCoinZeta to be called + // ZRC20DepositAndCallContract(ctx, from, to, msg.Amount.BigInt(), senderChain, msg.Message, contract, data, msg.CoinType, msg.Asset) + fungibleMock.On( + "ZRC20DepositAndCallContract", + ctx, + mock.Anything, + receiver, + amount, + senderChain, + mock.Anything, + coin.CoinType_ERC20, + mock.Anything, + ).Return(&evmtypes.MsgEthereumTxResponse{ + Logs: []*evmtypes.Log{ + { + Address: receiver.Hex(), + Topics: []string{}, + Data: []byte{}, + BlockNumber: uint64(ctx.BlockHeight()), + TxHash: sample.Hash().Hex(), + TxIndex: 1, + BlockHash: sample.Hash().Hex(), + Index: 1, + }, + }, + }, true, nil) + + fungibleMock.On("GetSystemContract", mock.Anything).Return(fungibletypes.SystemContract{}, false) + + // call HandleEVMDeposit + cctx := sample.CrossChainTx(t, "foo") + cctx.InboundTxParams.TxOrigin = "" + cctx.GetCurrentOutTxParam().Receiver = receiver.String() + cctx.GetInboundTxParams().Amount = math.NewUintFromBigInt(amount) + cctx.GetInboundTxParams().CoinType = coin.CoinType_ERC20 + cctx.GetInboundTxParams().Sender = sample.EthAddress().String() + cctx.GetInboundTxParams().SenderChainId = senderChain + cctx.RelayedMessage = "" + cctx.GetInboundTxParams().Asset = "" + reverted, err := k.HandleEVMDeposit( + ctx, + cctx, + ) + require.Error(t, err) + require.False(t, reverted) + fungibleMock.AssertExpectations(t) + }) + + t.Run("can process ERC20 deposit calling fungible method for contract call if process logs doesnt fail", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + senderChain := getValidEthChainID(t) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + receiver := sample.EthAddress() + amount := big.NewInt(42) + + // expect DepositCoinZeta to be called + // ZRC20DepositAndCallContract(ctx, from, to, msg.Amount.BigInt(), senderChain, msg.Message, contract, data, msg.CoinType, msg.Asset) + fungibleMock.On( + "ZRC20DepositAndCallContract", + ctx, + mock.Anything, + receiver, + amount, + senderChain, + mock.Anything, + coin.CoinType_ERC20, + mock.Anything, + ).Return(&evmtypes.MsgEthereumTxResponse{ + Logs: []*evmtypes.Log{ + { + Address: receiver.Hex(), + Topics: []string{}, + Data: []byte{}, + BlockNumber: uint64(ctx.BlockHeight()), + TxHash: sample.Hash().Hex(), + TxIndex: 1, + BlockHash: sample.Hash().Hex(), + Index: 1, + }, + }, + }, true, nil) + + fungibleMock.On("GetSystemContract", mock.Anything).Return(fungibletypes.SystemContract{ + ConnectorZevm: sample.EthAddress().Hex(), + }, true) + + // call HandleEVMDeposit + cctx := sample.CrossChainTx(t, "foo") + cctx.InboundTxParams.TxOrigin = "" + cctx.GetCurrentOutTxParam().Receiver = receiver.String() + cctx.GetInboundTxParams().Amount = math.NewUintFromBigInt(amount) + cctx.GetInboundTxParams().CoinType = coin.CoinType_ERC20 + cctx.GetInboundTxParams().Sender = sample.EthAddress().String() + cctx.GetInboundTxParams().SenderChainId = senderChain + cctx.RelayedMessage = "" + cctx.GetInboundTxParams().Asset = "" + reverted, err := k.HandleEVMDeposit( + ctx, + cctx, + ) + require.NoError(t, err) + require.False(t, reverted) + fungibleMock.AssertExpectations(t) + }) + + t.Run("should error if invalid sender", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + receiver := sample.EthAddress() + amount := big.NewInt(42) + + // call HandleEVMDeposit + cctx := sample.CrossChainTx(t, "foo") + cctx.InboundTxParams.TxOrigin = "" + cctx.GetCurrentOutTxParam().Receiver = receiver.String() + cctx.GetInboundTxParams().Amount = math.NewUintFromBigInt(amount) + cctx.GetInboundTxParams().CoinType = coin.CoinType_ERC20 + cctx.GetInboundTxParams().Sender = "invalid" + cctx.GetInboundTxParams().SenderChainId = 987 + cctx.RelayedMessage = "" + cctx.GetInboundTxParams().Asset = "" + reverted, err := k.HandleEVMDeposit( + ctx, + cctx, + ) + require.Error(t, err) + require.False(t, reverted) + }) + t.Run("should return error with non-reverted if deposit ERC20 fails with tx non-failed", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -366,6 +512,10 @@ func TestMsgServer_HandleEVMDeposit(t *testing.T) { data, err := hex.DecodeString("DEADBEEF") require.NoError(t, err) + cctx := sample.CrossChainTx(t, "foo") + b, err := cctx.Marshal() + require.NoError(t, err) + ctx = ctx.WithTxBytes(b) fungibleMock.On( "ZRC20DepositAndCallContract", ctx, @@ -378,7 +528,6 @@ func TestMsgServer_HandleEVMDeposit(t *testing.T) { mock.Anything, ).Return(&evmtypes.MsgEthereumTxResponse{}, false, nil) - cctx := sample.CrossChainTx(t, "foo") cctx.GetCurrentOutTxParam().Receiver = sample.EthAddress().String() cctx.GetInboundTxParams().Amount = math.NewUintFromBigInt(amount) cctx.GetInboundTxParams().CoinType = coin.CoinType_ERC20 @@ -393,6 +542,7 @@ func TestMsgServer_HandleEVMDeposit(t *testing.T) { require.NoError(t, err) require.False(t, reverted) fungibleMock.AssertExpectations(t) + require.Equal(t, uint64(ctx.BlockHeight()), cctx.GetCurrentOutTxParam().OutboundTxObservedExternalHeight) }) t.Run("should deposit into receiver with specified data if no address parsed with data", func(t *testing.T) { diff --git a/x/crosschain/keeper/foreign_coins_test.go b/x/crosschain/keeper/foreign_coins_test.go new file mode 100644 index 0000000000..5d145b08f1 --- /dev/null +++ b/x/crosschain/keeper/foreign_coins_test.go @@ -0,0 +1,20 @@ +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" +) + +func TestKeeper_GetAllForeignCoins(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + fc := sample.ForeignCoins(t, sample.EthAddress().Hex()) + fc.ForeignChainId = 101 + k.GetFungibleKeeper().SetForeignCoins(ctx, fc) + + res, err := k.GetAllForeignCoins(ctx) + require.NoError(t, err) + require.Equal(t, 1, len(res)) +} diff --git a/x/crosschain/keeper/grpc_query_cctx_test.go b/x/crosschain/keeper/grpc_query_cctx_test.go index 6865d6d51e..59b0b68863 100644 --- a/x/crosschain/keeper/grpc_query_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_cctx_test.go @@ -64,7 +64,6 @@ func createCctxWithNonceRange( } func TestKeeper_CctxListPending(t *testing.T) { - t.Run("should fail for empty req", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) _, err := k.CctxListPending(ctx, nil) @@ -155,4 +154,133 @@ func TestKeeper_CctxListPending(t *testing.T) { // pending nonce + 2 require.EqualValues(t, uint64(1002), res.TotalPending) }) + + t.Run("error if some before low nonce are missing", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + cctxs := createCctxWithNonceRange(t, ctx, *k, 1000, 2000, chainID, tss, zk) + + // set some cctxs as pending below nonce + cctx1, found := k.GetCrossChainTx(ctx, sample.GetCctxIndexFromString("1337-940")) + require.True(t, found) + cctx1.CctxStatus.Status = types.CctxStatus_PendingOutbound + k.SetCrossChainTx(ctx, cctx1) + + cctx2, found := k.GetCrossChainTx(ctx, sample.GetCctxIndexFromString("1337-955")) + require.True(t, found) + cctx2.CctxStatus.Status = types.CctxStatus_PendingOutbound + k.SetCrossChainTx(ctx, cctx2) + + res, err := k.CctxListPending(ctx, &types.QueryListCctxPendingRequest{ChainId: chainID, Limit: 100}) + require.NoError(t, err) + require.Equal(t, 100, len(res.CrossChainTx)) + + expectedCctxs := append([]*types.CrossChainTx{&cctx1, &cctx2}, cctxs[0:98]...) + require.EqualValues(t, expectedCctxs, res.CrossChainTx) + + // pending nonce + 2 + require.EqualValues(t, uint64(1002), res.TotalPending) + }) +} + +func TestKeeper_ZetaAccounting(t *testing.T) { + t.Run("should error if zeta accounting not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ZetaAccounting(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return zeta accounting if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetZetaAccounting(ctx, types.ZetaAccounting{ + AbortedZetaAmount: sdk.NewUint(100), + }) + + res, err := k.ZetaAccounting(ctx, nil) + require.NoError(t, err) + require.Equal(t, &types.QueryZetaAccountingResponse{ + AbortedZetaAmount: sdk.NewUint(100).String(), + }, res) + }) +} + +func TestKeeper_CctxByNonce(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.CctxByNonce(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if nonce to cctx not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if crosschain tx not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + nonce := 1000 + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, nonce)) + + zk.ObserverKeeper.SetNonceToCctx(ctx, observertypes.NonceToCctx{ + ChainId: chainID, + Nonce: int64(nonce), + CctxIndex: cctx.Index, + Tss: tss.TssPubkey, + }) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + Nonce: uint64(nonce), + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if crosschain tx found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + chainID := getValidEthChainID(t) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + nonce := 1000 + cctx := sample.CrossChainTx(t, fmt.Sprintf("%d-%d", chainID, nonce)) + + zk.ObserverKeeper.SetNonceToCctx(ctx, observertypes.NonceToCctx{ + ChainId: chainID, + Nonce: int64(nonce), + CctxIndex: cctx.Index, + Tss: tss.TssPubkey, + }) + k.SetCrossChainTx(ctx, *cctx) + + res, err := k.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ + ChainID: chainID, + Nonce: uint64(nonce), + }) + require.NoError(t, err) + require.Equal(t, cctx, res.CrossChainTx) + }) } diff --git a/x/crosschain/keeper/grpc_query_gas_price_test.go b/x/crosschain/keeper/grpc_query_gas_price_test.go index cc48e2f3b0..b8e9f0606e 100644 --- a/x/crosschain/keeper/grpc_query_gas_price_test.go +++ b/x/crosschain/keeper/grpc_query_gas_price_test.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -37,15 +38,20 @@ func TestGasPriceQuerySingle(t *testing.T) { err: status.Error(codes.InvalidArgument, "not found"), }, { - desc: "InvalidRequest", + desc: "InvalidRequest nil", err: status.Error(codes.InvalidArgument, "invalid request"), }, + { + desc: "InvalidRequest index", + request: &types.QueryGetGasPriceRequest{Index: "abc"}, + err: fmt.Errorf("strconv.Atoi: parsing \"abc\": invalid syntax"), + }, } { tc := tc t.Run(tc.desc, func(t *testing.T) { response, err := keeper.GasPrice(wctx, tc.request) if tc.err != nil { - require.ErrorIs(t, err, tc.err) + require.Error(t, err) } else { require.Equal(t, tc.response, response) } diff --git a/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go b/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go new file mode 100644 index 0000000000..3f1d1738fa --- /dev/null +++ b/x/crosschain/keeper/grpc_query_in_tx_tracker_test.go @@ -0,0 +1,49 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/coin" + 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_InTxTrackerAllByChain(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 1, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 2, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + + res, err := k.InTxTrackerAllByChain(ctx, &types.QueryAllInTxTrackerByChainRequest{ + ChainId: 1, + }) + require.NoError(t, err) + require.Equal(t, 1, len(res.InTxTracker)) +} + +func TestKeeper_InTxTrackerAll(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 1, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + k.SetInTxTracker(ctx, types.InTxTracker{ + ChainId: 2, + TxHash: sample.Hash().Hex(), + CoinType: coin.CoinType_Gas, + }) + + res, err := k.InTxTrackerAll(ctx, &types.QueryAllInTxTrackersRequest{}) + require.NoError(t, err) + require.Equal(t, 2, len(res.InTxTracker)) +} diff --git a/x/crosschain/keeper/grpc_query_last_block_height.go b/x/crosschain/keeper/grpc_query_last_block_height.go index e30a113fb8..633c440dc9 100644 --- a/x/crosschain/keeper/grpc_query_last_block_height.go +++ b/x/crosschain/keeper/grpc_query_last_block_height.go @@ -2,11 +2,11 @@ package keeper import ( "context" + "math" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - math2 "github.com/ethereum/go-ethereum/common/math" "github.com/zeta-chain/zetacore/x/crosschain/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -50,10 +50,10 @@ func (k Keeper) LastBlockHeight(c context.Context, req *types.QueryGetLastBlockH if !found { return nil, status.Error(codes.InvalidArgument, "not found") } - if val.LastSendHeight >= math2.MaxInt64 { + if val.LastSendHeight >= math.MaxInt64 { return nil, status.Error(codes.OutOfRange, "invalid last send height") } - if val.LastReceiveHeight >= math2.MaxInt64 { + if val.LastReceiveHeight >= math.MaxInt64 { return nil, status.Error(codes.OutOfRange, "invalid last recv height") } diff --git a/x/crosschain/keeper/grpc_query_last_block_height_test.go b/x/crosschain/keeper/grpc_query_last_block_height_test.go index f2747bf7c9..057fe120b9 100644 --- a/x/crosschain/keeper/grpc_query_last_block_height_test.go +++ b/x/crosschain/keeper/grpc_query_last_block_height_test.go @@ -1,6 +1,7 @@ package keeper import ( + "math" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -53,6 +54,39 @@ func TestLastBlockHeightQuerySingle(t *testing.T) { } } +func TestLastBlockHeightLimits(t *testing.T) { + t.Run("should err if last send height is max int", func(t *testing.T) { + keeper, ctx := setupKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + keeper.SetLastBlockHeight(ctx, types.LastBlockHeight{ + Index: "index", + LastSendHeight: math.MaxInt64, + }) + + res, err := keeper.LastBlockHeight(wctx, &types.QueryGetLastBlockHeightRequest{ + Index: "index", + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should err if last receive height is max int", func(t *testing.T) { + keeper, ctx := setupKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + keeper.SetLastBlockHeight(ctx, types.LastBlockHeight{ + Index: "index", + LastSendHeight: 10, + LastReceiveHeight: math.MaxInt64, + }) + + res, err := keeper.LastBlockHeight(wctx, &types.QueryGetLastBlockHeightRequest{ + Index: "index", + }) + require.Nil(t, res) + require.Error(t, err) + }) +} + func TestLastBlockHeightQueryPaginated(t *testing.T) { keeper, ctx := setupKeeper(t) wctx := sdk.WrapSDKContext(ctx) diff --git a/x/crosschain/keeper/grpc_query_last_zeta_height.go b/x/crosschain/keeper/grpc_query_last_zeta_height.go index 2d62202751..ff1639d8dd 100644 --- a/x/crosschain/keeper/grpc_query_last_zeta_height.go +++ b/x/crosschain/keeper/grpc_query_last_zeta_height.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -17,7 +16,7 @@ func (k Keeper) LastZetaHeight(goCtx context.Context, req *types.QueryLastZetaHe ctx := sdk.UnwrapSDKContext(goCtx) height := ctx.BlockHeight() - if height >= math.MaxInt64 || height < 0 { + if height < 0 { return nil, status.Error(codes.OutOfRange, "height out of range") } return &types.QueryLastZetaHeightResponse{ diff --git a/x/crosschain/keeper/grpc_query_last_zeta_height_test.go b/x/crosschain/keeper/grpc_query_last_zeta_height_test.go new file mode 100644 index 0000000000..b34a96be20 --- /dev/null +++ b/x/crosschain/keeper/grpc_query_last_zeta_height_test.go @@ -0,0 +1,39 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_LastZetaHeight(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.LastZetaHeight(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if height less than zero", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + ctx = ctx.WithBlockHeight(-1) + res, err := k.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return height if gte 0", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + ctx = ctx.WithBlockHeight(0) + res, err := k.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) + require.NoError(t, err) + require.Equal(t, int64(0), res.Height) + + ctx = ctx.WithBlockHeight(5) + res, err = k.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) + require.NoError(t, err) + require.Equal(t, int64(5), res.Height) + }) +} diff --git a/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go b/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go index 39f5ad3673..c0c5db7e9b 100644 --- a/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go +++ b/x/crosschain/keeper/grpc_query_out_tx_tracker_test.go @@ -1,108 +1,88 @@ package keeper_test -//func TestOutTxTrackerQuerySingle(t *testing.T) { -// keeper, ctx := keepertest.ZetacoreKeeper(t) -// wctx := sdk.WrapSDKContext(ctx) -// msgs := createNOutTxTracker(keeper, ctx, 2) -// for _, tc := range []struct { -// desc string -// request *types.QueryGetOutTxTrackerRequest -// response *types.QueryGetOutTxTrackerResponse -// err error -// }{ -// { -// desc: "First", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: msgs[0].Index, -// }, -// response: &types.QueryGetOutTxTrackerResponse{OutTxTracker: msgs[0]}, -// }, -// { -// desc: "Second", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: msgs[1].Index, -// }, -// response: &types.QueryGetOutTxTrackerResponse{OutTxTracker: msgs[1]}, -// }, -// { -// desc: "KeyNotFound", -// request: &types.QueryGetOutTxTrackerRequest{ -// Index: strconv.Itoa(100000), -// }, -// err: status.Error(codes.NotFound, "not found"), -// }, -// { -// desc: "InvalidRequest", -// err: status.Error(codes.InvalidArgument, "invalid request"), -// }, -// } { -// t.Run(tc.desc, func(t *testing.T) { -// response, err := keeper.OutTxTracker(wctx, tc.request) -// if tc.err != nil { -// require.ErrorIs(t, err, tc.err) -// } else { -// require.NoError(t, err) -// require.Equal(t, -// nullify.Fill(tc.response), -// nullify.Fill(response), -// ) -// } -// }) -// } -//} -// -//func TestOutTxTrackerQueryPaginated(t *testing.T) { -// keeper, ctx := keepertest.ZetacoreKeeper(t) -// wctx := sdk.WrapSDKContext(ctx) -// msgs := createNOutTxTracker(keeper, ctx, 5) -// -// request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllOutTxTrackerRequest { -// return &types.QueryAllOutTxTrackerRequest{ -// Pagination: &query.PageRequest{ -// Key: next, -// Offset: offset, -// Limit: limit, -// CountTotal: total, -// }, -// } -// } -// t.Run("ByOffset", func(t *testing.T) { -// step := 2 -// for i := 0; i < len(msgs); i += step { -// resp, err := keeper.OutTxTrackerAll(wctx, request(nil, uint64(i), uint64(step), false)) -// require.NoError(t, err) -// require.LessOrEqual(t, len(resp.OutTxTracker), step) -// require.Subset(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// } -// }) -// t.Run("ByKey", func(t *testing.T) { -// step := 2 -// var next []byte -// for i := 0; i < len(msgs); i += step { -// resp, err := keeper.OutTxTrackerAll(wctx, request(next, 0, uint64(step), false)) -// require.NoError(t, err) -// require.LessOrEqual(t, len(resp.OutTxTracker), step) -// require.Subset(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// next = resp.Pagination.NextKey -// } -// }) -// t.Run("Total", func(t *testing.T) { -// resp, err := keeper.OutTxTrackerAll(wctx, request(nil, 0, 0, true)) -// require.NoError(t, err) -// require.Equal(t, len(msgs), int(resp.Pagination.Total)) -// require.ElementsMatch(t, -// nullify.Fill(msgs), -// nullify.Fill(resp.OutTxTracker), -// ) -// }) -// t.Run("InvalidRequest", func(t *testing.T) { -// _, err := keeper.OutTxTrackerAll(wctx, nil) -// require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) -// }) -//} +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestKeeper_OutTxTrackerAllByChain(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTrackerAllByChain(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + }) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 2, + }) + + res, err := k.OutTxTrackerAllByChain(ctx, &types.QueryAllOutTxTrackerByChainRequest{ + Chain: 1, + }) + require.NoError(t, err) + require.Equal(t, 1, len(res.OutTxTracker)) + }) +} + +func TestKeeper_OutTxTrackerAll(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTrackerAll(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + }) + + res, err := k.OutTxTrackerAll(ctx, &types.QueryAllOutTxTrackerRequest{}) + require.NoError(t, err) + require.Equal(t, 1, len(res.OutTxTracker)) + }) +} + +func TestKeeper_OutTxTracker(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTracker(ctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.OutTxTracker(ctx, &types.QueryGetOutTxTrackerRequest{ + ChainID: 1, + Nonce: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if req is not nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + Nonce: 1, + }) + + res, err := k.OutTxTracker(ctx, &types.QueryGetOutTxTrackerRequest{ + ChainID: 1, + Nonce: 1, + }) + require.NoError(t, err) + require.NotNil(t, res) + }) +} diff --git a/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go b/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go new file mode 100644 index 0000000000..f6baf0c625 --- /dev/null +++ b/x/crosschain/keeper/grpc_query_zeta_conversion_rate_test.go @@ -0,0 +1,120 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "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_ConvertGasToZeta(t *testing.T) { + t.Run("should err if chain not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 987, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if median price not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if zrc20 not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(common.Address{}, errors.New("err")) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should err if uniswap2router not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(sample.EthAddress(), nil) + + fungibleMock.On("QueryUniswapV2RouterGetZetaAmountsIn", mock.Anything, mock.Anything, mock.Anything). + Return(big.NewInt(0), errors.New("err")) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if all is set", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("QuerySystemContractGasCoinZRC20", mock.Anything, mock.Anything). + Return(sample.EthAddress(), nil) + + fungibleMock.On("QueryUniswapV2RouterGetZetaAmountsIn", mock.Anything, mock.Anything, mock.Anything). + Return(big.NewInt(5), nil) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: 5, + MedianIndex: 0, + Prices: []uint64{2}, + }) + + res, err := k.ConvertGasToZeta(ctx, &types.QueryConvertGasToZetaRequest{ + ChainId: 5, + GasLimit: "10", + }) + require.NoError(t, err) + require.Equal(t, &types.QueryConvertGasToZetaResponse{ + OutboundGasInZeta: "5", + ProtocolFeeInZeta: types.GetProtocolFee().String(), + // #nosec G701 always positive + ZetaBlockHeight: uint64(ctx.BlockHeight()), + }, res) + }) +} + +func TestKeeper_ProtocolFee(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + res, err := k.ProtocolFee(ctx, nil) + require.NoError(t, err) + require.Equal(t, &types.QueryMessagePassingProtocolFeeResponse{ + FeeInZeta: types.GetProtocolFee().String(), + }, res) +} diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go index dc89a3534f..5ab8eba308 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go @@ -67,7 +67,30 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { require.False(t, found) }) - t.Run("admin add tx tracker", func(t *testing.T) { + t.Run("fail for unsupported chain id", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + tx_hash := "string" + + chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: sample.AccAddress(), + ChainId: chainID + 1, + TxHash: tx_hash, + CoinType: coin.CoinType_Zeta, + Proof: nil, + BlockHash: "", + TxIndex: 0, + }) + require.ErrorIs(t, err, observertypes.ErrSupportedChains) + _, found := k.GetInTxTracker(ctx, chainID, tx_hash) + require.False(t, found) + }) + + t.Run("admin add tx tracker", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) diff --git a/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go b/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go index 24174733b0..010486017d 100644 --- a/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go +++ b/x/crosschain/keeper/msg_server_add_to_outtx_tracker_test.go @@ -15,7 +15,6 @@ import ( func getEthereumChainID() int64 { return 5 // Goerli - } // setEnabledChain sets the chain as enabled in chain params @@ -32,7 +31,7 @@ func setEnabledChain(ctx sdk.Context, zk keepertest.ZetaKeepers, chainID int64) } // setupTssAndNonceToCctx sets tss and nonce to cctx -func setupTssAndNonceToCctx(k *keeper.Keeper, ctx sdk.Context, chainId, nonce int64) { +func setupTssAndNonceToCctx(k *keeper.Keeper, ctx sdk.Context, chainId, nonce int64, status types.CctxStatus) { tssPubKey := "zetapub1addwnpepq28c57cvcs0a2htsem5zxr6qnlvq9mzhmm76z3jncsnzz32rclangr2g35p" k.GetObserverKeeper().SetTSS(ctx, observertypes.TSS{ TssPubkey: tssPubKey, @@ -47,7 +46,7 @@ func setupTssAndNonceToCctx(k *keeper.Keeper, ctx sdk.Context, chainId, nonce in Creator: "any", Index: "0x123", CctxStatus: &types.Status{ - Status: types.CctxStatus_PendingOutbound, + Status: status, }, } k.SetCrossChainTx(ctx, cctx) @@ -70,7 +69,7 @@ func TestMsgServer_AddToOutTxTracker(t *testing.T) { keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) chainID := getEthereumChainID() - setupTssAndNonceToCctx(k, ctx, chainID, 0) + setupTssAndNonceToCctx(k, ctx, chainID, 0, types.CctxStatus_PendingOutbound) setEnabledChain(ctx, zk, chainID) msgServer := keeper.NewMsgServerImpl(*k) @@ -89,6 +88,106 @@ func TestMsgServer_AddToOutTxTracker(t *testing.T) { require.True(t, found) }) + t.Run("should return early if cctx not pending", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + chainID := getEthereumChainID() + setupTssAndNonceToCctx(k, ctx, chainID, 0, types.CctxStatus_OutboundMined) + setEnabledChain(ctx, zk, chainID) + + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.AddToOutTxTracker(ctx, &types.MsgAddToOutTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: sample.Hash().Hex(), + Proof: nil, + BlockHash: "", + TxIndex: 0, + Nonce: 0, + }) + require.NoError(t, err) + require.Equal(t, &types.MsgAddToOutTxTrackerResponse{IsRemoved: true}, res) + _, found := k.GetOutTxTracker(ctx, chainID, 0) + require.False(t, found) + }) + + t.Run("should error for unsupported chain", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + + chainID := getEthereumChainID() + setupTssAndNonceToCctx(k, ctx, chainID, 0, types.CctxStatus_PendingOutbound) + setEnabledChain(ctx, zk, chainID) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.AddToOutTxTracker(ctx, &types.MsgAddToOutTxTracker{ + Creator: admin, + ChainId: chainID + 1, + TxHash: sample.Hash().Hex(), + Proof: nil, + BlockHash: "", + TxIndex: 0, + Nonce: 0, + }) + require.Error(t, err) + }) + + t.Run("should error if no tss", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + + chainID := getEthereumChainID() + setEnabledChain(ctx, zk, chainID) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.AddToOutTxTracker(ctx, &types.MsgAddToOutTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: sample.Hash().Hex(), + Proof: nil, + BlockHash: "", + TxIndex: 0, + Nonce: 0, + }) + require.Error(t, err) + }) + + t.Run("should error if no cctx", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + + chainID := getEthereumChainID() + setEnabledChain(ctx, zk, chainID) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.AddToOutTxTracker(ctx, &types.MsgAddToOutTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: sample.Hash().Hex(), + Proof: nil, + BlockHash: "", + TxIndex: 0, + Nonce: 0, + }) + require.Error(t, err) + }) + t.Run("unable to add tracker admin exceeding maximum allowed length of hashlist without proof", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, @@ -99,7 +198,7 @@ func TestMsgServer_AddToOutTxTracker(t *testing.T) { keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) chainID := getEthereumChainID() - setupTssAndNonceToCctx(k, ctx, chainID, 0) + setupTssAndNonceToCctx(k, ctx, chainID, 0, types.CctxStatus_PendingOutbound) setEnabledChain(ctx, zk, chainID) k.SetOutTxTracker(ctx, types.OutTxTracker{ diff --git a/x/crosschain/keeper/msg_server_gas_price_voter.go b/x/crosschain/keeper/msg_server_gas_price_voter.go index 308f895f59..52532c206f 100644 --- a/x/crosschain/keeper/msg_server_gas_price_voter.go +++ b/x/crosschain/keeper/msg_server_gas_price_voter.go @@ -25,14 +25,11 @@ func (k msgServer) GasPriceVoter(goCtx context.Context, msg *types.MsgGasPriceVo chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { - return nil, observertypes.ErrSupportedChains + return nil, cosmoserrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID : %d ", msg.ChainId)) } if ok := k.zetaObserverKeeper.IsNonTombstonedObserver(ctx, msg.Creator); !ok { return nil, observertypes.ErrNotObserver } - if chain == nil { - return nil, cosmoserrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID : %d ", msg.ChainId)) - } gasPrice, isFound := k.GetGasPrice(ctx, chain.ChainId) if !isFound { diff --git a/x/crosschain/keeper/msg_server_gas_price_voter_test.go b/x/crosschain/keeper/msg_server_gas_price_voter_test.go new file mode 100644 index 0000000000..50c11dbaa9 --- /dev/null +++ b/x/crosschain/keeper/msg_server_gas_price_voter_test.go @@ -0,0 +1,204 @@ +package keeper_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + 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" +) + +func TestMsgServer_GasPriceVoter(t *testing.T) { + t.Run("should error if unsupported chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(nil) + + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + ChainId: 5, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not non tombstoned observer", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + ChainId: 5, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if gas price not found and set gas price in fungible keeper fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainId: 5, + }) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(true) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("SetGasPrice", mock.Anything, mock.Anything, mock.Anything).Return(uint64(0), errors.New("err")) + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + ChainId: 5, + }) + require.Error(t, err) + require.Nil(t, res) + _, found := k.GetGasPrice(ctx, 5) + require.True(t, found) + }) + + t.Run("should not error if gas price not found and set gas price in fungible keeper succeeds", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainId: 5, + }) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(true) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("SetGasPrice", mock.Anything, mock.Anything, mock.Anything).Return(uint64(1), nil) + msgServer := keeper.NewMsgServerImpl(*k) + creator := sample.AccAddress() + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + Creator: creator, + ChainId: 5, + Price: 1, + BlockNumber: 1, + }) + require.NoError(t, err) + require.Empty(t, res) + gp, found := k.GetGasPrice(ctx, 5) + require.True(t, found) + require.Equal(t, types.GasPrice{ + Creator: creator, + Index: "5", + ChainId: 5, + Signers: []string{creator}, + BlockNums: []uint64{1}, + Prices: []uint64{1}, + MedianIndex: 0, + }, gp) + }) + + t.Run("should not error if gas price found and msg.creator in signers", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainId: 5, + }) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(true) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("SetGasPrice", mock.Anything, mock.Anything, mock.Anything).Return(uint64(1), nil) + msgServer := keeper.NewMsgServerImpl(*k) + + creator := sample.AccAddress() + k.SetGasPrice(ctx, types.GasPrice{ + Creator: creator, + ChainId: 5, + Signers: []string{creator}, + BlockNums: []uint64{1}, + Prices: []uint64{1}, + }) + + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + Creator: creator, + ChainId: 5, + BlockNumber: 2, + Price: 2, + }) + require.NoError(t, err) + require.Empty(t, res) + gp, found := k.GetGasPrice(ctx, 5) + require.True(t, found) + require.Equal(t, types.GasPrice{ + Creator: creator, + Index: "", + ChainId: 5, + Signers: []string{creator}, + BlockNums: []uint64{2}, + Prices: []uint64{2}, + MedianIndex: 0, + }, gp) + }) + + t.Run("should not error if gas price found and msg.creator not in signers", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{ + ChainId: 5, + }) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(true) + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("SetGasPrice", mock.Anything, mock.Anything, mock.Anything).Return(uint64(1), nil) + msgServer := keeper.NewMsgServerImpl(*k) + + creator := sample.AccAddress() + k.SetGasPrice(ctx, types.GasPrice{ + Creator: creator, + ChainId: 5, + BlockNums: []uint64{1}, + Prices: []uint64{1}, + }) + + res, err := msgServer.GasPriceVoter(ctx, &types.MsgGasPriceVoter{ + Creator: creator, + ChainId: 5, + BlockNumber: 2, + Price: 2, + }) + require.NoError(t, err) + require.Empty(t, res) + gp, found := k.GetGasPrice(ctx, 5) + require.True(t, found) + require.Equal(t, types.GasPrice{ + Creator: creator, + Index: "", + ChainId: 5, + Signers: []string{creator}, + BlockNums: []uint64{1, 2}, + Prices: []uint64{1, 2}, + MedianIndex: 1, + }, gp) + }) +} diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 7fd1228400..b9fddc9dae 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -41,6 +41,10 @@ func (k msgServer) MigrateTssFunds(goCtx context.Context, msg *types.MsgMigrateT } tssHistory := k.zetaObserverKeeper.GetAllTSS(ctx) + if len(tssHistory) == 0 { + return nil, errorsmod.Wrap(types.ErrCannotMigrateTssFunds, "empty TSS history") + } + sort.SliceStable(tssHistory, func(i, j int) bool { return tssHistory[i].FinalizedZetaHeight < tssHistory[j].FinalizedZetaHeight }) diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go index d4a6c5206e..f13a0065ae 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -6,6 +6,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/gas" @@ -78,7 +79,7 @@ func setupTssMigrationParams( } func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { - t.Run("test gas price multiplier", func(t *testing.T) { + t.Run("test evm chain", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) @@ -106,11 +107,220 @@ func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { multipliedValue, err := gas.MultiplyGasPrice(gp, crosschaintypes.TssMigrationGasMultiplierEVM) require.NoError(t, err) require.Equal(t, multipliedValue.String(), cctx.GetCurrentOutTxParam().OutboundTxGasPrice) + }) + + t.Run("test btc chain", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidBTCChain() + amount := sdkmath.NewUintFromString("10000000000000000000") + indexString, _ := setupTssMigrationParams(zk, k, ctx, *chain, amount, true, true) + gp, found := k.GetMedianGasPriceInUint(ctx, chain.ChainId) + require.True(t, found) + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.NoError(t, err) + hash := crypto.Keccak256Hash([]byte(indexString)) + index := hash.Hex() + cctx, found := k.GetCrossChainTx(ctx, index) + require.True(t, found) + require.Equal(t, gp.MulUint64(2).String(), cctx.GetCurrentOutTxParam().OutboundTxGasPrice) }) } func TestMsgServer_MigrateTssFunds(t *testing.T) { + t.Run("should error if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, false) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if inbound enabled", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(true) + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(false) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, false) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if tss history empty", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(false) + observerMock.On("GetTSS", mock.Anything).Return(sample.Tss(), true) + observerMock.On("GetAllTSS", mock.Anything).Return([]observertypes.TSS{}) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if no new tss generated", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(false) + tss := sample.Tss() + observerMock.On("GetTSS", mock.Anything).Return(tss, true) + observerMock.On("GetAllTSS", mock.Anything).Return([]observertypes.TSS{tss}) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if current tss is the latest", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(false) + tss1 := sample.Tss() + tss1.FinalizedZetaHeight = 2 + tss2 := sample.Tss() + tss2.FinalizedZetaHeight = 1 + observerMock.On("GetTSS", mock.Anything).Return(tss1, true) + observerMock.On("GetAllTSS", mock.Anything).Return([]observertypes.TSS{tss2}) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + + t.Run("should error if pending nonces not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("IsInboundEnabled", mock.Anything).Return(false) + tss1 := sample.Tss() + tss1.FinalizedZetaHeight = 2 + tss2 := sample.Tss() + tss2.FinalizedZetaHeight = 3 + observerMock.On("GetTSS", mock.Anything).Return(tss1, true) + observerMock.On("GetAllTSS", mock.Anything).Return([]observertypes.TSS{tss2}) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observertypes.PendingNonces{}, false) + + msgServer := keeper.NewMsgServerImpl(*k) + chain := getValidEthChain(t) + amount := sdkmath.NewUintFromString("10000000000000000000") + _, err := msgServer.MigrateTssFunds(ctx, &crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + }) + require.Error(t, err) + }) + t.Run("successfully create tss migration cctx", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, diff --git a/x/crosschain/keeper/msg_server_refund_aborted_tx_test.go b/x/crosschain/keeper/msg_server_refund_aborted_tx_test.go index 7d91e71b6c..f5615c8963 100644 --- a/x/crosschain/keeper/msg_server_refund_aborted_tx_test.go +++ b/x/crosschain/keeper/msg_server_refund_aborted_tx_test.go @@ -154,6 +154,70 @@ func TestMsgServer_RefundAbortedCCTX(t *testing.T) { require.True(t, c.CctxStatus.IsAbortRefunded) }) + t.Run("should error if aleady refunded", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + chainID := getValidEthChainID(t) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) + + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + + cctx := sample.CrossChainTx(t, "sample-index") + cctx.CctxStatus.Status = crosschaintypes.CctxStatus_Aborted + cctx.CctxStatus.IsAbortRefunded = true + cctx.InboundTxParams.TxOrigin = cctx.InboundTxParams.Sender + cctx.InboundTxParams.SenderChainId = chainID + cctx.InboundTxParams.CoinType = coin.CoinType_Zeta + cctx.OutboundTxParams = nil + k.SetCrossChainTx(ctx, *cctx) + k.SetZetaAccounting(ctx, crosschaintypes.ZetaAccounting{AbortedZetaAmount: cctx.GetCurrentOutTxParam().Amount}) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + + _, err := msgServer.RefundAbortedCCTX(ctx, &crosschaintypes.MsgRefundAbortedCCTX{ + Creator: admin, + CctxIndex: cctx.Index, + RefundAddress: cctx.InboundTxParams.Sender, + }) + require.Error(t, err) + }) + + t.Run("should error if refund fails", func(t *testing.T) { + k, ctx, sdkk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + chainID := getValidEthChainID(t) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) + + msgServer := keeper.NewMsgServerImpl(*k) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + + cctx := sample.CrossChainTx(t, "sample-index") + cctx.CctxStatus.Status = crosschaintypes.CctxStatus_Aborted + cctx.CctxStatus.IsAbortRefunded = false + cctx.InboundTxParams.TxOrigin = cctx.InboundTxParams.Sender + cctx.InboundTxParams.SenderChainId = chainID + cctx.InboundTxParams.CoinType = coin.CoinType_Cmd + cctx.OutboundTxParams = nil + k.SetCrossChainTx(ctx, *cctx) + k.SetZetaAccounting(ctx, crosschaintypes.ZetaAccounting{AbortedZetaAmount: cctx.GetCurrentOutTxParam().Amount}) + deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper) + + _, err := msgServer.RefundAbortedCCTX(ctx, &crosschaintypes.MsgRefundAbortedCCTX{ + Creator: admin, + CctxIndex: cctx.Index, + RefundAddress: cctx.InboundTxParams.Sender, + }) + require.Error(t, err) + }) + t.Run("successfully refund to optional refund address if provided", func(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, diff --git a/x/crosschain/keeper/msg_server_remove_out_tx_tracker_test.go b/x/crosschain/keeper/msg_server_remove_out_tx_tracker_test.go new file mode 100644 index 0000000000..e3b0a59b44 --- /dev/null +++ b/x/crosschain/keeper/msg_server_remove_out_tx_tracker_test.go @@ -0,0 +1,66 @@ +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" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + "github.com/zeta-chain/zetacore/x/crosschain/keeper" + "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TestMsgServer_RemoveFromOutTxTracker(t *testing.T) { + t.Run("should error if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + Nonce: 1, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, false) + + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.RemoveFromOutTxTracker(ctx, &types.MsgRemoveFromOutTxTracker{ + Creator: admin, + }) + require.Error(t, err) + require.Empty(t, res) + + _, found := k.GetOutTxTracker(ctx, 1, 1) + require.True(t, found) + }) + + t.Run("should remove if authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + k.SetOutTxTracker(ctx, types.OutTxTracker{ + ChainId: 1, + Nonce: 1, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) + + msgServer := keeper.NewMsgServerImpl(*k) + + res, err := msgServer.RemoveFromOutTxTracker(ctx, &types.MsgRemoveFromOutTxTracker{ + Creator: admin, + ChainId: 1, + Nonce: 1, + }) + require.NoError(t, err) + require.Empty(t, res) + + _, found := k.GetOutTxTracker(ctx, 1, 1) + require.False(t, found) + }) +} diff --git a/x/crosschain/keeper/msg_server_update_tss_test.go b/x/crosschain/keeper/msg_server_update_tss_test.go index 0020cb32f8..56bfdc205f 100644 --- a/x/crosschain/keeper/msg_server_update_tss_test.go +++ b/x/crosschain/keeper/msg_server_update_tss_test.go @@ -13,6 +13,42 @@ import ( ) func TestMsgServer_UpdateTssAddress(t *testing.T) { + t.Run("should fail if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, false) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ + Creator: admin, + TssPubkey: "", + }) + require.Error(t, err) + }) + + t.Run("should fail if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupAdmin, true) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, err := msgServer.UpdateTssAddress(ctx, &crosschaintypes.MsgUpdateTssAddress{ + Creator: admin, + TssPubkey: "", + }) + require.Error(t, err) + }) + t.Run("successfully update tss address", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, 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 25d5615056..87ff60e729 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go @@ -2,12 +2,15 @@ package keeper_test import ( "encoding/hex" + "errors" "math/big" + "math/rand" "testing" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" @@ -160,6 +163,91 @@ func TestKeeper_VoteOnObservedInboundTx(t *testing.T) { _, found = zk.ObserverKeeper.GetBallot(ctx, msg2.Digest()) require.False(t, found) }) + + t.Run("should error if vote on inbound ballot fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("VoteOnInboundBallot", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(true, false, errors.New("err")) + msgServer := keeper.NewMsgServerImpl(*k) + to, from := int64(1337), int64(101) + + msg := sample.InboundVote(0, from, to) + res, err := msgServer.VoteOnObservedInboundTx( + ctx, + &msg, + ) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if not finalized", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + validatorList := setObservers(t, k, ctx, zk) + + // add one more voter to make it not finalized + r := rand.New(rand.NewSource(42)) + valAddr := sample.ValAddress(r) + observerSet := append(validatorList, valAddr.String()) + zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ + ObserverList: observerSet, + }) + to, from := int64(1337), int64(101) + supportedChains := zk.ObserverKeeper.GetSupportedChains(ctx) + for _, chain := range supportedChains { + if chains.IsEVMChain(chain.ChainId) { + from = chain.ChainId + } + if chains.IsZetaChain(chain.ChainId) { + to = chain.ChainId + } + } + zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) + + msg := sample.InboundVote(0, from, to) + for _, validatorAddr := range validatorList { + msg.Creator = validatorAddr + _, err := msgServer.VoteOnObservedInboundTx( + ctx, + &msg, + ) + require.NoError(t, err) + } + ballot, _, _ := zk.ObserverKeeper.FindBallot( + ctx, + msg.Digest(), + zk.ObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId), + observertypes.ObservationType_InBoundTx, + ) + require.Equal(t, ballot.BallotStatus, observertypes.BallotStatus_BallotInProgress) + require.Equal(t, ballot.Votes[0], observertypes.VoteType_SuccessObservation) + require.Equal(t, ballot.Votes[1], observertypes.VoteType_NotYetVoted) + _, found := k.GetCrossChainTx(ctx, msg.Digest()) + require.False(t, found) + }) + + t.Run("should err if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("VoteOnInboundBallot", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(true, false, nil) + observerMock.On("GetTSS", mock.Anything).Return(observertypes.TSS{}, false) + msgServer := keeper.NewMsgServerImpl(*k) + to, from := int64(1337), int64(101) + + msg := sample.InboundVote(0, from, to) + res, err := msgServer.VoteOnObservedInboundTx( + ctx, + &msg, + ) + require.Error(t, err) + require.Nil(t, res) + }) } func TestStatus_ChangeStatus(t *testing.T) { diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go index 511e703acd..fa9884f25a 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go @@ -198,7 +198,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { keepertest.MockGetOutBound(observerMock, ctx) // Successfully mock ProcessOutbound - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) _ = keepertest.MockUpdateNonce(observerMock, *senderChain) @@ -257,7 +257,7 @@ func TestKeeper_VoteOnObservedOutboundTx(t *testing.T) { keepertest.MockGetOutBound(observerMock, ctx) // Mock Failed ProcessOutbound - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) observerMock.On("GetChainNonces", mock.Anything, senderChain.ChainName.String()). Return(observertypes.ChainNonces{}, false) diff --git a/x/crosschain/keeper/params.go b/x/crosschain/keeper/params.go deleted file mode 100644 index b81567feb5..0000000000 --- a/x/crosschain/keeper/params.go +++ /dev/null @@ -1,31 +0,0 @@ -package keeper - -import ( - "context" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/zeta-chain/zetacore/x/crosschain/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -// GetParams get all parameters as types.Params -func (k Keeper) GetParams(_ sdk.Context) types.Params { - return types.NewParams() -} - -// SetParams set the params -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramstore.SetParamSet(ctx, ¶ms) -} - -//Queries - -func (k Keeper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") - } - ctx := sdk.UnwrapSDKContext(c) - - return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil -} diff --git a/x/crosschain/keeper/process_inbound.go b/x/crosschain/keeper/process_inbound.go index c45d65bf51..3178ee34b0 100644 --- a/x/crosschain/keeper/process_inbound.go +++ b/x/crosschain/keeper/process_inbound.go @@ -13,14 +13,14 @@ import ( // The internal functions handle the state changes and error handling. func (k Keeper) ProcessInbound(ctx sdk.Context, cctx *types.CrossChainTx) { if chains.IsZetaChain(cctx.GetCurrentOutTxParam().ReceiverChainId) { - k.ProcessZEVMDeposit(ctx, cctx) + k.processZEVMDeposit(ctx, cctx) } else { - k.ProcessCrosschainMsgPassing(ctx, cctx) + k.processCrosschainMsgPassing(ctx, cctx) } } /* -ProcessZEVMDeposit processes the EVM deposit CCTX. A deposit is a cctx which has Zetachain as the receiver chain.It trasnsitions state according to the following rules: +processZEVMDeposit processes the EVM deposit CCTX. A deposit is a cctx which has Zetachain as the receiver chain.It trasnsitions state according to the following rules: - If the deposit is successful, the CCTX status is changed to OutboundMined. - If the deposit returns an internal error i.e if HandleEVMDeposit() returns an error, but isContractReverted is false, the CCTX status is changed to Aborted. - If the deposit is reverted, the function tries to create a revert cctx with status PendingRevert. @@ -30,7 +30,7 @@ Note : Aborted CCTXs are not refunded in this function. The refund is done using We do not return an error from this function , as all changes need to be persisted to the state. Instead we use a temporary context to make changes and then commit the context on for the happy path ,i.e cctx is set to OutboundMined. */ -func (k Keeper) ProcessZEVMDeposit(ctx sdk.Context, cctx *types.CrossChainTx) { +func (k Keeper) processZEVMDeposit(ctx sdk.Context, cctx *types.CrossChainTx) { tmpCtx, commit := ctx.CacheContext() isContractReverted, err := k.HandleEVMDeposit(tmpCtx, cctx) @@ -92,13 +92,13 @@ func (k Keeper) ProcessZEVMDeposit(ctx sdk.Context, cctx *types.CrossChainTx) { } /* -ProcessCrosschainMsgPassing processes the CCTX for crosschain message passing. A crosschain message passing is a cctx which has a non-Zetachain as the receiver chain.It trasnsitions state according to the following rules: +processCrosschainMsgPassing processes the CCTX for crosschain message passing. A crosschain message passing is a cctx which has a non-Zetachain as the receiver chain.It trasnsitions state according to the following rules: - If the crosschain message passing is successful, the CCTX status is changed to PendingOutbound. - If the crosschain message passing returns an error, the CCTX status is changed to Aborted. We do not return an error from this function, as all changes need to be persisted to the state. Instead, we use a temporary context to make changes and then commit the context on for the happy path ,i.e cctx is set to PendingOutbound. */ -func (k Keeper) ProcessCrosschainMsgPassing(ctx sdk.Context, cctx *types.CrossChainTx) { +func (k Keeper) processCrosschainMsgPassing(ctx sdk.Context, cctx *types.CrossChainTx) { tmpCtx, commit := ctx.CacheContext() outboundReceiverChainID := cctx.GetCurrentOutTxParam().ReceiverChainId err := func() error { diff --git a/x/crosschain/keeper/process_inbound_test.go b/x/crosschain/keeper/process_inbound_test.go index 4b53f817de..491e362f78 100644 --- a/x/crosschain/keeper/process_inbound_test.go +++ b/x/crosschain/keeper/process_inbound_test.go @@ -8,6 +8,7 @@ import ( sdkmath "cosmossdk.io/math" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -16,7 +17,7 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestKeeper_ProcessZEVMDeposit(t *testing.T) { +func TestKeeper_ProcessInboundZEVMDeposit(t *testing.T) { t.Run("process zevm deposit successfully", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -31,14 +32,15 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { fungibleMock.On("DepositCoinZeta", mock.Anything, receiver, amount). Return(nil) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := sample.CrossChainTx(t, "test") cctx.CctxStatus = &types.Status{Status: types.CctxStatus_PendingInbound} cctx.GetCurrentOutTxParam().Receiver = receiver.String() + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId cctx.GetInboundTxParams().Amount = sdkmath.NewUintFromBigInt(amount) cctx.InboundTxParams.CoinType = coin.CoinType_Zeta cctx.GetInboundTxParams().SenderChainId = 0 - k.ProcessZEVMDeposit(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_OutboundMined, cctx.CctxStatus.Status) }) @@ -56,14 +58,15 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { fungibleMock.On("DepositCoinZeta", mock.Anything, receiver, amount). Return(fmt.Errorf("deposit error"), false) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := sample.CrossChainTx(t, "test") cctx.CctxStatus = &types.Status{Status: types.CctxStatus_PendingInbound} cctx.GetCurrentOutTxParam().Receiver = receiver.String() + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId cctx.GetInboundTxParams().Amount = sdkmath.NewUintFromBigInt(amount) cctx.InboundTxParams.CoinType = coin.CoinType_Zeta cctx.GetInboundTxParams().SenderChainId = 0 - k.ProcessZEVMDeposit(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, "deposit error", cctx.CctxStatus.StatusMessage) }) @@ -90,9 +93,10 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId). Return(nil) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, "", amount) - k.ProcessZEVMDeposit(ctx, cctx) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("invalid sender chain id %d", cctx.InboundTxParams.SenderChainId), cctx.CctxStatus.StatusMessage) }) @@ -122,9 +126,10 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, asset, senderChain.ChainId). Return(fungibletypes.ForeignCoins{}, false) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - k.ProcessZEVMDeposit(ctx, cctx) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("revert gas limit error: %s", types.ErrForeignCoinNotFound), cctx.CctxStatus.StatusMessage) }) @@ -152,15 +157,53 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock unsuccessful PayGasInERC20AndUpdateCctx observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId). Return(nil).Once() - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - k.ProcessZEVMDeposit(ctx, cctx) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) + require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) + require.Equal(t, fmt.Sprintf("deposit revert message: %s err : %s", errDeposit, observertypes.ErrSupportedChains), cctx.CctxStatus.StatusMessage) + }) + + t.Run("uunable to process zevm deposit HandleEVMDeposit revert fails at PayGasInERC20AndUpdateCctx with gas limit is 0", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + UseObserverMock: true, + }) + + // Setup mock data + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + receiver := sample.EthAddress() + amount := big.NewInt(42) + senderChain := getValidEthChain(t) + asset := "" + + // Setup expected calls + errDeposit := fmt.Errorf("deposit failed") + keepertest.MockRevertForHandleEVMDeposit(fungibleMock, receiver, amount, senderChain.ChainId, errDeposit) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + + // Mock successful GetSupportedChainFromChainID + keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) + + // mock successful GetRevertGasLimit for ERC20 + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 0) + + // mock unsuccessful PayGasInERC20AndUpdateCctx + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId). + Return(nil).Once() + + // call ProcessInbound + cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, fmt.Sprintf("deposit revert message: %s err : %s", errDeposit, observertypes.ErrSupportedChains), cctx.CctxStatus.StatusMessage) }) @@ -188,7 +231,7 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) @@ -197,9 +240,10 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { observerMock.On("GetChainNonces", mock.Anything, senderChain.ChainName.String()). Return(observertypes.ChainNonces{}, false) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - k.ProcessZEVMDeposit(ctx, cctx) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Contains(t, cctx.CctxStatus.StatusMessage, "cannot find receiver chain nonce") }) @@ -227,16 +271,17 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) // mock successful UpdateNonce updatedNonce := keepertest.MockUpdateNonce(observerMock, *senderChain) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) - k.ProcessZEVMDeposit(ctx, cctx) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_PendingRevert, cctx.CctxStatus.Status) require.Equal(t, errDeposit.Error(), cctx.CctxStatus.StatusMessage) require.Equal(t, updatedNonce, cctx.GetCurrentOutTxParam().OutboundTxTssNonce) @@ -265,18 +310,19 @@ func TestKeeper_ProcessZEVMDeposit(t *testing.T) { keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) - // call ProcessZEVMDeposit + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) + cctx.GetCurrentOutTxParam().ReceiverChainId = chains.ZetaPrivnetChain().ChainId cctx.OutboundTxParams = append(cctx.OutboundTxParams, cctx.GetCurrentOutTxParam()) - k.ProcessZEVMDeposit(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Contains(t, cctx.CctxStatus.StatusMessage, fmt.Sprintf("revert outbound error: %s", "cannot revert a revert tx")) }) } -func TestKeeper_ProcessCrosschainMsgPassing(t *testing.T) { +func TestKeeper_ProcessInboundProcessCrosschainMsgPassing(t *testing.T) { t.Run("process crosschain msg passing successfully", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -296,9 +342,9 @@ func TestKeeper_ProcessCrosschainMsgPassing(t *testing.T) { // mock successful UpdateNonce updatedNonce := keepertest.MockUpdateNonce(observerMock, *receiverChain) - // call ProcessCrosschainMsgPassing + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *receiverChain, "", amount) - k.ProcessCrosschainMsgPassing(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_PendingOutbound, cctx.CctxStatus.Status) require.Equal(t, updatedNonce, cctx.GetCurrentOutTxParam().OutboundTxTssNonce) }) @@ -319,9 +365,9 @@ func TestKeeper_ProcessCrosschainMsgPassing(t *testing.T) { observerMock.On("GetSupportedChainFromChainID", mock.Anything, receiverChain.ChainId). Return(nil).Once() - // call ProcessCrosschainMsgPassing + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *receiverChain, "", amount) - k.ProcessCrosschainMsgPassing(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Equal(t, observertypes.ErrSupportedChains.Error(), cctx.CctxStatus.StatusMessage) }) @@ -346,9 +392,9 @@ func TestKeeper_ProcessCrosschainMsgPassing(t *testing.T) { observerMock.On("GetChainNonces", mock.Anything, receiverChain.ChainName.String()). Return(observertypes.ChainNonces{}, false) - // call ProcessCrosschainMsgPassing + // call ProcessInbound cctx := GetERC20Cctx(t, receiver, *receiverChain, "", amount) - k.ProcessCrosschainMsgPassing(ctx, cctx) + k.ProcessInbound(ctx, cctx) require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status) require.Contains(t, cctx.CctxStatus.StatusMessage, "cannot find receiver chain nonce") }) diff --git a/x/crosschain/keeper/process_outbound_test.go b/x/crosschain/keeper/process_outbound_test.go index 23877e14f7..90837f17d8 100644 --- a/x/crosschain/keeper/process_outbound_test.go +++ b/x/crosschain/keeper/process_outbound_test.go @@ -67,7 +67,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { asset := "" // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) @@ -82,7 +82,38 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingRevert) require.Equal(t, types.TxFinalizationStatus_NotFinalized, cctx.GetCurrentOutTxParam().TxFinalizationStatus) require.Equal(t, types.TxFinalizationStatus_Executed, cctx.OutboundTxParams[0].TxFinalizationStatus) + }) + + t.Run("successfully process failed outbound set to pending revert if gas limit is 0", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + UseObserverMock: true, + }) + + // Setup mock data + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + receiver := sample.EthAddress() + amount := big.NewInt(42) + senderChain := getValidEthChain(t) + asset := "" + // mock successful GetRevertGasLimit for ERC20 + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 0) + + // mock successful PayGasAndUpdateCctx + keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) + + // mock successful UpdateNonce + _ = keepertest.MockUpdateNonce(observerMock, *senderChain) + + cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) + cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound + err := k.ProcessFailedOutbound(ctx, cctx, sample.String()) + require.NoError(t, err) + require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_PendingRevert) + require.Equal(t, types.TxFinalizationStatus_NotFinalized, cctx.GetCurrentOutTxParam().TxFinalizationStatus) + require.Equal(t, types.TxFinalizationStatus_Executed, cctx.OutboundTxParams[0].TxFinalizationStatus) }) t.Run("unable to process revert when update nonce fails", func(t *testing.T) { @@ -100,7 +131,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { asset := "" // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) @@ -131,7 +162,7 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) { asset := "" // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId). @@ -201,6 +232,15 @@ func TestKeeper_ProcessOutbound(t *testing.T) { require.Equal(t, cctx.GetCurrentOutTxParam().TxFinalizationStatus, types.TxFinalizationStatus_Executed) }) + t.Run("do not process if cctx invalid", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + cctx := GetERC20Cctx(t, sample.EthAddress(), chains.GoerliChain(), "", big.NewInt(42)) + cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound + cctx.InboundTxParams = nil + err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotInProgress, sample.String()) + require.Error(t, err) + }) + t.Run("do not process outbound on error, no new outbound created", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseFungibleMock: true, @@ -244,12 +284,16 @@ func TestKeeper_ProcessOutbound(t *testing.T) { cctx := GetERC20Cctx(t, receiver, *senderChain, asset, amount) cctx.OutboundTxParams = append(cctx.OutboundTxParams, sample.OutboundTxParams(sample.Rand())) + cctx.OutboundTxParams[1].ReceiverChainId = 5 + cctx.OutboundTxParams[1].OutboundTxBallotIndex = "" + cctx.OutboundTxParams[1].OutboundTxHash = "" + cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) err := k.ProcessOutbound(ctx, cctx, observertypes.BallotStatus_BallotFinalized_FailureObservation, sample.String()) - require.ErrorContains(t, err, "cannot revert a revert") + require.Error(t, err) }) t.Run("successfully revert a outbound and create a new revert tx", func(t *testing.T) { @@ -270,7 +314,7 @@ func TestKeeper_ProcessOutbound(t *testing.T) { cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound oldOutTxParamsLen := len(cctx.OutboundTxParams) // mock successful GetRevertGasLimit for ERC20 - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain) + keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, *senderChain, 100) // mock successful PayGasAndUpdateCctx keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, *senderChain, asset) diff --git a/x/crosschain/keeper/refund_test.go b/x/crosschain/keeper/refund_test.go index b1b893f71e..09732bd23a 100644 --- a/x/crosschain/keeper/refund_test.go +++ b/x/crosschain/keeper/refund_test.go @@ -1,11 +1,14 @@ package keeper_test import ( + "errors" "fmt" "testing" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/pkg/coin" @@ -43,6 +46,69 @@ func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(42), balance.Uint64()) }) + + t.Run("should error if zrc20 address empty", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + fungibleMock.On("GetGasCoinForForeignCoin", mock.Anything, mock.Anything).Return(fungibletypes.ForeignCoins{ + Zrc20ContractAddress: "0x", + }, true) + + err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_Gas, + SenderChainId: chainID, + Sender: sender.String(), + TxOrigin: sender.String(), + Amount: math.NewUint(20), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + + t.Run("should error if deposit zrc20 fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + fungibleMock.On("GetGasCoinForForeignCoin", mock.Anything, mock.Anything).Return(fungibletypes.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().Hex(), + }, true) + + fungibleMock.On("DepositZRC20", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("")) + + err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_Gas, + SenderChainId: chainID, + Sender: sender.String(), + TxOrigin: sender.String(), + Amount: math.NewUint(20), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + t.Run("should refund inbound amount zrc20 gas on zeta chain", func(t *testing.T) { k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) @@ -143,6 +209,56 @@ func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) { fmt.Println(coin.Amount.String()) require.Equal(t, "42", coin.Amount.String()) }) + + t.Run("should error if non evm chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + sender := sample.EthAddress() + + err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_Gas, + SenderChainId: 101, + Sender: sender.String(), + TxOrigin: sender.String(), + Amount: math.NewUint(20), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + + t.Run("should error if deposit coin zeta fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("DepositCoinZeta", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("err")) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_Gas, + SenderChainId: chainID, + Sender: sender.String(), + TxOrigin: sender.String(), + Amount: math.NewUint(20), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + t.Run("should refund inbound amount on zeta chain if outbound is not present", func(t *testing.T) { k, ctx, sdkk, _ := keepertest.CrosschainKeeper(t) k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) @@ -249,6 +365,69 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { require.Equal(t, uint64(84), balance.Uint64()) }) + t.Run("should error if zrc20 address empty", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, mock.Anything, mock.Anything).Return(fungibletypes.ForeignCoins{ + Zrc20ContractAddress: "0x", + }, true) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + asset := sample.EthAddress().String() + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + Amount: math.NewUint(42), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + + t.Run("should error if deposit zrc20 fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName) + asset := sample.EthAddress().String() + sender := sample.EthAddress() + chainID := getValidEthChainID(t) + + fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, mock.Anything, mock.Anything).Return(fungibletypes.ForeignCoins{ + Zrc20ContractAddress: sample.EthAddress().Hex(), + }, true) + + fungibleMock.On("DepositZRC20", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("")) + + err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{ + InboundTxParams: &types.InboundTxParams{ + CoinType: coin.CoinType_ERC20, + SenderChainId: chainID, + Sender: sender.String(), + Asset: asset, + Amount: math.NewUint(42), + }, + OutboundTxParams: []*types.OutboundTxParams{{ + Amount: math.NewUint(42), + }}, + }, + sender, + ) + require.Error(t, err) + }) + t.Run("should fail with invalid cctx", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) @@ -316,3 +495,12 @@ func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) { require.ErrorContains(t, err, "zrc not found") }) } + +func TestKeeper_RefundAbortedAmountOnZetaChain_FailsForUnsupportedCoinType(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + + cctx := sample.CrossChainTx(t, "index") + cctx.InboundTxParams.CoinType = coin.CoinType_Cmd + err := k.RefundAbortedAmountOnZetaChain(ctx, *cctx, common.Address{}) + require.ErrorContains(t, err, "unsupported coin type for refund on ZetaChain") +} diff --git a/x/crosschain/keeper/verify_proof_test.go b/x/crosschain/keeper/verify_proof_test.go new file mode 100644 index 0000000000..62d47773b9 --- /dev/null +++ b/x/crosschain/keeper/verify_proof_test.go @@ -0,0 +1,393 @@ +package keeper_test + +import ( + "errors" + "math/big" + "testing" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/coin" + "github.com/zeta-chain/zetacore/pkg/proofs" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_VerifyProof(t *testing.T) { + t.Run("should error if crosschain flags not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{}, false) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 5, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if BlockHeaderVerificationFlags nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: nil, + }, true) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 5, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if verification not enabled for btc chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: &observertypes.BlockHeaderVerificationFlags{ + IsBtcTypeChainEnabled: false, + }, + }, true) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 18444, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if verification not enabled for evm chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: &observertypes.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + }, + }, true) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 5, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if block header-based verification not supported", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: &observertypes.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: false, + }, + }, true) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 101, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if blockhash invalid", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: &observertypes.BlockHeaderVerificationFlags{ + IsBtcTypeChainEnabled: true, + }, + }, true) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 18444, "invalid", 1) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if block header not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetCrosschainFlags", mock.Anything).Return(observertypes.CrosschainFlags{ + BlockHeaderVerificationFlags: &observertypes.BlockHeaderVerificationFlags{ + IsEthTypeChainEnabled: true, + }, + }, true) + + observerMock.On("GetBlockHeader", mock.Anything, mock.Anything).Return(proofs.BlockHeader{}, false) + + res, err := k.VerifyProof(ctx, &proofs.Proof{}, 5, sample.Hash().String(), 1) + require.Error(t, err) + require.Nil(t, res) + }) + // TODO: // https://github.com/zeta-chain/node/issues/1875 add more tests +} + +func TestKeeper_VerifyEVMInTxBody(t *testing.T) { + to := sample.EthAddress() + tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + ChainID: big.NewInt(5), + Nonce: 1, + GasTipCap: nil, + GasFeeCap: nil, + Gas: 21000, + To: &to, + Value: big.NewInt(5), + Data: nil, + }) + t.Run("should error if msg tx hash not correct", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: "0x0", + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error if msg chain id not correct", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: 1, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error if not supported coin type", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Cmd, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error for cointype_zeta if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Zeta, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error for cointype_zeta if tx.to wrong", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ + ConnectorContractAddress: sample.EthAddress().Hex(), + }, true) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Zeta, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should not error for cointype_zeta", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ + ConnectorContractAddress: to.Hex(), + }, true) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Zeta, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.NoError(t, err) + }) + + t.Run("should error for cointype_erc20 if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_ERC20, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error for cointype_erc20 if tx.to wrong", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ + Erc20CustodyContractAddress: sample.EthAddress().Hex(), + }, true) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_ERC20, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should not error for cointype_erc20", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ + Erc20CustodyContractAddress: to.Hex(), + }, true) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_ERC20, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.NoError(t, err) + }) + + t.Run("should error for cointype_gas if tss address not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{}, errors.New("err")) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Gas, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error for cointype_gas if tss eth address is empty", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ + Eth: "0x", + }, nil) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Gas, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should error for cointype_gas if tss eth address is wrong", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ + Eth: sample.EthAddress().Hex(), + }, nil) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Gas, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.Error(t, err) + }) + + t.Run("should not error for cointype_gas", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ + Eth: to.Hex(), + }, nil) + + txBytes, err := tx.MarshalBinary() + require.NoError(t, err) + msg := &types.MsgAddToInTxTracker{ + TxHash: tx.Hash().Hex(), + ChainId: tx.ChainId().Int64(), + CoinType: coin.CoinType_Gas, + } + + err = k.VerifyEVMInTxBody(ctx, msg, txBytes) + require.NoError(t, err) + }) +} diff --git a/x/crosschain/keeper/zeta_accounting_test.go b/x/crosschain/keeper/zeta_accounting_test.go index 8802fe7666..7a3eee1223 100644 --- a/x/crosschain/keeper/zeta_accounting_test.go +++ b/x/crosschain/keeper/zeta_accounting_test.go @@ -11,7 +11,6 @@ import ( ) func TestKeeper_AddZetaAccounting(t *testing.T) { - t.Run("should add aborted zeta amount", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) originalAmount := sdkmath.NewUint(rand.Uint64()) @@ -28,6 +27,18 @@ func TestKeeper_AddZetaAccounting(t *testing.T) { require.Equal(t, originalAmount.Add(addAmount), val.AbortedZetaAmount) }) + t.Run("should add aborted zeta amount if accounting not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeper(t) + originalAmount := sdkmath.NewUint(0) + _, found := k.GetZetaAccounting(ctx) + require.False(t, found) + addAmount := sdkmath.NewUint(rand.Uint64()) + k.AddZetaAbortedAmount(ctx, addAmount) + val, found := k.GetZetaAccounting(ctx) + require.True(t, found) + require.Equal(t, originalAmount.Add(addAmount), val.AbortedZetaAmount) + }) + t.Run("cant find aborted amount", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeper(t) val, found := k.GetZetaAccounting(ctx) diff --git a/x/crosschain/module.go b/x/crosschain/module.go index 45d23053da..4fe79325d6 100644 --- a/x/crosschain/module.go +++ b/x/crosschain/module.go @@ -76,12 +76,7 @@ func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - - err := types.RegisterClientCtx(clientCtx) - if err != nil { - fmt.Println("RegisterQueryHandlerClient err: %w", err) - } - err = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) if err != nil { fmt.Println("RegisterQueryHandlerClient err: %w", err) } diff --git a/x/crosschain/module_simulation.go b/x/crosschain/module_simulation.go index ef8ecee194..e198a69462 100644 --- a/x/crosschain/module_simulation.go +++ b/x/crosschain/module_simulation.go @@ -15,9 +15,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { for i, acc := range simState.Accounts { accs[i] = acc.Address.String() } - crosschainGenesis := types.GenesisState{ - Params: types.DefaultParams(), - } + crosschainGenesis := types.GenesisState{} simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&crosschainGenesis) } diff --git a/x/crosschain/types/client_ctx.go b/x/crosschain/types/client_ctx.go deleted file mode 100644 index b4622e1a61..0000000000 --- a/x/crosschain/types/client_ctx.go +++ /dev/null @@ -1,14 +0,0 @@ -package types - -import ( - "github.com/cosmos/cosmos-sdk/client" -) - -var ( - ClientCtx client.Context -) - -func RegisterClientCtx(clientCtx client.Context) error { - ClientCtx = clientCtx - return nil -} diff --git a/x/crosschain/types/genesis.pb.go b/x/crosschain/types/genesis.pb.go index 43a21227fb..c6358ad693 100644 --- a/x/crosschain/types/genesis.pb.go +++ b/x/crosschain/types/genesis.pb.go @@ -26,15 +26,14 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the metacore module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - OutTxTrackerList []OutTxTracker `protobuf:"bytes,2,rep,name=outTxTrackerList,proto3" json:"outTxTrackerList"` - GasPriceList []*GasPrice `protobuf:"bytes,5,rep,name=gasPriceList,proto3" json:"gasPriceList,omitempty"` - CrossChainTxs []*CrossChainTx `protobuf:"bytes,7,rep,name=CrossChainTxs,proto3" json:"CrossChainTxs,omitempty"` - LastBlockHeightList []*LastBlockHeight `protobuf:"bytes,8,rep,name=lastBlockHeightList,proto3" json:"lastBlockHeightList,omitempty"` - 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"` + OutTxTrackerList []OutTxTracker `protobuf:"bytes,1,rep,name=outTxTrackerList,proto3" json:"outTxTrackerList"` + GasPriceList []*GasPrice `protobuf:"bytes,2,rep,name=gasPriceList,proto3" json:"gasPriceList,omitempty"` + CrossChainTxs []*CrossChainTx `protobuf:"bytes,3,rep,name=CrossChainTxs,proto3" json:"CrossChainTxs,omitempty"` + LastBlockHeightList []*LastBlockHeight `protobuf:"bytes,4,rep,name=lastBlockHeightList,proto3" json:"lastBlockHeightList,omitempty"` + InTxHashToCctxList []InTxHashToCctx `protobuf:"bytes,5,rep,name=inTxHashToCctxList,proto3" json:"inTxHashToCctxList"` + InTxTrackerList []InTxTracker `protobuf:"bytes,6,rep,name=in_tx_tracker_list,json=inTxTrackerList,proto3" json:"in_tx_tracker_list"` + ZetaAccounting ZetaAccounting `protobuf:"bytes,7,opt,name=zeta_accounting,json=zetaAccounting,proto3" json:"zeta_accounting"` + FinalizedInbounds []string `protobuf:"bytes,8,rep,name=FinalizedInbounds,proto3" json:"FinalizedInbounds,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -70,13 +69,6 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo -func (m *GenesisState) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - func (m *GenesisState) GetOutTxTrackerList() []OutTxTracker { if m != nil { return m.OutTxTrackerList @@ -140,39 +132,37 @@ func init() { func init() { proto.RegisterFile("crosschain/genesis.proto", fileDescriptor_dd51403692d571f4) } var fileDescriptor_dd51403692d571f4 = []byte{ - // 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, + // 465 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x1b, 0xba, 0x0d, 0x30, 0x83, 0x81, 0xe1, 0x10, 0x55, 0x22, 0xab, 0xc6, 0x81, 0x09, + 0x58, 0x22, 0xe0, 0x13, 0xd0, 0x4a, 0x6c, 0xd3, 0x26, 0x01, 0xa1, 0xa7, 0x89, 0xc9, 0x38, 0x9e, + 0x95, 0x58, 0x0b, 0x76, 0x15, 0xbf, 0x48, 0xa1, 0x9f, 0x82, 0x6f, 0xc4, 0x75, 0xc7, 0x1d, 0x39, + 0x21, 0xd4, 0x7e, 0x11, 0x64, 0x27, 0x0c, 0x47, 0x99, 0xd6, 0xde, 0x9e, 0xfc, 0xde, 0xff, 0xf7, + 0x7f, 0xf9, 0x3b, 0x46, 0x3e, 0x2b, 0x94, 0xd6, 0x2c, 0xa3, 0x42, 0x46, 0x29, 0x97, 0x5c, 0x0b, + 0x1d, 0x4e, 0x0b, 0x05, 0x0a, 0x3f, 0x9d, 0x71, 0xa0, 0xb6, 0x11, 0xda, 0x4a, 0x15, 0x3c, 0xfc, + 0x3f, 0x3c, 0xd8, 0x76, 0x84, 0xb6, 0x24, 0xb6, 0x26, 0x50, 0xd5, 0xfa, 0xc1, 0xc0, 0x25, 0x53, + 0x4d, 0xa6, 0x85, 0x60, 0xbc, 0xe9, 0x3d, 0x73, 0x7a, 0x56, 0x43, 0x32, 0xaa, 0x33, 0x02, 0x8a, + 0x30, 0x76, 0x05, 0x08, 0x3a, 0x43, 0x50, 0x50, 0x76, 0xce, 0x8b, 0xa6, 0xbf, 0xe3, 0xf4, 0x73, + 0xaa, 0x81, 0x24, 0xb9, 0x62, 0xe7, 0x24, 0xe3, 0x22, 0xcd, 0xa0, 0x99, 0x71, 0xb7, 0x54, 0x25, + 0x74, 0x21, 0x4f, 0x52, 0x95, 0x2a, 0x5b, 0x46, 0xa6, 0xaa, 0x4f, 0x77, 0x7e, 0xae, 0xa3, 0xcd, + 0xfd, 0x3a, 0x8d, 0xcf, 0x40, 0x81, 0xe3, 0x53, 0xf4, 0x50, 0x95, 0x30, 0xa9, 0x26, 0xb5, 0xf8, + 0x58, 0x68, 0xf0, 0xbd, 0x61, 0x7f, 0xf7, 0xde, 0x9b, 0x97, 0xe1, 0x8d, 0x39, 0x85, 0x1f, 0x1c, + 0xd9, 0x68, 0xed, 0xe2, 0xf7, 0x76, 0x2f, 0xee, 0xa0, 0xf0, 0x11, 0xda, 0x4c, 0xa9, 0xfe, 0x68, + 0x12, 0xb2, 0xe8, 0x5b, 0x16, 0xfd, 0x7c, 0x09, 0x7a, 0xbf, 0x91, 0xc4, 0x2d, 0x31, 0xfe, 0x84, + 0xee, 0x8f, 0xcd, 0xd0, 0xd8, 0x0c, 0x4d, 0x2a, 0xed, 0xf7, 0x57, 0x5a, 0xd4, 0xd5, 0xc4, 0x6d, + 0x02, 0xfe, 0x8a, 0x1e, 0x9b, 0x84, 0x47, 0x26, 0xe0, 0x03, 0x9b, 0xaf, 0x5d, 0x73, 0xcd, 0x82, + 0xc3, 0x25, 0xe0, 0xe3, 0xb6, 0x32, 0xbe, 0x0e, 0x85, 0x19, 0xc2, 0xc6, 0xea, 0x80, 0xea, 0x6c, + 0xa2, 0xc6, 0x0c, 0x2a, 0x6b, 0xb0, 0x6e, 0x0d, 0xf6, 0x96, 0x18, 0x1c, 0xb6, 0x84, 0x4d, 0xc8, + 0xd7, 0xe0, 0xf0, 0xa9, 0x31, 0x71, 0xfe, 0x01, 0x92, 0x1b, 0x93, 0x0d, 0x6b, 0xf2, 0x62, 0x05, + 0x93, 0xf6, 0x35, 0x6e, 0x09, 0xd9, 0xbe, 0xc5, 0x2f, 0x68, 0xcb, 0x28, 0x09, 0x65, 0x4c, 0x95, + 0x12, 0x84, 0x4c, 0xfd, 0xdb, 0x43, 0x6f, 0x85, 0x0f, 0x38, 0xe1, 0x40, 0xdf, 0x5d, 0x89, 0x1a, + 0xfc, 0x83, 0x59, 0xeb, 0x14, 0xbf, 0x42, 0x8f, 0xde, 0x0b, 0x49, 0x73, 0x31, 0xe3, 0x67, 0x87, + 0x32, 0x51, 0xa5, 0x3c, 0xd3, 0xfe, 0x9d, 0x61, 0x7f, 0xf7, 0x6e, 0xdc, 0x6d, 0x8c, 0x8e, 0x2e, + 0xe6, 0x81, 0x77, 0x39, 0x0f, 0xbc, 0x3f, 0xf3, 0xc0, 0xfb, 0xb1, 0x08, 0x7a, 0x97, 0x8b, 0xa0, + 0xf7, 0x6b, 0x11, 0xf4, 0x4e, 0x5e, 0xa7, 0x02, 0xb2, 0x32, 0x09, 0x99, 0xfa, 0x16, 0x19, 0x8b, + 0xbd, 0xfa, 0x75, 0xfc, 0xdb, 0x2b, 0xaa, 0x22, 0xe7, 0xcd, 0xc0, 0xf7, 0x29, 0xd7, 0xc9, 0x86, + 0x7d, 0x15, 0x6f, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xe1, 0x07, 0xea, 0x2d, 0x04, 0x00, + 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -201,9 +191,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.FinalizedInbounds[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.FinalizedInbounds[iNdEx]))) i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x82 + dAtA[i] = 0x42 } } { @@ -215,7 +203,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x62 + dAtA[i] = 0x3a if len(m.InTxTrackerList) > 0 { for iNdEx := len(m.InTxTrackerList) - 1; iNdEx >= 0; iNdEx-- { { @@ -227,7 +215,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x32 } } if len(m.InTxHashToCctxList) > 0 { @@ -241,7 +229,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x2a } } if len(m.LastBlockHeightList) > 0 { @@ -255,7 +243,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x42 + dAtA[i] = 0x22 } } if len(m.CrossChainTxs) > 0 { @@ -269,7 +257,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x1a } } if len(m.GasPriceList) > 0 { @@ -283,7 +271,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x12 } } if len(m.OutTxTrackerList) > 0 { @@ -297,19 +285,9 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0xa } } - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -330,8 +308,6 @@ func (m *GenesisState) Size() (n int) { } var l int _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) if len(m.OutTxTrackerList) > 0 { for _, e := range m.OutTxTrackerList { l = e.Size() @@ -373,7 +349,7 @@ func (m *GenesisState) Size() (n int) { if len(m.FinalizedInbounds) > 0 { for _, s := range m.FinalizedInbounds { l = len(s) - n += 2 + l + sovGenesis(uint64(l)) + n += 1 + l + sovGenesis(uint64(l)) } } return n @@ -415,39 +391,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field OutTxTrackerList", wireType) } @@ -481,7 +424,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field GasPriceList", wireType) } @@ -515,7 +458,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CrossChainTxs", wireType) } @@ -549,7 +492,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LastBlockHeightList", wireType) } @@ -583,7 +526,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 9: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field InTxHashToCctxList", wireType) } @@ -617,7 +560,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 11: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field InTxTrackerList", wireType) } @@ -651,7 +594,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ZetaAccounting", wireType) } @@ -684,7 +627,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 16: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field FinalizedInbounds", wireType) } diff --git a/x/crosschain/types/genesis_test.go b/x/crosschain/types/genesis_test.go index 2b8b5eb80f..d84d811bd9 100644 --- a/x/crosschain/types/genesis_test.go +++ b/x/crosschain/types/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -47,6 +48,11 @@ func TestGenesisState_Validate(t *testing.T) { InTxHash: "1", }, }, + GasPriceList: []*types.GasPrice{ + sample.GasPrice(t, "0"), + sample.GasPrice(t, "1"), + sample.GasPrice(t, "2"), + }, }, valid: true, }, @@ -78,6 +84,20 @@ func TestGenesisState_Validate(t *testing.T) { }, valid: false, }, + { + desc: "duplicated gasPriceList", + genState: &types.GenesisState{ + GasPriceList: []*types.GasPrice{ + { + Index: "1", + }, + { + Index: "1", + }, + }, + }, + valid: false, + }, } { t.Run(tc.desc, func(t *testing.T) { err := tc.genState.Validate() diff --git a/x/crosschain/types/params.go b/x/crosschain/types/params.go deleted file mode 100644 index 7dda7b56d5..0000000000 --- a/x/crosschain/types/params.go +++ /dev/null @@ -1,44 +0,0 @@ -package types - -import ( - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "gopkg.in/yaml.v2" -) - -var _ paramtypes.ParamSet = (*Params)(nil) - -// ParamKeyTable the param key table for launch module -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} - -// NewParams creates a new Params instance -func NewParams() Params { - return Params{ - Enabled: true, - } -} - -// DefaultParams returns a default set of parameters -func DefaultParams() Params { - return NewParams() -} - -// ParamSetPairs get the params.ParamSet -func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{} -} - -// Validate validates the set of params -func (p Params) Validate() error { - return nil -} - -// String implements the Stringer interface. -func (p Params) String() string { - out, err := yaml.Marshal(p) - if err != nil { - return "" - } - return string(out) -} diff --git a/x/crosschain/types/params.pb.go b/x/crosschain/types/params.pb.go deleted file mode 100644 index ad3305a765..0000000000 --- a/x/crosschain/types/params.pb.go +++ /dev/null @@ -1,307 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: crosschain/params.proto - -package types - -import ( - fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/gogo/protobuf/proto" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// Params defines the parameters for the module. -type Params struct { - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` -} - -func (m *Params) Reset() { *m = Params{} } -func (*Params) ProtoMessage() {} -func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_cd6915e32c251e53, []int{0} -} -func (m *Params) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Params.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Params) XXX_Merge(src proto.Message) { - xxx_messageInfo_Params.Merge(m, src) -} -func (m *Params) XXX_Size() int { - return m.Size() -} -func (m *Params) XXX_DiscardUnknown() { - xxx_messageInfo_Params.DiscardUnknown(m) -} - -var xxx_messageInfo_Params proto.InternalMessageInfo - -func (m *Params) GetEnabled() bool { - if m != nil { - return m.Enabled - } - return false -} - -func init() { - proto.RegisterType((*Params)(nil), "zetachain.zetacore.crosschain.Params") -} - -func init() { proto.RegisterFile("crosschain/params.proto", fileDescriptor_cd6915e32c251e53) } - -var fileDescriptor_cd6915e32c251e53 = []byte{ - // 175 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0x2e, 0xca, 0x2f, - 0x2e, 0x4e, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, - 0xca, 0x2f, 0xc9, 0x17, 0x92, 0xad, 0x4a, 0x2d, 0x49, 0x04, 0x8b, 0xeb, 0x81, 0x59, 0xf9, 0x45, - 0xa9, 0x7a, 0x08, 0xb5, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0x95, 0xfa, 0x20, 0x16, 0x44, - 0x93, 0x92, 0x06, 0x17, 0x5b, 0x00, 0xd8, 0x10, 0x21, 0x09, 0x2e, 0xf6, 0xd4, 0xbc, 0xc4, 0xa4, - 0x9c, 0xd4, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x18, 0xd7, 0x8a, 0x65, 0xc6, 0x02, - 0x79, 0x06, 0x27, 0xef, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, - 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4c, - 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x07, 0xd9, 0xac, 0x0b, 0x71, 0x1c, - 0xcc, 0x11, 0xfa, 0x15, 0xfa, 0x48, 0x4e, 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0xdb, - 0x6e, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x96, 0x4e, 0x4b, 0x16, 0xcd, 0x00, 0x00, 0x00, -} - -func (m *Params) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Params) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Enabled { - i-- - if m.Enabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintParams(dAtA []byte, offset int, v uint64) int { - offset -= sovParams(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Params) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Enabled { - n += 2 - } - return n -} - -func sovParams(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozParams(x uint64) (n int) { - return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Params) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Enabled = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipParams(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthParams - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipParams(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthParams - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupParams - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthParams - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/crosschain/types/query.pb.go b/x/crosschain/types/query.pb.go index 7273180766..af554543a3 100644 --- a/x/crosschain/types/query.pb.go +++ b/x/crosschain/types/query.pb.go @@ -111,89 +111,6 @@ func (m *QueryZetaAccountingResponse) GetAbortedZetaAmount() string { return "" } -// QueryParamsRequest is request type for the Query/Params RPC method. -type QueryParamsRequest struct { -} - -func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } -func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryParamsRequest) ProtoMessage() {} -func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{2} -} -func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsRequest.Merge(m, src) -} -func (m *QueryParamsRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo - -// QueryParamsResponse is response type for the Query/Params RPC method. -type QueryParamsResponse struct { - // params holds all the parameters of this module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` -} - -func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } -func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryParamsResponse) ProtoMessage() {} -func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{3} -} -func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryParamsResponse.Merge(m, src) -} -func (m *QueryParamsResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryParamsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo - -func (m *QueryParamsResponse) GetParams() Params { - if m != nil { - return m.Params - } - return Params{} -} - type QueryGetOutTxTrackerRequest struct { ChainID int64 `protobuf:"varint,1,opt,name=chainID,proto3" json:"chainID,omitempty"` Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"` @@ -203,7 +120,7 @@ func (m *QueryGetOutTxTrackerRequest) Reset() { *m = QueryGetOutTxTracke func (m *QueryGetOutTxTrackerRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetOutTxTrackerRequest) ProtoMessage() {} func (*QueryGetOutTxTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{4} + return fileDescriptor_65a992045e92a606, []int{2} } func (m *QueryGetOutTxTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -254,7 +171,7 @@ func (m *QueryGetOutTxTrackerResponse) Reset() { *m = QueryGetOutTxTrack func (m *QueryGetOutTxTrackerResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetOutTxTrackerResponse) ProtoMessage() {} func (*QueryGetOutTxTrackerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{5} + return fileDescriptor_65a992045e92a606, []int{3} } func (m *QueryGetOutTxTrackerResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -298,7 +215,7 @@ func (m *QueryAllOutTxTrackerRequest) Reset() { *m = QueryAllOutTxTracke func (m *QueryAllOutTxTrackerRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerRequest) ProtoMessage() {} func (*QueryAllOutTxTrackerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{6} + return fileDescriptor_65a992045e92a606, []int{4} } func (m *QueryAllOutTxTrackerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -343,7 +260,7 @@ func (m *QueryAllOutTxTrackerResponse) Reset() { *m = QueryAllOutTxTrack func (m *QueryAllOutTxTrackerResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerResponse) ProtoMessage() {} func (*QueryAllOutTxTrackerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{7} + return fileDescriptor_65a992045e92a606, []int{5} } func (m *QueryAllOutTxTrackerResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -395,7 +312,7 @@ func (m *QueryAllOutTxTrackerByChainRequest) Reset() { *m = QueryAllOutT func (m *QueryAllOutTxTrackerByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerByChainRequest) ProtoMessage() {} func (*QueryAllOutTxTrackerByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{8} + return fileDescriptor_65a992045e92a606, []int{6} } func (m *QueryAllOutTxTrackerByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -447,7 +364,7 @@ func (m *QueryAllOutTxTrackerByChainResponse) Reset() { *m = QueryAllOut func (m *QueryAllOutTxTrackerByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllOutTxTrackerByChainResponse) ProtoMessage() {} func (*QueryAllOutTxTrackerByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{9} + return fileDescriptor_65a992045e92a606, []int{7} } func (m *QueryAllOutTxTrackerByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -499,7 +416,7 @@ func (m *QueryAllInTxTrackerByChainRequest) Reset() { *m = QueryAllInTxT func (m *QueryAllInTxTrackerByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackerByChainRequest) ProtoMessage() {} func (*QueryAllInTxTrackerByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{10} + return fileDescriptor_65a992045e92a606, []int{8} } func (m *QueryAllInTxTrackerByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -551,7 +468,7 @@ func (m *QueryAllInTxTrackerByChainResponse) Reset() { *m = QueryAllInTx func (m *QueryAllInTxTrackerByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackerByChainResponse) ProtoMessage() {} func (*QueryAllInTxTrackerByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{11} + return fileDescriptor_65a992045e92a606, []int{9} } func (m *QueryAllInTxTrackerByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -602,7 +519,7 @@ func (m *QueryAllInTxTrackersRequest) Reset() { *m = QueryAllInTxTracker func (m *QueryAllInTxTrackersRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackersRequest) ProtoMessage() {} func (*QueryAllInTxTrackersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{12} + return fileDescriptor_65a992045e92a606, []int{10} } func (m *QueryAllInTxTrackersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -647,7 +564,7 @@ func (m *QueryAllInTxTrackersResponse) Reset() { *m = QueryAllInTxTracke func (m *QueryAllInTxTrackersResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxTrackersResponse) ProtoMessage() {} func (*QueryAllInTxTrackersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{13} + return fileDescriptor_65a992045e92a606, []int{11} } func (m *QueryAllInTxTrackersResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -698,7 +615,7 @@ func (m *QueryGetInTxHashToCctxRequest) Reset() { *m = QueryGetInTxHashT func (m *QueryGetInTxHashToCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetInTxHashToCctxRequest) ProtoMessage() {} func (*QueryGetInTxHashToCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{14} + return fileDescriptor_65a992045e92a606, []int{12} } func (m *QueryGetInTxHashToCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -742,7 +659,7 @@ func (m *QueryGetInTxHashToCctxResponse) Reset() { *m = QueryGetInTxHash func (m *QueryGetInTxHashToCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetInTxHashToCctxResponse) ProtoMessage() {} func (*QueryGetInTxHashToCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{15} + return fileDescriptor_65a992045e92a606, []int{13} } func (m *QueryGetInTxHashToCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -786,7 +703,7 @@ func (m *QueryInTxHashToCctxDataRequest) Reset() { *m = QueryInTxHashToC func (m *QueryInTxHashToCctxDataRequest) String() string { return proto.CompactTextString(m) } func (*QueryInTxHashToCctxDataRequest) ProtoMessage() {} func (*QueryInTxHashToCctxDataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{16} + return fileDescriptor_65a992045e92a606, []int{14} } func (m *QueryInTxHashToCctxDataRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -830,7 +747,7 @@ func (m *QueryInTxHashToCctxDataResponse) Reset() { *m = QueryInTxHashTo func (m *QueryInTxHashToCctxDataResponse) String() string { return proto.CompactTextString(m) } func (*QueryInTxHashToCctxDataResponse) ProtoMessage() {} func (*QueryInTxHashToCctxDataResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{17} + return fileDescriptor_65a992045e92a606, []int{15} } func (m *QueryInTxHashToCctxDataResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -874,7 +791,7 @@ func (m *QueryAllInTxHashToCctxRequest) Reset() { *m = QueryAllInTxHashT func (m *QueryAllInTxHashToCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxHashToCctxRequest) ProtoMessage() {} func (*QueryAllInTxHashToCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{18} + return fileDescriptor_65a992045e92a606, []int{16} } func (m *QueryAllInTxHashToCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -919,7 +836,7 @@ func (m *QueryAllInTxHashToCctxResponse) Reset() { *m = QueryAllInTxHash func (m *QueryAllInTxHashToCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllInTxHashToCctxResponse) ProtoMessage() {} func (*QueryAllInTxHashToCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{19} + return fileDescriptor_65a992045e92a606, []int{17} } func (m *QueryAllInTxHashToCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -970,7 +887,7 @@ func (m *QueryGetGasPriceRequest) Reset() { *m = QueryGetGasPriceRequest func (m *QueryGetGasPriceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetGasPriceRequest) ProtoMessage() {} func (*QueryGetGasPriceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{20} + return fileDescriptor_65a992045e92a606, []int{18} } func (m *QueryGetGasPriceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1014,7 +931,7 @@ func (m *QueryGetGasPriceResponse) Reset() { *m = QueryGetGasPriceRespon func (m *QueryGetGasPriceResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetGasPriceResponse) ProtoMessage() {} func (*QueryGetGasPriceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{21} + return fileDescriptor_65a992045e92a606, []int{19} } func (m *QueryGetGasPriceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1058,7 +975,7 @@ func (m *QueryAllGasPriceRequest) Reset() { *m = QueryAllGasPriceRequest func (m *QueryAllGasPriceRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllGasPriceRequest) ProtoMessage() {} func (*QueryAllGasPriceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{22} + return fileDescriptor_65a992045e92a606, []int{20} } func (m *QueryAllGasPriceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1103,7 +1020,7 @@ func (m *QueryAllGasPriceResponse) Reset() { *m = QueryAllGasPriceRespon func (m *QueryAllGasPriceResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllGasPriceResponse) ProtoMessage() {} func (*QueryAllGasPriceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{23} + return fileDescriptor_65a992045e92a606, []int{21} } func (m *QueryAllGasPriceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1154,7 +1071,7 @@ func (m *QueryGetLastBlockHeightRequest) Reset() { *m = QueryGetLastBloc func (m *QueryGetLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightRequest) ProtoMessage() {} func (*QueryGetLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{24} + return fileDescriptor_65a992045e92a606, []int{22} } func (m *QueryGetLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1198,7 +1115,7 @@ func (m *QueryGetLastBlockHeightResponse) Reset() { *m = QueryGetLastBlo func (m *QueryGetLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetLastBlockHeightResponse) ProtoMessage() {} func (*QueryGetLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{25} + return fileDescriptor_65a992045e92a606, []int{23} } func (m *QueryGetLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1242,7 +1159,7 @@ func (m *QueryAllLastBlockHeightRequest) Reset() { *m = QueryAllLastBloc func (m *QueryAllLastBlockHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightRequest) ProtoMessage() {} func (*QueryAllLastBlockHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{26} + return fileDescriptor_65a992045e92a606, []int{24} } func (m *QueryAllLastBlockHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1287,7 +1204,7 @@ func (m *QueryAllLastBlockHeightResponse) Reset() { *m = QueryAllLastBlo func (m *QueryAllLastBlockHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllLastBlockHeightResponse) ProtoMessage() {} func (*QueryAllLastBlockHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{27} + return fileDescriptor_65a992045e92a606, []int{25} } func (m *QueryAllLastBlockHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1338,7 +1255,7 @@ func (m *QueryGetCctxRequest) Reset() { *m = QueryGetCctxRequest{} } func (m *QueryGetCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxRequest) ProtoMessage() {} func (*QueryGetCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{28} + return fileDescriptor_65a992045e92a606, []int{26} } func (m *QueryGetCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1383,7 +1300,7 @@ func (m *QueryGetCctxByNonceRequest) Reset() { *m = QueryGetCctxByNonceR func (m *QueryGetCctxByNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxByNonceRequest) ProtoMessage() {} func (*QueryGetCctxByNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{29} + return fileDescriptor_65a992045e92a606, []int{27} } func (m *QueryGetCctxByNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1434,7 +1351,7 @@ func (m *QueryGetCctxResponse) Reset() { *m = QueryGetCctxResponse{} } func (m *QueryGetCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCctxResponse) ProtoMessage() {} func (*QueryGetCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{30} + return fileDescriptor_65a992045e92a606, []int{28} } func (m *QueryGetCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1478,7 +1395,7 @@ func (m *QueryAllCctxRequest) Reset() { *m = QueryAllCctxRequest{} } func (m *QueryAllCctxRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxRequest) ProtoMessage() {} func (*QueryAllCctxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{31} + return fileDescriptor_65a992045e92a606, []int{29} } func (m *QueryAllCctxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1523,7 +1440,7 @@ func (m *QueryAllCctxResponse) Reset() { *m = QueryAllCctxResponse{} } func (m *QueryAllCctxResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllCctxResponse) ProtoMessage() {} func (*QueryAllCctxResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{32} + return fileDescriptor_65a992045e92a606, []int{30} } func (m *QueryAllCctxResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1575,7 +1492,7 @@ func (m *QueryListCctxPendingRequest) Reset() { *m = QueryListCctxPendin func (m *QueryListCctxPendingRequest) String() string { return proto.CompactTextString(m) } func (*QueryListCctxPendingRequest) ProtoMessage() {} func (*QueryListCctxPendingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{33} + return fileDescriptor_65a992045e92a606, []int{31} } func (m *QueryListCctxPendingRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1627,7 +1544,7 @@ func (m *QueryListCctxPendingResponse) Reset() { *m = QueryListCctxPendi func (m *QueryListCctxPendingResponse) String() string { return proto.CompactTextString(m) } func (*QueryListCctxPendingResponse) ProtoMessage() {} func (*QueryListCctxPendingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{34} + return fileDescriptor_65a992045e92a606, []int{32} } func (m *QueryListCctxPendingResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1677,7 +1594,7 @@ func (m *QueryLastZetaHeightRequest) Reset() { *m = QueryLastZetaHeightR func (m *QueryLastZetaHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightRequest) ProtoMessage() {} func (*QueryLastZetaHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{35} + return fileDescriptor_65a992045e92a606, []int{33} } func (m *QueryLastZetaHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1714,7 +1631,7 @@ func (m *QueryLastZetaHeightResponse) Reset() { *m = QueryLastZetaHeight func (m *QueryLastZetaHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryLastZetaHeightResponse) ProtoMessage() {} func (*QueryLastZetaHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{36} + return fileDescriptor_65a992045e92a606, []int{34} } func (m *QueryLastZetaHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1759,7 +1676,7 @@ func (m *QueryConvertGasToZetaRequest) Reset() { *m = QueryConvertGasToZ func (m *QueryConvertGasToZetaRequest) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaRequest) ProtoMessage() {} func (*QueryConvertGasToZetaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{37} + return fileDescriptor_65a992045e92a606, []int{35} } func (m *QueryConvertGasToZetaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1812,7 +1729,7 @@ func (m *QueryConvertGasToZetaResponse) Reset() { *m = QueryConvertGasTo func (m *QueryConvertGasToZetaResponse) String() string { return proto.CompactTextString(m) } func (*QueryConvertGasToZetaResponse) ProtoMessage() {} func (*QueryConvertGasToZetaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{38} + return fileDescriptor_65a992045e92a606, []int{36} } func (m *QueryConvertGasToZetaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1869,7 +1786,7 @@ func (m *QueryMessagePassingProtocolFeeRequest) Reset() { *m = QueryMess func (m *QueryMessagePassingProtocolFeeRequest) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeRequest) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{39} + return fileDescriptor_65a992045e92a606, []int{37} } func (m *QueryMessagePassingProtocolFeeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1908,7 +1825,7 @@ func (m *QueryMessagePassingProtocolFeeResponse) Reset() { func (m *QueryMessagePassingProtocolFeeResponse) String() string { return proto.CompactTextString(m) } func (*QueryMessagePassingProtocolFeeResponse) ProtoMessage() {} func (*QueryMessagePassingProtocolFeeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_65a992045e92a606, []int{40} + return fileDescriptor_65a992045e92a606, []int{38} } func (m *QueryMessagePassingProtocolFeeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1947,8 +1864,6 @@ func (m *QueryMessagePassingProtocolFeeResponse) GetFeeInZeta() string { func init() { proto.RegisterType((*QueryZetaAccountingRequest)(nil), "zetachain.zetacore.crosschain.QueryZetaAccountingRequest") proto.RegisterType((*QueryZetaAccountingResponse)(nil), "zetachain.zetacore.crosschain.QueryZetaAccountingResponse") - proto.RegisterType((*QueryParamsRequest)(nil), "zetachain.zetacore.crosschain.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "zetachain.zetacore.crosschain.QueryParamsResponse") proto.RegisterType((*QueryGetOutTxTrackerRequest)(nil), "zetachain.zetacore.crosschain.QueryGetOutTxTrackerRequest") proto.RegisterType((*QueryGetOutTxTrackerResponse)(nil), "zetachain.zetacore.crosschain.QueryGetOutTxTrackerResponse") proto.RegisterType((*QueryAllOutTxTrackerRequest)(nil), "zetachain.zetacore.crosschain.QueryAllOutTxTrackerRequest") @@ -1991,119 +1906,115 @@ func init() { func init() { proto.RegisterFile("crosschain/query.proto", fileDescriptor_65a992045e92a606) } var fileDescriptor_65a992045e92a606 = []byte{ - // 1782 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xdf, 0x6f, 0x14, 0x55, - 0x14, 0xee, 0xed, 0xd2, 0x52, 0x6e, 0x0b, 0x95, 0x4b, 0x85, 0x3a, 0xb4, 0x5b, 0x98, 0x5a, 0x5a, - 0xc1, 0xee, 0xd0, 0x02, 0x45, 0xa0, 0x18, 0xb7, 0x45, 0x0a, 0xb1, 0x40, 0xdd, 0xd4, 0x68, 0x30, - 0x66, 0x73, 0x3b, 0x3b, 0xce, 0x4e, 0x98, 0xce, 0x94, 0x9d, 0x59, 0xd2, 0xd2, 0xf4, 0x85, 0x07, - 0x5f, 0x7c, 0x31, 0x21, 0xd1, 0x17, 0x5f, 0x8d, 0x3e, 0xf8, 0xe0, 0x83, 0xd1, 0x07, 0x13, 0x8c, - 0x51, 0x91, 0x47, 0x12, 0x13, 0x63, 0x34, 0x31, 0x06, 0xfc, 0x43, 0xcc, 0xdc, 0x39, 0xb3, 0x7b, - 0xe7, 0xd7, 0xee, 0xed, 0x76, 0x79, 0xe0, 0xa9, 0x3b, 0x73, 0xef, 0x39, 0xe7, 0xfb, 0xbe, 0xfb, - 0x63, 0xce, 0x39, 0xc5, 0x07, 0xd5, 0x8a, 0xed, 0x38, 0x6a, 0x99, 0x1a, 0x96, 0x72, 0xbb, 0xaa, - 0x55, 0x36, 0x72, 0x6b, 0x15, 0xdb, 0xb5, 0xc9, 0xf0, 0x5d, 0xcd, 0xa5, 0xec, 0x75, 0x8e, 0xfd, - 0xb2, 0x2b, 0x5a, 0xae, 0x3e, 0x55, 0x3a, 0xae, 0xda, 0xce, 0xaa, 0xed, 0x28, 0x2b, 0xd4, 0xd1, - 0x7c, 0x3b, 0xe5, 0xce, 0xd4, 0x8a, 0xe6, 0xd2, 0x29, 0x65, 0x8d, 0xea, 0x86, 0x45, 0x5d, 0xc3, - 0xb6, 0x7c, 0x57, 0xd2, 0x08, 0x17, 0x82, 0xfd, 0x2c, 0xb2, 0xdf, 0x45, 0x77, 0x1d, 0x26, 0x48, - 0xdc, 0x04, 0x9d, 0x3a, 0xc5, 0xb5, 0x8a, 0xa1, 0x6a, 0x30, 0x36, 0xca, 0x8d, 0x31, 0x9b, 0x62, - 0x99, 0x3a, 0xe5, 0xa2, 0x6b, 0x17, 0x55, 0xb5, 0xe6, 0x20, 0x1b, 0x9b, 0xe4, 0x56, 0xa8, 0x7a, - 0x4b, 0xab, 0xc0, 0xb8, 0xcc, 0x8d, 0x9b, 0xd4, 0x71, 0x8b, 0x2b, 0xa6, 0xad, 0xde, 0x2a, 0x96, - 0x35, 0x43, 0x2f, 0xbb, 0x09, 0x28, 0xed, 0xaa, 0x1b, 0x77, 0x72, 0x88, 0x9b, 0xb0, 0x46, 0x2b, - 0x74, 0xd5, 0x81, 0x81, 0x01, 0xdd, 0xd6, 0x6d, 0xf6, 0x53, 0xf1, 0x7e, 0xc1, 0xdb, 0x21, 0xdd, - 0xb6, 0x75, 0x53, 0x53, 0xe8, 0x9a, 0xa1, 0x50, 0xcb, 0xb2, 0x5d, 0x26, 0x09, 0xd8, 0xc8, 0x43, - 0x58, 0x7a, 0xdb, 0x53, 0xed, 0xa6, 0xe6, 0xd2, 0xbc, 0xaa, 0xda, 0x55, 0xcb, 0x35, 0x2c, 0xbd, - 0xa0, 0xdd, 0xae, 0x6a, 0x8e, 0x2b, 0x5f, 0xc3, 0x87, 0x13, 0x47, 0x9d, 0x35, 0xdb, 0x72, 0x34, - 0x92, 0xc3, 0x07, 0xe8, 0x8a, 0x5d, 0x71, 0xb5, 0x52, 0xd1, 0x5b, 0x9b, 0x22, 0x5d, 0xf5, 0x66, - 0x0c, 0xa2, 0x23, 0x68, 0x62, 0x4f, 0x61, 0x3f, 0x0c, 0x31, 0x5b, 0x36, 0x20, 0x0f, 0x60, 0xc2, - 0xdc, 0x2d, 0x31, 0xd4, 0x41, 0x90, 0x9b, 0xf8, 0x40, 0xe8, 0x2d, 0x38, 0x9f, 0xc7, 0xdd, 0x3e, - 0x3b, 0xe6, 0xaf, 0x77, 0x7a, 0x2c, 0xd7, 0x70, 0x27, 0xe4, 0x7c, 0xf3, 0xb9, 0x5d, 0x8f, 0xfe, - 0x19, 0xe9, 0x28, 0x80, 0x69, 0x8d, 0xc0, 0x82, 0xe6, 0xde, 0xa8, 0xba, 0xcb, 0xeb, 0xcb, 0xbe, - 0x92, 0x10, 0x9a, 0x0c, 0xe2, 0xdd, 0xcc, 0xf8, 0xea, 0x25, 0x16, 0x24, 0x53, 0x08, 0x1e, 0xc9, - 0x00, 0xee, 0xb2, 0x6c, 0x4b, 0xd5, 0x06, 0x3b, 0x8f, 0xa0, 0x89, 0x5d, 0x05, 0xff, 0x41, 0xae, - 0xe2, 0xa1, 0x64, 0x77, 0x80, 0xf9, 0x1d, 0xdc, 0x67, 0x73, 0xef, 0x01, 0xf9, 0x89, 0x26, 0xc8, - 0x79, 0x57, 0x80, 0x3f, 0xe4, 0x46, 0xd6, 0x80, 0x45, 0xde, 0x34, 0x93, 0x58, 0x5c, 0xc6, 0xb8, - 0xbe, 0xd7, 0x21, 0xe6, 0xb1, 0x9c, 0x7f, 0x30, 0x72, 0xde, 0xc1, 0xc8, 0xf9, 0x07, 0x0a, 0x0e, - 0x46, 0x6e, 0x89, 0xea, 0x1a, 0xd8, 0x16, 0x38, 0x4b, 0xf9, 0x01, 0x02, 0x7a, 0xb1, 0x38, 0xa9, - 0xf4, 0x32, 0x6d, 0xa0, 0x47, 0x16, 0x42, 0xf8, 0x3b, 0x19, 0xfe, 0xf1, 0xa6, 0xf8, 0x7d, 0x4c, - 0x21, 0x02, 0xf7, 0x10, 0x96, 0x93, 0x08, 0xcc, 0x6d, 0xcc, 0x7b, 0x48, 0x02, 0xbd, 0x06, 0x70, - 0x17, 0x43, 0x06, 0x6b, 0xee, 0x3f, 0x44, 0x54, 0xec, 0x6c, 0x59, 0xc5, 0x5f, 0x11, 0x1e, 0x6d, - 0x08, 0xe2, 0x39, 0x11, 0xf3, 0x23, 0x84, 0x8f, 0x06, 0x3c, 0xae, 0x5a, 0x69, 0x5a, 0xbe, 0x84, - 0x7b, 0xfc, 0x4b, 0xd4, 0x28, 0x85, 0x8f, 0x50, 0xa9, 0x6d, 0x82, 0xfe, 0xc4, 0xad, 0x6a, 0x12, - 0x10, 0xd0, 0xb3, 0x80, 0x7b, 0x0d, 0x2b, 0x2a, 0xe7, 0xf1, 0x26, 0x72, 0xf2, 0xfe, 0x7c, 0x35, - 0x79, 0x27, 0xed, 0x13, 0x93, 0x3b, 0xc1, 0x5c, 0x48, 0xa7, 0xdd, 0x27, 0xf8, 0x07, 0xee, 0x04, - 0x87, 0xe3, 0x3c, 0x0f, 0x22, 0x5d, 0xc0, 0xc3, 0xc1, 0xed, 0xea, 0x85, 0xbc, 0x42, 0x9d, 0xf2, - 0xb2, 0x3d, 0xaf, 0xba, 0xeb, 0x81, 0x4c, 0x12, 0xee, 0x31, 0x60, 0x00, 0x3e, 0x32, 0xb5, 0x67, - 0x79, 0x0b, 0x67, 0xd3, 0x8c, 0x81, 0xfb, 0xfb, 0x78, 0x9f, 0x11, 0x1a, 0x01, 0xa1, 0x27, 0x05, - 0xe8, 0xd7, 0x8d, 0x40, 0x81, 0x88, 0x2b, 0x79, 0x16, 0xc2, 0x87, 0x27, 0x5f, 0xa2, 0x2e, 0x15, - 0x01, 0x7f, 0x17, 0x8f, 0xa4, 0x5a, 0x03, 0xfa, 0x77, 0xf1, 0xde, 0x79, 0x0f, 0x13, 0xdb, 0xf4, - 0xcb, 0xeb, 0x8e, 0xe0, 0x7d, 0xc1, 0xdb, 0x00, 0xf4, 0xb0, 0x1f, 0x59, 0x07, 0xd5, 0x61, 0xcb, - 0xc4, 0x55, 0x6f, 0xd7, 0xe6, 0x7c, 0x88, 0x40, 0xa3, 0x84, 0x48, 0x0d, 0x96, 0x28, 0xd3, 0xa6, - 0x25, 0x6a, 0xdf, 0x3e, 0x55, 0xf0, 0xa1, 0x60, 0xab, 0x2d, 0x50, 0x67, 0xc9, 0x4b, 0x12, 0xb9, - 0x4f, 0x8b, 0x61, 0x95, 0xb4, 0x75, 0x58, 0x61, 0xff, 0x41, 0x2e, 0xe2, 0xc1, 0xb8, 0x41, 0x2d, - 0xcd, 0xe9, 0x09, 0xde, 0x81, 0xb6, 0xe3, 0x4d, 0xc8, 0xd6, 0x5c, 0xd4, 0x0c, 0x65, 0x0a, 0x88, - 0xf2, 0xa6, 0x19, 0x45, 0xd4, 0xae, 0xd5, 0xfb, 0x0a, 0x01, 0x89, 0x50, 0x8c, 0x44, 0x12, 0x99, - 0x96, 0x48, 0xb4, 0x6f, 0x7d, 0x66, 0xea, 0x57, 0xc1, 0x22, 0x75, 0xdc, 0x39, 0x2f, 0xc7, 0xbe, - 0xc2, 0x52, 0xec, 0xc6, 0xcb, 0xb4, 0x09, 0xa7, 0x30, 0xc9, 0x0e, 0x88, 0xbe, 0x87, 0xfb, 0x23, - 0x43, 0x20, 0x69, 0xae, 0x09, 0xdf, 0xa8, 0xc3, 0xa8, 0x1b, 0xb9, 0x5c, 0x3f, 0x1c, 0x29, 0xa0, - 0xdb, 0xb5, 0x92, 0xbf, 0x20, 0xe0, 0x99, 0x14, 0xaa, 0x11, 0xcf, 0x4c, 0x1b, 0x78, 0xb6, 0x6f, - 0x95, 0x4f, 0x40, 0xd9, 0xb0, 0xa0, 0xb9, 0xfc, 0x6d, 0x95, 0xbc, 0xb4, 0x8b, 0x50, 0xe6, 0xc0, - 0xe4, 0xb9, 0x8d, 0xeb, 0x5e, 0x3e, 0xdf, 0x6a, 0x19, 0xa0, 0xe3, 0x81, 0x70, 0x68, 0x50, 0xed, - 0x06, 0xee, 0xe3, 0xef, 0x56, 0xc1, 0xf4, 0x9f, 0x37, 0x29, 0x84, 0x1c, 0xc8, 0x1f, 0x00, 0xc7, - 0xbc, 0x69, 0x3e, 0x8b, 0x1b, 0xf9, 0x1b, 0x04, 0x44, 0x6a, 0xfe, 0x53, 0x89, 0x64, 0x76, 0x44, - 0xa4, 0x7d, 0xab, 0x7e, 0x1d, 0x12, 0xa9, 0x45, 0xc3, 0x61, 0xda, 0x2f, 0x69, 0x56, 0xa9, 0x5e, - 0xb0, 0x36, 0x4a, 0x47, 0x07, 0x70, 0x97, 0x69, 0xac, 0x1a, 0x2e, 0x8b, 0xbe, 0xb7, 0xe0, 0x3f, - 0xc8, 0xf7, 0x83, 0x8c, 0x29, 0xe6, 0xf0, 0x59, 0x49, 0x21, 0xe3, 0x3e, 0xd7, 0x76, 0xa9, 0x09, - 0x81, 0x60, 0x67, 0x85, 0xde, 0xd5, 0xaa, 0x72, 0xef, 0xf0, 0x78, 0xf5, 0x73, 0xe8, 0x22, 0x90, - 0xcf, 0x04, 0x1a, 0x44, 0x46, 0x01, 0xf1, 0x41, 0xdc, 0xcd, 0x5d, 0x4d, 0x99, 0x02, 0x3c, 0xc9, - 0xcb, 0xc0, 0x74, 0xde, 0xb6, 0xee, 0x68, 0x15, 0xef, 0x4b, 0xb4, 0x6c, 0x7b, 0xe6, 0xb1, 0x53, - 0x10, 0x93, 0x4e, 0xc2, 0x3d, 0x3a, 0x75, 0x16, 0x6b, 0xea, 0xed, 0x29, 0xd4, 0x9e, 0xe5, 0x2f, - 0x10, 0xe4, 0x0f, 0x71, 0xb7, 0x80, 0xe7, 0x55, 0xbc, 0xdf, 0xae, 0xba, 0x2b, 0x76, 0xd5, 0x2a, - 0x2d, 0x50, 0xe7, 0xaa, 0xe5, 0x0d, 0x06, 0x3d, 0x82, 0xd8, 0x80, 0x37, 0x9b, 0x75, 0x26, 0x54, - 0xdb, 0xbc, 0xac, 0x69, 0x30, 0xdb, 0x0f, 0x1a, 0x1f, 0x20, 0x13, 0xb8, 0xdf, 0xfb, 0xcb, 0xdf, - 0x53, 0x19, 0xa6, 0x67, 0xf4, 0xb5, 0x3c, 0x8e, 0xc7, 0x18, 0xcc, 0x6b, 0x9a, 0xe3, 0x50, 0x5d, - 0x5b, 0xa2, 0x8e, 0x63, 0x58, 0xfa, 0x52, 0xdd, 0x63, 0xa0, 0xee, 0x65, 0x7c, 0xac, 0xd9, 0x44, - 0x20, 0x36, 0x84, 0xf7, 0x7c, 0x58, 0x83, 0xe8, 0x13, 0xaa, 0xbf, 0x98, 0xfe, 0x78, 0x04, 0x77, - 0x31, 0x47, 0xe4, 0x53, 0x84, 0xbb, 0xfd, 0xee, 0x04, 0x99, 0x6a, 0xb2, 0x6f, 0xe2, 0xed, 0x11, - 0x69, 0x7a, 0x3b, 0x26, 0x3e, 0x32, 0x79, 0xec, 0xde, 0xef, 0xff, 0xdd, 0xef, 0x1c, 0x21, 0xc3, - 0x8a, 0x67, 0x31, 0xc9, 0xb5, 0xbc, 0xf8, 0xb6, 0x11, 0x79, 0x88, 0x70, 0x1f, 0x5f, 0x50, 0x92, - 0xf3, 0x22, 0xb1, 0x92, 0x7b, 0x29, 0xd2, 0x85, 0x96, 0x6c, 0x01, 0xf0, 0x45, 0x06, 0xf8, 0x2c, - 0x39, 0x93, 0x02, 0x98, 0x2f, 0x71, 0x95, 0x4d, 0xb8, 0x9d, 0xb7, 0x94, 0x4d, 0x76, 0x1f, 0x6f, - 0x91, 0xef, 0x11, 0xee, 0xe7, 0xfd, 0xe6, 0x4d, 0x53, 0x8c, 0x4b, 0x72, 0x47, 0x45, 0x8c, 0x4b, - 0x4a, 0x97, 0x44, 0x3e, 0xc1, 0xb8, 0x8c, 0x91, 0x51, 0x01, 0x2e, 0xe4, 0x6f, 0x84, 0x0f, 0x46, - 0x90, 0x43, 0x61, 0x4b, 0xf2, 0x2d, 0x80, 0x08, 0x57, 0xe7, 0xd2, 0xdc, 0x4e, 0x5c, 0x00, 0x9d, - 0xf3, 0x8c, 0xce, 0x69, 0x32, 0x2d, 0x40, 0x07, 0x6c, 0x61, 0x85, 0xb6, 0xc8, 0x5f, 0x08, 0xbf, - 0xc8, 0x55, 0x8f, 0x1c, 0xb9, 0x37, 0x04, 0x91, 0xa5, 0x76, 0x1e, 0xa4, 0xfc, 0x0e, 0x3c, 0x00, - 0xb5, 0x59, 0x46, 0x6d, 0x86, 0x9c, 0x4e, 0xa1, 0x66, 0x58, 0x29, 0xcc, 0x8a, 0x46, 0x69, 0x8b, - 0x7c, 0x87, 0xf0, 0xbe, 0x30, 0x39, 0xe1, 0x3d, 0x97, 0xd0, 0x03, 0x10, 0xde, 0x73, 0x49, 0x75, - 0x7d, 0xd3, 0x3d, 0xc7, 0x31, 0x71, 0xc8, 0x6f, 0x00, 0x9c, 0xab, 0x8d, 0x66, 0x05, 0x0f, 0x6f, - 0x62, 0x85, 0x28, 0x5d, 0x6c, 0xd1, 0x1a, 0xc0, 0xbf, 0xc6, 0xc0, 0x4f, 0x93, 0x93, 0x0d, 0xc0, - 0xd7, 0xcd, 0x94, 0xcd, 0xe0, 0x79, 0x8b, 0xfc, 0x81, 0x30, 0x89, 0xd7, 0xcc, 0x44, 0x08, 0x4f, - 0x6a, 0xa5, 0x2e, 0xbd, 0xde, 0xaa, 0x39, 0xf0, 0xc9, 0x33, 0x3e, 0x17, 0xc8, 0xb9, 0x54, 0x3e, - 0xd1, 0x7f, 0x1f, 0x14, 0x4b, 0xd4, 0xa5, 0x3c, 0xb1, 0x1f, 0x11, 0xde, 0x1f, 0x8e, 0xe0, 0x6d, - 0xaf, 0xd9, 0x6d, 0x6c, 0x91, 0x16, 0x57, 0x29, 0xb5, 0x36, 0x97, 0x27, 0x19, 0xab, 0x71, 0x32, - 0x26, 0xb4, 0x4a, 0xe4, 0x6b, 0x54, 0xaf, 0x09, 0xc9, 0x8c, 0xe0, 0x06, 0x89, 0x14, 0xaf, 0xd2, - 0xd9, 0x6d, 0xdb, 0x01, 0x58, 0x85, 0x81, 0x7d, 0x85, 0x8c, 0xa7, 0x80, 0xd5, 0xc1, 0xc0, 0xd3, - 0xbc, 0xa4, 0xad, 0x6f, 0x91, 0x2f, 0x11, 0xee, 0x0d, 0xbc, 0x78, 0x52, 0xcf, 0x08, 0x8a, 0xd5, - 0x12, 0xe2, 0x84, 0x12, 0x5a, 0x1e, 0x67, 0x88, 0x8f, 0x92, 0x91, 0x26, 0x88, 0xc9, 0x03, 0x84, - 0x5f, 0x88, 0xe6, 0x5a, 0x44, 0xe8, 0xf2, 0x48, 0x49, 0xfc, 0xa4, 0xd9, 0xd6, 0x8c, 0x05, 0xa5, - 0x56, 0xa3, 0x58, 0x1f, 0x22, 0xdc, 0xcb, 0xa5, 0x53, 0xe4, 0x92, 0x48, 0xf8, 0x66, 0x69, 0x9b, - 0xf4, 0xe6, 0x0e, 0xbd, 0x00, 0x9b, 0xe3, 0x8c, 0xcd, 0xcb, 0x44, 0x4e, 0xcb, 0x9c, 0x38, 0xe0, - 0x8f, 0x50, 0xac, 0x4a, 0x26, 0xa2, 0x57, 0x61, 0x72, 0x8d, 0x2f, 0x76, 0xf5, 0xa4, 0xf7, 0x27, - 0xe4, 0x19, 0x06, 0xff, 0x24, 0xc9, 0xa5, 0xc0, 0x37, 0xc3, 0x76, 0xb5, 0xed, 0xff, 0x33, 0xc2, - 0x24, 0xe2, 0xd3, 0x3b, 0x05, 0xa2, 0x57, 0xc6, 0x4e, 0xd8, 0xa4, 0x77, 0x21, 0xe4, 0x1c, 0x63, - 0x33, 0x41, 0x8e, 0x89, 0xb1, 0x21, 0x9f, 0x23, 0xbc, 0x8b, 0x5d, 0x3e, 0xd3, 0x82, 0x32, 0xf2, - 0xd7, 0xe3, 0xa9, 0x6d, 0xd9, 0x08, 0x7e, 0x77, 0x55, 0xf8, 0x60, 0x31, 0x91, 0xbf, 0x45, 0xb8, - 0x97, 0xeb, 0x3e, 0x90, 0x73, 0xdb, 0x88, 0x18, 0xee, 0x58, 0xb4, 0x06, 0xf6, 0x0c, 0x03, 0xab, - 0x90, 0xc9, 0x86, 0x60, 0x63, 0xc9, 0xf5, 0x67, 0x08, 0xef, 0x0e, 0xbe, 0x40, 0xd3, 0x82, 0x2b, - 0xba, 0x6d, 0x61, 0x23, 0x1d, 0x08, 0x79, 0x94, 0x61, 0x1d, 0x26, 0x87, 0x1b, 0x60, 0xf5, 0x32, - 0xb0, 0x7e, 0xcf, 0xca, 0xab, 0xdd, 0xa1, 0x74, 0x16, 0x4b, 0xc1, 0x92, 0xbb, 0x07, 0x62, 0x29, - 0x58, 0x4a, 0xa3, 0xa0, 0xe9, 0xcd, 0xa1, 0xd6, 0x6d, 0x58, 0xea, 0x18, 0xfe, 0x9f, 0xba, 0xd8, - 0x66, 0x48, 0xfc, 0x2f, 0xbd, 0x74, 0xbe, 0x15, 0x53, 0xc1, 0xaf, 0xfa, 0xdd, 0x30, 0x4a, 0x0f, - 0x78, 0xb8, 0xed, 0x20, 0x06, 0x3c, 0xb1, 0x91, 0x21, 0x06, 0x3c, 0xb9, 0xcb, 0xd1, 0x14, 0xb8, - 0x19, 0x32, 0x9b, 0x7b, 0xeb, 0xd1, 0x93, 0x2c, 0x7a, 0xfc, 0x24, 0x8b, 0xfe, 0x7d, 0x92, 0x45, - 0x9f, 0x3c, 0xcd, 0x76, 0x3c, 0x7e, 0x9a, 0xed, 0xf8, 0xf3, 0x69, 0xb6, 0xe3, 0xe6, 0x94, 0x6e, - 0xb8, 0xe5, 0xea, 0x4a, 0x4e, 0xb5, 0x57, 0x79, 0x57, 0x01, 0x1e, 0x65, 0x9d, 0xf7, 0xea, 0x6e, - 0xac, 0x69, 0xce, 0x4a, 0x37, 0xfb, 0x0a, 0x9c, 0xfa, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x77, - 0x46, 0x98, 0xb4, 0x22, 0x00, 0x00, + // 1715 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xd1, 0x6f, 0x14, 0x45, + 0x18, 0xef, 0xf4, 0x28, 0x94, 0x69, 0xa1, 0x32, 0x54, 0xac, 0x4b, 0x7b, 0x85, 0xad, 0xd0, 0x0a, + 0xf6, 0x16, 0x0a, 0x14, 0x81, 0x62, 0xbc, 0x16, 0x29, 0xc4, 0x02, 0xf5, 0x52, 0xa3, 0xc1, 0x98, + 0xcb, 0x74, 0x6f, 0xdd, 0xdb, 0xb0, 0xdd, 0x29, 0xb7, 0x7b, 0xa4, 0xa5, 0xe9, 0x0b, 0x0f, 0x3e, + 0x9b, 0xf0, 0xe0, 0x8b, 0xaf, 0x46, 0x1f, 0x7c, 0xf0, 0xc1, 0xe8, 0x83, 0x09, 0xc6, 0xa8, 0xc8, + 0x23, 0x89, 0x89, 0x31, 0x9a, 0x18, 0x03, 0xfe, 0x05, 0xfe, 0x05, 0x66, 0x67, 0xbf, 0xbd, 0x9b, + 0xdd, 0xdb, 0xbd, 0x9b, 0x5e, 0x8f, 0x07, 0x9e, 0x7a, 0xbb, 0x33, 0xdf, 0x37, 0xbf, 0xdf, 0x6f, + 0xbe, 0xf9, 0xf6, 0xfb, 0xa6, 0xf8, 0x80, 0x5e, 0x61, 0xae, 0xab, 0x97, 0xa9, 0xe5, 0x68, 0xb7, + 0xab, 0x46, 0x65, 0x3d, 0xb7, 0x5a, 0x61, 0x1e, 0x23, 0x23, 0x77, 0x0d, 0x8f, 0xf2, 0xd7, 0x39, + 0xfe, 0x8b, 0x55, 0x8c, 0x5c, 0x7d, 0xaa, 0x72, 0x4c, 0x67, 0xee, 0x0a, 0x73, 0xb5, 0x65, 0xea, + 0x1a, 0x81, 0x9d, 0x76, 0xe7, 0xe4, 0xb2, 0xe1, 0xd1, 0x93, 0xda, 0x2a, 0x35, 0x2d, 0x87, 0x7a, + 0x16, 0x73, 0x02, 0x57, 0xca, 0xa8, 0xb0, 0x04, 0xff, 0x59, 0xe4, 0xbf, 0x8b, 0xde, 0x1a, 0x4c, + 0x50, 0x84, 0x09, 0x26, 0x75, 0x8b, 0xab, 0x15, 0x4b, 0x37, 0x60, 0x6c, 0x4c, 0x18, 0xe3, 0x36, + 0xc5, 0x32, 0x75, 0xcb, 0x45, 0x8f, 0x15, 0x75, 0xbd, 0xe6, 0x20, 0xdb, 0x30, 0xc9, 0xab, 0x50, + 0xfd, 0x96, 0x51, 0x81, 0x71, 0x55, 0x18, 0xb7, 0xa9, 0xeb, 0x15, 0x97, 0x6d, 0xa6, 0xdf, 0x2a, + 0x96, 0x0d, 0xcb, 0x2c, 0x7b, 0x09, 0x28, 0x59, 0xd5, 0x6b, 0x74, 0x32, 0x68, 0x32, 0x93, 0xf1, + 0x9f, 0x9a, 0xff, 0x0b, 0xde, 0x0e, 0x9b, 0x8c, 0x99, 0xb6, 0xa1, 0xd1, 0x55, 0x4b, 0xa3, 0x8e, + 0xc3, 0x3c, 0xce, 0xdc, 0x0d, 0x46, 0xd5, 0x61, 0xac, 0xbc, 0xe3, 0x8b, 0x73, 0xd3, 0xf0, 0x68, + 0x5e, 0xd7, 0x59, 0xd5, 0xf1, 0x2c, 0xc7, 0x2c, 0x18, 0xb7, 0xab, 0x86, 0xeb, 0xa9, 0xd7, 0xf0, + 0xc1, 0xc4, 0x51, 0x77, 0x95, 0x39, 0xae, 0x41, 0x72, 0x78, 0x3f, 0x5d, 0x66, 0x15, 0xcf, 0x28, + 0x15, 0xfd, 0x2d, 0x28, 0xd2, 0x15, 0x7f, 0xc6, 0x10, 0x3a, 0x84, 0x26, 0x76, 0x17, 0xf6, 0xc1, + 0x10, 0xb7, 0xe5, 0x03, 0x35, 0x77, 0xf3, 0x86, 0x77, 0xa3, 0xea, 0x2d, 0xad, 0x2d, 0x05, 0xf0, + 0x61, 0x35, 0x32, 0x84, 0x77, 0x71, 0x76, 0x57, 0x2f, 0x71, 0x17, 0x99, 0x42, 0xf8, 0x48, 0x06, + 0x71, 0x8f, 0xc3, 0x1c, 0xdd, 0x18, 0xea, 0x3e, 0x84, 0x26, 0x76, 0x14, 0x82, 0x07, 0xb5, 0x8a, + 0x87, 0x93, 0xdd, 0x01, 0xbc, 0x77, 0x71, 0x3f, 0x13, 0xde, 0x73, 0xa7, 0x7d, 0x53, 0xc7, 0x73, + 0x4d, 0x03, 0x27, 0x27, 0xba, 0x9a, 0xdd, 0xf1, 0xe8, 0xef, 0xd1, 0xae, 0x42, 0xc4, 0x8d, 0x6a, + 0x00, 0x8b, 0xbc, 0x6d, 0x27, 0xb1, 0xb8, 0x8c, 0x71, 0x3d, 0xc0, 0x60, 0xcd, 0xa3, 0xb9, 0x20, + 0x1a, 0x73, 0x7e, 0x34, 0xe6, 0x82, 0x28, 0x86, 0x68, 0xcc, 0x2d, 0x52, 0xd3, 0x00, 0xdb, 0x82, + 0x60, 0xa9, 0x3e, 0x40, 0x40, 0xaf, 0x61, 0x9d, 0x54, 0x7a, 0x99, 0x0e, 0xd0, 0x23, 0xf3, 0x11, + 0xfc, 0xdd, 0x1c, 0xff, 0x78, 0x4b, 0xfc, 0x01, 0xa6, 0x08, 0x81, 0x7b, 0x08, 0xab, 0x49, 0x04, + 0x66, 0xd7, 0xe7, 0x7c, 0x24, 0xa1, 0x5e, 0x83, 0xb8, 0x87, 0x23, 0x83, 0x3d, 0x0f, 0x1e, 0x62, + 0x2a, 0x76, 0xb7, 0xad, 0xe2, 0x2f, 0x08, 0x8f, 0x35, 0x05, 0xf1, 0x9c, 0x88, 0xf9, 0x31, 0xc2, + 0x87, 0x43, 0x1e, 0x57, 0x9d, 0x34, 0x2d, 0x5f, 0xc6, 0xbd, 0x41, 0xe6, 0xb2, 0x4a, 0xd1, 0x23, + 0x54, 0xea, 0x98, 0xa0, 0x3f, 0x0a, 0xbb, 0x9a, 0x04, 0x04, 0xf4, 0x2c, 0xe0, 0x3e, 0xcb, 0x89, + 0xcb, 0x79, 0xac, 0x85, 0x9c, 0xa2, 0xbf, 0x40, 0x4d, 0xd1, 0x49, 0xe7, 0xc4, 0x14, 0x4e, 0xb0, + 0xb0, 0xa4, 0xdb, 0xe9, 0x13, 0xfc, 0xbd, 0x70, 0x82, 0xa3, 0xeb, 0x3c, 0x0f, 0x22, 0x5d, 0xc0, + 0x23, 0x61, 0x76, 0xf5, 0x97, 0xbc, 0x42, 0xdd, 0xf2, 0x12, 0x9b, 0xd3, 0xbd, 0xb5, 0x50, 0x26, + 0x05, 0xf7, 0x5a, 0x30, 0x00, 0x29, 0xbf, 0xf6, 0xac, 0x6e, 0xe2, 0x6c, 0x9a, 0x31, 0x70, 0xff, + 0x00, 0xef, 0xb5, 0x22, 0x23, 0x20, 0xf4, 0xa4, 0x04, 0xfd, 0xba, 0x11, 0x28, 0x10, 0x73, 0xa5, + 0xce, 0xc0, 0xf2, 0xd1, 0xc9, 0x97, 0xa8, 0x47, 0x65, 0xc0, 0xdf, 0xc5, 0xa3, 0xa9, 0xd6, 0x80, + 0xfe, 0x3d, 0xbc, 0x67, 0xce, 0xc7, 0xc4, 0x83, 0x7e, 0x69, 0xcd, 0x95, 0xcc, 0x17, 0xa2, 0x0d, + 0x40, 0x8f, 0xfa, 0x51, 0x4d, 0x50, 0x1d, 0x42, 0xa6, 0x51, 0xf5, 0x4e, 0x05, 0xe7, 0x43, 0x04, + 0x1a, 0x25, 0xac, 0xd4, 0x64, 0x8b, 0x32, 0x1d, 0xda, 0xa2, 0xce, 0xc5, 0xa9, 0x86, 0x5f, 0x0a, + 0x43, 0x6d, 0x9e, 0xba, 0x8b, 0x7e, 0x65, 0x26, 0x7c, 0x5a, 0x2c, 0xa7, 0x64, 0xac, 0xc1, 0x0e, + 0x07, 0x0f, 0x6a, 0x11, 0x0f, 0x35, 0x1a, 0x00, 0xe5, 0x39, 0xdc, 0x1b, 0xbe, 0x03, 0x6d, 0xc7, + 0x5b, 0x90, 0xad, 0xb9, 0xa8, 0x19, 0xaa, 0x14, 0x10, 0xe5, 0x6d, 0x3b, 0x8e, 0xa8, 0x53, 0xbb, + 0xf7, 0x25, 0x02, 0x12, 0x91, 0x35, 0x12, 0x49, 0x64, 0xda, 0x22, 0xd1, 0xb9, 0xfd, 0x99, 0xae, + 0xa7, 0x82, 0x05, 0xea, 0x7a, 0xb3, 0x7e, 0x61, 0x7b, 0x85, 0xd7, 0xb5, 0xcd, 0xb7, 0x69, 0x03, + 0x4e, 0x61, 0x92, 0x1d, 0x10, 0x7d, 0x1f, 0x0f, 0xc4, 0x86, 0x40, 0xd2, 0x5c, 0x0b, 0xbe, 0x71, + 0x87, 0x71, 0x37, 0x6a, 0xb9, 0x7e, 0x38, 0x52, 0x40, 0x77, 0x6a, 0x27, 0x7f, 0x46, 0xc0, 0x33, + 0x69, 0xa9, 0x66, 0x3c, 0x33, 0x1d, 0xe0, 0xd9, 0xb9, 0x5d, 0x3e, 0x8e, 0xf7, 0x87, 0xbb, 0x25, + 0x66, 0xab, 0xe4, 0xad, 0x5d, 0x80, 0xa6, 0x03, 0x26, 0xcf, 0xae, 0x5f, 0xf7, 0xeb, 0xf9, 0x76, + 0xdb, 0x00, 0x13, 0x0f, 0x46, 0x97, 0x06, 0xd5, 0x6e, 0xe0, 0x7e, 0x31, 0xb7, 0x4a, 0x96, 0xff, + 0xa2, 0x49, 0x21, 0xe2, 0x40, 0xfd, 0x10, 0x38, 0xe6, 0x6d, 0xfb, 0x59, 0x64, 0xe4, 0xaf, 0x11, + 0x10, 0xa9, 0xf9, 0x4f, 0x25, 0x92, 0xd9, 0x16, 0x91, 0xce, 0xed, 0xfa, 0x75, 0x28, 0xa4, 0x16, + 0x2c, 0x97, 0x6b, 0xbf, 0x68, 0x38, 0xa5, 0x7a, 0xfb, 0xd8, 0xac, 0x1c, 0x1d, 0xc4, 0x3d, 0xb6, + 0xb5, 0x62, 0x79, 0x7c, 0xf5, 0x3d, 0x85, 0xe0, 0x41, 0xbd, 0x1f, 0x56, 0x4c, 0x0d, 0x0e, 0x9f, + 0x95, 0x14, 0x2a, 0xee, 0xf7, 0x98, 0x47, 0x6d, 0x58, 0x08, 0x22, 0x2b, 0xf2, 0xae, 0xd6, 0x23, + 0xfb, 0x87, 0xc7, 0xef, 0x66, 0x23, 0x89, 0x40, 0x3d, 0x13, 0x6a, 0x10, 0x1b, 0x05, 0xc4, 0x07, + 0xf0, 0x4e, 0x21, 0x35, 0x65, 0x0a, 0xf0, 0xa4, 0x2e, 0x01, 0xd3, 0x39, 0xe6, 0xdc, 0x31, 0x2a, + 0xfe, 0x97, 0x68, 0x89, 0xf9, 0xe6, 0x0d, 0xa7, 0xa0, 0x41, 0x3a, 0x05, 0xf7, 0x9a, 0xd4, 0x5d, + 0xa8, 0xa9, 0xb7, 0xbb, 0x50, 0x7b, 0x56, 0x3f, 0x47, 0x50, 0x3f, 0x34, 0xba, 0x05, 0x3c, 0xaf, + 0xe1, 0x7d, 0xac, 0xea, 0x2d, 0xb3, 0xaa, 0x53, 0x9a, 0xa7, 0xee, 0x55, 0xc7, 0x1f, 0x0c, 0x3b, + 0xf6, 0x86, 0x01, 0x7f, 0x36, 0xbf, 0x27, 0xd0, 0x99, 0x7d, 0xd9, 0x30, 0x60, 0x76, 0xb0, 0x68, + 0xe3, 0x00, 0x99, 0xc0, 0x03, 0xfe, 0x5f, 0x31, 0x4f, 0x65, 0xb8, 0x9e, 0xf1, 0xd7, 0xea, 0x38, + 0x3e, 0xc2, 0x61, 0x5e, 0x33, 0x5c, 0x97, 0x9a, 0xc6, 0x22, 0x75, 0x5d, 0xcb, 0x31, 0x17, 0xeb, + 0x1e, 0x43, 0x75, 0x2f, 0xe3, 0xa3, 0xad, 0x26, 0x02, 0xb1, 0x61, 0xbc, 0xfb, 0xa3, 0x1a, 0xc4, + 0x80, 0x50, 0xfd, 0xc5, 0xd4, 0x7f, 0x23, 0xb8, 0x87, 0x3b, 0x22, 0x0f, 0x11, 0xee, 0x17, 0xfb, + 0x36, 0x72, 0xbe, 0x45, 0xf4, 0x34, 0xb9, 0xb2, 0x50, 0x2e, 0xb4, 0x65, 0x1b, 0x20, 0x56, 0x2f, + 0xde, 0xfb, 0xed, 0xdf, 0xfb, 0xdd, 0x67, 0xc9, 0x19, 0xcd, 0x37, 0x9d, 0x14, 0xee, 0x9f, 0x6a, + 0x97, 0x3c, 0x35, 0x23, 0x6d, 0x03, 0x92, 0xe0, 0xa6, 0xb6, 0xc1, 0xd3, 0xde, 0x26, 0xf9, 0x0e, + 0xe1, 0x01, 0xd1, 0x6f, 0xde, 0xb6, 0xe5, 0xb8, 0x24, 0x5f, 0x5c, 0xc8, 0x71, 0x49, 0xb9, 0x8c, + 0x50, 0x8f, 0x73, 0x2e, 0x47, 0xc8, 0x98, 0x04, 0x17, 0xf2, 0x17, 0xc2, 0x07, 0x62, 0xc8, 0xa1, + 0x7f, 0x24, 0xf9, 0x36, 0x40, 0x44, 0x9b, 0x60, 0x65, 0x76, 0x3b, 0x2e, 0x80, 0xce, 0x79, 0x4e, + 0xe7, 0x34, 0x99, 0x92, 0xa0, 0x03, 0xb6, 0xb0, 0x43, 0x9b, 0xe4, 0x4f, 0x84, 0x5f, 0x14, 0x9a, + 0x34, 0x81, 0xdc, 0x9b, 0x92, 0xc8, 0x52, 0x1b, 0x7c, 0x25, 0xbf, 0x0d, 0x0f, 0x40, 0x6d, 0x86, + 0x53, 0x9b, 0x26, 0xa7, 0x53, 0xa8, 0x59, 0x4e, 0x0a, 0xb3, 0xa2, 0x55, 0xda, 0x24, 0xdf, 0x22, + 0xbc, 0x37, 0x4a, 0x4e, 0x3a, 0xe6, 0x12, 0x5a, 0x6d, 0xe9, 0x98, 0x4b, 0x6a, 0x9f, 0x5b, 0xc6, + 0x9c, 0xc0, 0xc4, 0x25, 0xbf, 0x02, 0x70, 0xa1, 0x05, 0x99, 0x91, 0x3c, 0xbc, 0x89, 0x8d, 0x98, + 0x72, 0xb1, 0x4d, 0x6b, 0x00, 0xff, 0x3a, 0x07, 0x3f, 0x45, 0x4e, 0x34, 0x01, 0x5f, 0x37, 0xd3, + 0x36, 0xc2, 0xe7, 0x4d, 0xf2, 0x3b, 0xc2, 0xa4, 0xb1, 0x35, 0x25, 0x52, 0x78, 0x52, 0x1b, 0x62, + 0xe5, 0x8d, 0x76, 0xcd, 0x81, 0x4f, 0x9e, 0xf3, 0xb9, 0x40, 0xce, 0xa5, 0xf2, 0x89, 0x5f, 0x8d, + 0x17, 0x4b, 0xd4, 0xa3, 0x22, 0xb1, 0x1f, 0x10, 0xde, 0x17, 0x5d, 0xc1, 0x0f, 0xaf, 0x99, 0x2d, + 0x84, 0x48, 0x9b, 0xbb, 0x94, 0xda, 0x02, 0xab, 0x93, 0x9c, 0xd5, 0x38, 0x39, 0x22, 0xb5, 0x4b, + 0xe4, 0x2b, 0x54, 0x6f, 0xbd, 0xc8, 0xb4, 0x64, 0x80, 0xc4, 0x7a, 0x44, 0xe5, 0xec, 0x96, 0xed, + 0x00, 0xac, 0xc6, 0xc1, 0xbe, 0x4a, 0xc6, 0x53, 0xc0, 0x9a, 0x60, 0xe0, 0x6b, 0x5e, 0x32, 0xd6, + 0x36, 0xc9, 0x17, 0x08, 0xf7, 0x85, 0x5e, 0x7c, 0xa9, 0xa7, 0x25, 0xc5, 0x6a, 0x0b, 0x71, 0x42, + 0xa7, 0xaa, 0x8e, 0x73, 0xc4, 0x87, 0xc9, 0x68, 0x0b, 0xc4, 0xe4, 0x01, 0xc2, 0x2f, 0xc4, 0x4b, + 0x1a, 0x22, 0x95, 0x3c, 0x52, 0xea, 0x2b, 0x65, 0xa6, 0x3d, 0x63, 0x49, 0xa9, 0xf5, 0x38, 0xd6, + 0x87, 0x08, 0xf7, 0x09, 0x55, 0x0b, 0xb9, 0x24, 0xb3, 0x7c, 0xab, 0xea, 0x48, 0x79, 0x6b, 0x9b, + 0x5e, 0x80, 0xcd, 0x31, 0xce, 0xe6, 0x15, 0xa2, 0xa6, 0xb0, 0x11, 0x2a, 0x3d, 0xf2, 0x08, 0x35, + 0x34, 0xa3, 0x44, 0x36, 0x15, 0x26, 0xb7, 0xd2, 0x72, 0xa9, 0x27, 0xfd, 0x1a, 0x40, 0x9d, 0xe6, + 0xf0, 0x4f, 0x90, 0x5c, 0x0a, 0x7c, 0x3b, 0x6a, 0x57, 0x0b, 0xff, 0x9f, 0x10, 0x26, 0x31, 0x9f, + 0xfe, 0x29, 0x90, 0x4d, 0x19, 0xdb, 0x61, 0x93, 0xde, 0xec, 0xab, 0x39, 0xce, 0x66, 0x82, 0x1c, + 0x95, 0x63, 0x43, 0x3e, 0x43, 0x78, 0x07, 0x4f, 0x3e, 0x53, 0x92, 0x32, 0x8a, 0xe9, 0xf1, 0xd4, + 0x96, 0x6c, 0x24, 0xbf, 0xbb, 0x3a, 0x7c, 0xb0, 0xb8, 0xc8, 0xdf, 0x20, 0xdc, 0x27, 0x34, 0xf9, + 0xe4, 0xdc, 0x16, 0x56, 0x8c, 0x5e, 0x0c, 0xb4, 0x07, 0xf6, 0x0c, 0x07, 0xab, 0x91, 0xc9, 0xa6, + 0x60, 0x1b, 0x8a, 0xeb, 0x4f, 0x11, 0xde, 0x15, 0x7e, 0x81, 0xa6, 0x24, 0x77, 0x74, 0xcb, 0xc2, + 0xc6, 0x1a, 0x7d, 0x75, 0x8c, 0x63, 0x1d, 0x21, 0x07, 0x9b, 0x60, 0xf5, 0x2b, 0xb0, 0x01, 0xdf, + 0xca, 0x6f, 0x91, 0xa1, 0x43, 0x95, 0x2b, 0xc1, 0x92, 0x9b, 0x74, 0xb9, 0x12, 0x2c, 0xa5, 0x1f, + 0x6f, 0x99, 0x39, 0xf4, 0xba, 0x0d, 0x2f, 0x1d, 0xa3, 0xff, 0x48, 0x96, 0x0b, 0x86, 0xc4, 0x7f, + 0x4d, 0x2b, 0xe7, 0xdb, 0x31, 0x95, 0xfc, 0xaa, 0xdf, 0x8d, 0xa2, 0xf4, 0x81, 0x47, 0xbb, 0x7b, + 0x39, 0xe0, 0x89, 0xf7, 0x05, 0x72, 0xc0, 0x93, 0x2f, 0x13, 0x5a, 0x02, 0xb7, 0x23, 0x66, 0xb3, + 0x6f, 0x3f, 0x7a, 0x92, 0x45, 0x8f, 0x9f, 0x64, 0xd1, 0x3f, 0x4f, 0xb2, 0xe8, 0x93, 0xa7, 0xd9, + 0xae, 0xc7, 0x4f, 0xb3, 0x5d, 0x7f, 0x3c, 0xcd, 0x76, 0xdd, 0x3c, 0x69, 0x5a, 0x5e, 0xb9, 0xba, + 0x9c, 0xd3, 0xd9, 0x8a, 0xe8, 0x2a, 0xc4, 0xa3, 0xad, 0x89, 0x5e, 0xbd, 0xf5, 0x55, 0xc3, 0x5d, + 0xde, 0xc9, 0xbf, 0x02, 0xa7, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xda, 0xf6, 0xfb, 0xb3, 0x90, + 0x21, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2118,8 +2029,6 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - // Parameters queries the parameters of the module. - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // Queries a OutTxTracker by index. OutTxTracker(ctx context.Context, in *QueryGetOutTxTrackerRequest, opts ...grpc.CallOption) (*QueryGetOutTxTrackerResponse, error) // Queries a list of OutTxTracker items. @@ -2164,15 +2073,6 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/Params", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *queryClient) OutTxTracker(ctx context.Context, in *QueryGetOutTxTrackerRequest, opts ...grpc.CallOption) (*QueryGetOutTxTrackerResponse, error) { out := new(QueryGetOutTxTrackerResponse) err := c.cc.Invoke(ctx, "/zetachain.zetacore.crosschain.Query/OutTxTracker", in, out, opts...) @@ -2355,8 +2255,6 @@ func (c *queryClient) LastZetaHeight(ctx context.Context, in *QueryLastZetaHeigh // QueryServer is the server API for Query service. type QueryServer interface { - // Parameters queries the parameters of the module. - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) // Queries a OutTxTracker by index. OutTxTracker(context.Context, *QueryGetOutTxTrackerRequest) (*QueryGetOutTxTrackerResponse, error) // Queries a list of OutTxTracker items. @@ -2397,9 +2295,6 @@ type QueryServer interface { type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") -} func (*UnimplementedQueryServer) OutTxTracker(ctx context.Context, req *QueryGetOutTxTrackerRequest) (*QueryGetOutTxTrackerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method OutTxTracker not implemented") } @@ -2465,24 +2360,6 @@ func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/zetachain.zetacore.crosschain.Query/Params", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Query_OutTxTracker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryGetOutTxTrackerRequest) if err := dec(in); err != nil { @@ -2847,10 +2724,6 @@ var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.crosschain.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Params", - Handler: _Query_Params_Handler, - }, { MethodName: "OutTxTracker", Handler: _Query_OutTxTracker_Handler, @@ -2989,62 +2862,6 @@ func (m *QueryZetaAccountingResponse) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } -func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *QueryGetOutTxTrackerRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4440,26 +4257,6 @@ func (m *QueryZetaAccountingResponse) Size() (n int) { return n } -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} - func (m *QueryGetOutTxTrackerRequest) Size() (n int) { if m == nil { return 0 @@ -5143,139 +4940,6 @@ func (m *QueryZetaAccountingResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *QueryGetOutTxTrackerRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/crosschain/types/query.pb.gw.go b/x/crosschain/types/query.pb.gw.go index 3e7f8b97c6..6234a732ea 100644 --- a/x/crosschain/types/query.pb.gw.go +++ b/x/crosschain/types/query.pb.gw.go @@ -33,24 +33,6 @@ var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage var _ = metadata.Join -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryParamsRequest - var metadata runtime.ServerMetadata - - msg, err := server.Params(ctx, &protoReq) - return msg, metadata, err - -} - func request_Query_OutTxTracker_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryGetOutTxTrackerRequest var metadata runtime.ServerMetadata @@ -965,29 +947,6 @@ func local_request_Query_LastZetaHeight_0(ctx context.Context, marshaler runtime // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_Query_OutTxTracker_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1489,26 +1448,6 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_Query_OutTxTracker_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1913,8 +1852,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_OutTxTracker_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"zeta-chain", "crosschain", "outTxTracker", "chainID", "nonce"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_OutTxTrackerAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "crosschain", "outTxTracker"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1957,8 +1894,6 @@ var ( ) var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage - forward_Query_OutTxTracker_0 = runtime.ForwardResponseMessage forward_Query_OutTxTrackerAll_0 = runtime.ForwardResponseMessage diff --git a/x/crosschain/types/status.go b/x/crosschain/types/status.go index 729b0b9bcb..b1c6fcdffb 100644 --- a/x/crosschain/types/status.go +++ b/x/crosschain/types/status.go @@ -64,5 +64,4 @@ func stateTransitionMap() map[CctxStatus][]CctxStatus { CctxStatus_Reverted, } return stateTransitionMap - } diff --git a/x/crosschain/types/status_test.go b/x/crosschain/types/status_test.go index cadf64490e..ad5298d383 100644 --- a/x/crosschain/types/status_test.go +++ b/x/crosschain/types/status_test.go @@ -1,9 +1,11 @@ package types_test import ( + "fmt" "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -23,3 +25,76 @@ func TestStatus_AbortRefunded(t *testing.T) { require.Equal(t, status.LastUpdateTimestamp, timestamp) }) } + +func TestStatus_ValidateTransition(t *testing.T) { + tests := []struct { + name string + oldStatus types.CctxStatus + newStatus types.CctxStatus + expectedValid bool + }{ + {"Valid - PendingInbound to PendingOutbound", types.CctxStatus_PendingInbound, types.CctxStatus_PendingOutbound, true}, + {"Valid - PendingInbound to Aborted", types.CctxStatus_PendingInbound, types.CctxStatus_Aborted, true}, + {"Valid - PendingInbound to OutboundMined", types.CctxStatus_PendingInbound, types.CctxStatus_OutboundMined, true}, + {"Valid - PendingInbound to PendingRevert", types.CctxStatus_PendingInbound, types.CctxStatus_PendingRevert, true}, + + {"Valid - PendingOutbound to Aborted", types.CctxStatus_PendingOutbound, types.CctxStatus_Aborted, true}, + {"Valid - PendingOutbound to PendingRevert", types.CctxStatus_PendingOutbound, types.CctxStatus_PendingRevert, true}, + {"Valid - PendingOutbound to OutboundMined", types.CctxStatus_PendingOutbound, types.CctxStatus_OutboundMined, true}, + {"Valid - PendingOutbound to Reverted", types.CctxStatus_PendingOutbound, types.CctxStatus_Reverted, true}, + + {"Valid - PendingRevert to Aborted", types.CctxStatus_PendingRevert, types.CctxStatus_Aborted, true}, + {"Valid - PendingRevert to OutboundMined", types.CctxStatus_PendingRevert, types.CctxStatus_OutboundMined, true}, + {"Valid - PendingRevert to Reverted", types.CctxStatus_PendingRevert, types.CctxStatus_Reverted, true}, + + {"Invalid - PendingInbound to Reverted", types.CctxStatus_PendingInbound, types.CctxStatus_Reverted, false}, + {"Invalid - PendingInbound to PendingInbound", types.CctxStatus_PendingInbound, types.CctxStatus_PendingInbound, false}, + + {"Invalid - PendingOutbound to PendingInbound", types.CctxStatus_PendingOutbound, types.CctxStatus_PendingInbound, false}, + {"Invalid - PendingOutbound to PendingOutbound", types.CctxStatus_PendingOutbound, types.CctxStatus_PendingOutbound, false}, + + {"Invalid - PendingRevert to PendingInbound", types.CctxStatus_PendingRevert, types.CctxStatus_PendingInbound, false}, + {"Invalid - PendingRevert to PendingOutbound", types.CctxStatus_PendingRevert, types.CctxStatus_PendingOutbound, false}, + {"Invalid - PendingRevert to PendingRevert", types.CctxStatus_PendingRevert, types.CctxStatus_PendingRevert, false}, + + {"Invalid old status - CctxStatus_Aborted", types.CctxStatus_Aborted, types.CctxStatus_PendingRevert, false}, + {"Invalid old status - CctxStatus_Reverted", types.CctxStatus_Reverted, types.CctxStatus_PendingRevert, false}, + {"Invalid old status - CctxStatus_OutboundMined", types.CctxStatus_OutboundMined, types.CctxStatus_PendingRevert, false}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + m := types.Status{Status: tc.oldStatus} + valid := m.ValidateTransition(tc.newStatus) + if valid != tc.expectedValid { + t.Errorf("expected %v, got %v", tc.expectedValid, valid) + } + }) + } +} + +func TestStatus_ChangeStatus(t *testing.T) { + t.Run("should change status and msg if transition is valid", func(t *testing.T) { + s := types.Status{Status: types.CctxStatus_PendingInbound} + + s.ChangeStatus(types.CctxStatus_PendingOutbound, "msg") + assert.Equal(t, s.Status, types.CctxStatus_PendingOutbound) + assert.Equal(t, s.StatusMessage, "msg") + }) + + t.Run("should change status if transition is valid", func(t *testing.T) { + s := types.Status{Status: types.CctxStatus_PendingInbound} + + s.ChangeStatus(types.CctxStatus_PendingOutbound, "") + assert.Equal(t, s.Status, types.CctxStatus_PendingOutbound) + assert.Equal(t, s.StatusMessage, "") + }) + + t.Run("should change status to aborted and msg if transition is invalid", func(t *testing.T) { + s := types.Status{Status: types.CctxStatus_PendingOutbound} + + s.ChangeStatus(types.CctxStatus_PendingInbound, "msg") + assert.Equal(t, s.Status, types.CctxStatus_Aborted) + assert.Equal(t, fmt.Sprintf("Failed to transition : OldStatus %s , NewStatus %s , MSG : %s :", types.CctxStatus_PendingOutbound.String(), types.CctxStatus_PendingInbound.String(), "msg"), s.StatusMessage) + }) +} From fca927f538cf4cd89e74db57a262f7b8ab5a91af Mon Sep 17 00:00:00 2001 From: skosito Date: Wed, 3 Apr 2024 18:33:36 +0100 Subject: [PATCH 2/2] test: improve observer module coverage (#1961) --- changelog.md | 1 + proto/observer/ballot.proto | 1 + testutil/keeper/mocks/observer/staking.go | 5 + typescript/observer/ballot_pb.d.ts | 2 + x/observer/abci.go | 4 - x/observer/abci_test.go | 98 ++++++++ x/observer/genesis.go | 2 +- x/observer/genesis_test.go | 188 ++++++++++---- x/observer/keeper/ballot_test.go | 161 +++++++++++- x/observer/keeper/blame_test.go | 110 +++++++++ x/observer/keeper/block_header_test.go | 32 +++ x/observer/keeper/chain_params_test.go | 30 ++- x/observer/keeper/crosschain_flags_test.go | 83 +++++++ x/observer/keeper/grpc_query_ballot_test.go | 136 +++++++++++ x/observer/keeper/grpc_query_blame_test.go | 180 ++++++++------ .../keeper/grpc_query_block_header_test.go | 119 +++++++++ .../keeper/grpc_query_chain_params_test.go | 97 ++++++++ .../grpc_query_crosschain_flags_test.go | 47 ++++ x/observer/keeper/grpc_query_keygen_test.go | 53 ++-- .../keeper/grpc_query_node_account_test.go | 22 +- x/observer/keeper/grpc_query_nonces_test.go | 81 ++++++ x/observer/keeper/grpc_query_observer_test.go | 78 ++++++ x/observer/keeper/grpc_query_params_test.go | 9 +- x/observer/keeper/grpc_query_prove_test.go | 72 ++++++ .../keeper/grpc_query_supported_chain_test.go | 21 ++ x/observer/keeper/grpc_query_tss_test.go | 230 ++++++++++++++++++ x/observer/keeper/hooks_test.go | 213 ++++++++++++++++ x/observer/keeper/keeper_test.go | 53 ---- x/observer/keeper/keygen_test.go | 20 +- .../keeper/msg_server_add_blame_vote_test.go | 182 ++++++++++++++ .../keeper/msg_server_add_observer_test.go | 117 +++++++++ .../keeper/msg_server_update_keygen_test.go | 105 ++++++++ x/observer/keeper/node_account_test.go | 28 ++- x/observer/keeper/nonce_to_cctx_test.go | 8 + x/observer/keeper/observer_set_test.go | 35 ++- x/observer/keeper/params_test.go | 6 +- x/observer/keeper/pending_nonces_test.go | 69 ++++++ x/observer/keeper/tss_funds_migrator_test.go | 7 +- x/observer/keeper/tss_test.go | 112 ++------- x/observer/keeper/utils.go | 3 +- x/observer/keeper/utils_test.go | 202 ++++++++++++++- x/observer/keeper/vote_inbound_test.go | 51 ++++ x/observer/keeper/vote_outbound_test.go | 42 ++++ x/observer/types/ballot.go | 6 + x/observer/types/ballot.pb.go | 1 + x/observer/types/ballot_test.go | 19 +- x/observer/types/chain_params_test.go | 20 ++ x/observer/types/crosschain_flags_test.go | 19 ++ x/observer/types/expected_keepers.go | 1 + x/observer/types/genesis_test.go | 19 ++ x/observer/types/observer_set_test.go | 32 +++ x/observer/types/params.go | 10 +- x/observer/types/params_test.go | 74 ++++++ x/observer/types/parsers_test.go | 98 ++++++++ x/observer/types/test_data.go | 27 -- x/observer/types/utils_test.go | 55 +++++ 56 files changed, 3112 insertions(+), 384 deletions(-) create mode 100644 x/observer/abci_test.go create mode 100644 x/observer/keeper/blame_test.go create mode 100644 x/observer/keeper/block_header_test.go create mode 100644 x/observer/keeper/crosschain_flags_test.go create mode 100644 x/observer/keeper/grpc_query_ballot_test.go create mode 100644 x/observer/keeper/grpc_query_block_header_test.go create mode 100644 x/observer/keeper/grpc_query_chain_params_test.go create mode 100644 x/observer/keeper/grpc_query_crosschain_flags_test.go create mode 100644 x/observer/keeper/grpc_query_observer_test.go create mode 100644 x/observer/keeper/grpc_query_prove_test.go create mode 100644 x/observer/keeper/grpc_query_supported_chain_test.go create mode 100644 x/observer/keeper/grpc_query_tss_test.go create mode 100644 x/observer/keeper/hooks_test.go delete mode 100644 x/observer/keeper/keeper_test.go create mode 100644 x/observer/keeper/msg_server_add_blame_vote_test.go create mode 100644 x/observer/keeper/msg_server_add_observer_test.go create mode 100644 x/observer/keeper/msg_server_update_keygen_test.go create mode 100644 x/observer/types/crosschain_flags_test.go create mode 100644 x/observer/types/observer_set_test.go create mode 100644 x/observer/types/params_test.go create mode 100644 x/observer/types/parsers_test.go delete mode 100644 x/observer/types/test_data.go create mode 100644 x/observer/types/utils_test.go diff --git a/changelog.md b/changelog.md index 8fe144056a..bc3070f7e1 100644 --- a/changelog.md +++ b/changelog.md @@ -51,6 +51,7 @@ * [1879](https://github.com/zeta-chain/node/pull/1879) - full coverage for messages in types packages * [1899](https://github.com/zeta-chain/node/pull/1899) - add empty test files so packages are included in coverage * [1903](https://github.com/zeta-chain/node/pull/1903) - common package tests +* [1961](https://github.com/zeta-chain/node/pull/1961) - improve observer module coverage * [1967](https://github.com/zeta-chain/node/pull/1967) - improve crosschain module coverage * [1955](https://github.com/zeta-chain/node/pull/1955) - improve emissions module coverage diff --git a/proto/observer/ballot.proto b/proto/observer/ballot.proto index c89b50bb83..aa871cff35 100644 --- a/proto/observer/ballot.proto +++ b/proto/observer/ballot.proto @@ -20,6 +20,7 @@ enum BallotStatus { BallotInProgress = 2; } +// https://github.com/zeta-chain/node/issues/939 message Ballot { string index = 1; string ballot_identifier = 2; diff --git a/testutil/keeper/mocks/observer/staking.go b/testutil/keeper/mocks/observer/staking.go index 90007b6c35..72bf99599f 100644 --- a/testutil/keeper/mocks/observer/staking.go +++ b/testutil/keeper/mocks/observer/staking.go @@ -71,6 +71,11 @@ func (_m *ObserverStakingKeeper) GetValidator(ctx types.Context, addr types.ValA return r0, r1 } +// SetDelegation provides a mock function with given fields: ctx, delegation +func (_m *ObserverStakingKeeper) SetDelegation(ctx types.Context, delegation stakingtypes.Delegation) { + _m.Called(ctx, delegation) +} + // SetValidator provides a mock function with given fields: ctx, validator func (_m *ObserverStakingKeeper) SetValidator(ctx types.Context, validator stakingtypes.Validator) { _m.Called(ctx, validator) diff --git a/typescript/observer/ballot_pb.d.ts b/typescript/observer/ballot_pb.d.ts index 100a1a0f1d..1eb7d2f01d 100644 --- a/typescript/observer/ballot_pb.d.ts +++ b/typescript/observer/ballot_pb.d.ts @@ -50,6 +50,8 @@ export declare enum BallotStatus { } /** + * https://github.com/zeta-chain/node/issues/939 + * * @generated from message zetachain.zetacore.observer.Ballot */ export declare class Ballot extends Message { diff --git a/x/observer/abci.go b/x/observer/abci.go index f219bb833d..41121ced19 100644 --- a/x/observer/abci.go +++ b/x/observer/abci.go @@ -21,10 +21,6 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { return } totalObserverCountCurrentBlock := allObservers.LenUint() - if totalObserverCountCurrentBlock < 0 { - ctx.Logger().Error("TotalObserverCount is negative at height", ctx.BlockHeight()) - return - } // #nosec G701 always in range if totalObserverCountCurrentBlock == lastBlockObserverCount.Count { return diff --git a/x/observer/abci_test.go b/x/observer/abci_test.go new file mode 100644 index 0000000000..02a161d6b6 --- /dev/null +++ b/x/observer/abci_test.go @@ -0,0 +1,98 @@ +package observer_test + +import ( + "math" + "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/observer" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestBeginBlocker(t *testing.T) { + t.Run("should not update LastObserverCount if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + observer.BeginBlocker(ctx, *k) + + _, found := k.GetLastObserverCount(ctx) + require.False(t, found) + + _, found = k.GetKeygen(ctx) + require.False(t, found) + }) + + t.Run("should not update LastObserverCount if observer set not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + count := 1 + k.SetLastObserverCount(ctx, &types.LastObserverCount{ + Count: uint64(count), + }) + + observer.BeginBlocker(ctx, *k) + + lastObserverCount, found := k.GetLastObserverCount(ctx) + require.True(t, found) + require.Equal(t, uint64(count), lastObserverCount.Count) + require.Equal(t, int64(0), lastObserverCount.LastChangeHeight) + + _, found = k.GetKeygen(ctx) + require.False(t, found) + }) + + t.Run("should not update LastObserverCount if observer set count equal last observed count", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + count := 1 + os := sample.ObserverSet(count) + k.SetObserverSet(ctx, os) + k.SetLastObserverCount(ctx, &types.LastObserverCount{ + Count: uint64(count), + }) + + observer.BeginBlocker(ctx, *k) + + lastObserverCount, found := k.GetLastObserverCount(ctx) + require.True(t, found) + require.Equal(t, uint64(count), lastObserverCount.Count) + require.Equal(t, int64(0), lastObserverCount.LastChangeHeight) + + _, found = k.GetKeygen(ctx) + require.False(t, found) + }) + + t.Run("should update LastObserverCount", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + observeSetLen := 10 + count := 1 + os := sample.ObserverSet(observeSetLen) + k.SetObserverSet(ctx, os) + k.SetLastObserverCount(ctx, &types.LastObserverCount{ + Count: uint64(count), + }) + + keygen, found := k.GetKeygen(ctx) + require.False(t, found) + require.Equal(t, types.Keygen{}, keygen) + + observer.BeginBlocker(ctx, *k) + + keygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.Empty(t, keygen.GranteePubkeys) + require.Equal(t, types.KeygenStatus_PendingKeygen, keygen.Status) + require.Equal(t, int64(math.MaxInt64), keygen.BlockNumber) + + inboundEnabled := k.IsInboundEnabled(ctx) + require.False(t, inboundEnabled) + + lastObserverCount, found := k.GetLastObserverCount(ctx) + require.True(t, found) + require.Equal(t, uint64(observeSetLen), lastObserverCount.Count) + require.Equal(t, ctx.BlockHeight(), lastObserverCount.LastChangeHeight) + }) +} diff --git a/x/observer/genesis.go b/x/observer/genesis.go index 7e3ff44311..b6d85757ff 100644 --- a/x/observer/genesis.go +++ b/x/observer/genesis.go @@ -16,7 +16,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) observerCount = uint64(len(genState.Observers.ObserverList)) } - // if chian params are defined set them + // if chain params are defined set them if len(genState.ChainParamsList.ChainParams) > 0 { k.SetChainParamsList(ctx, genState.ChainParamsList) } else { diff --git a/x/observer/genesis_test.go b/x/observer/genesis_test.go index 7482f24f95..62e442e9ba 100644 --- a/x/observer/genesis_test.go +++ b/x/observer/genesis_test.go @@ -12,45 +12,151 @@ import ( ) func TestGenesis(t *testing.T) { - params := types.DefaultParams() - tss := sample.Tss() - genesisState := types.GenesisState{ - Params: ¶ms, - Tss: &tss, - BlameList: sample.BlameRecordsList(t, 10), - Ballots: []*types.Ballot{ - sample.Ballot(t, "0"), - sample.Ballot(t, "1"), - sample.Ballot(t, "2"), - }, - Observers: sample.ObserverSet(3), - NodeAccountList: []*types.NodeAccount{ - sample.NodeAccount(), - sample.NodeAccount(), - sample.NodeAccount(), - }, - CrosschainFlags: types.DefaultCrosschainFlags(), - Keygen: sample.Keygen(t), - ChainParamsList: sample.ChainParamsList(), - LastObserverCount: sample.LastObserverCount(10), - TssFundMigrators: []types.TssFundMigratorInfo{sample.TssFundsMigrator(1), sample.TssFundsMigrator(2)}, - ChainNonces: []types.ChainNonces{ - sample.ChainNonces(t, "0"), - sample.ChainNonces(t, "1"), - sample.ChainNonces(t, "2"), - }, - PendingNonces: sample.PendingNoncesList(t, "sample", 20), - NonceToCctx: sample.NonceToCctxList(t, "sample", 20), - } - - // Init and export - k, ctx, _, _ := keepertest.ObserverKeeper(t) - observer.InitGenesis(ctx, *k, genesisState) - got := observer.ExportGenesis(ctx, *k) - require.NotNil(t, got) - - // Compare genesis after init and export - nullify.Fill(&genesisState) - nullify.Fill(got) - require.Equal(t, genesisState, *got) + t.Run("genState fields defined", func(t *testing.T) { + params := types.DefaultParams() + tss := sample.Tss() + genesisState := types.GenesisState{ + Params: ¶ms, + Tss: &tss, + BlameList: sample.BlameRecordsList(t, 10), + Ballots: []*types.Ballot{ + sample.Ballot(t, "0"), + sample.Ballot(t, "1"), + sample.Ballot(t, "2"), + }, + Observers: sample.ObserverSet(3), + NodeAccountList: []*types.NodeAccount{ + sample.NodeAccount(), + sample.NodeAccount(), + sample.NodeAccount(), + }, + CrosschainFlags: types.DefaultCrosschainFlags(), + Keygen: sample.Keygen(t), + ChainParamsList: sample.ChainParamsList(), + LastObserverCount: sample.LastObserverCount(10), + TssFundMigrators: []types.TssFundMigratorInfo{sample.TssFundsMigrator(1), sample.TssFundsMigrator(2)}, + ChainNonces: []types.ChainNonces{ + sample.ChainNonces(t, "0"), + sample.ChainNonces(t, "1"), + sample.ChainNonces(t, "2"), + }, + PendingNonces: sample.PendingNoncesList(t, "sample", 20), + NonceToCctx: sample.NonceToCctxList(t, "sample", 20), + TssHistory: []types.TSS{sample.Tss()}, + } + + // Init and export + k, ctx, _, _ := keepertest.ObserverKeeper(t) + observer.InitGenesis(ctx, *k, genesisState) + got := observer.ExportGenesis(ctx, *k) + require.NotNil(t, got) + + // Compare genesis after init and export + nullify.Fill(&genesisState) + nullify.Fill(got) + require.Equal(t, genesisState, *got) + }) + + t.Run("genState fields not defined", func(t *testing.T) { + genesisState := types.GenesisState{} + + k, ctx, _, _ := keepertest.ObserverKeeper(t) + observer.InitGenesis(ctx, *k, genesisState) + got := observer.ExportGenesis(ctx, *k) + require.NotNil(t, got) + + defaultParams := types.DefaultParams() + btcChainParams := types.GetDefaultBtcRegtestChainParams() + btcChainParams.IsSupported = true + goerliChainParams := types.GetDefaultGoerliLocalnetChainParams() + goerliChainParams.IsSupported = true + zetaPrivnetChainParams := types.GetDefaultZetaPrivnetChainParams() + zetaPrivnetChainParams.IsSupported = true + localnetChainParams := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + btcChainParams, + goerliChainParams, + zetaPrivnetChainParams, + }, + } + expectedGenesisState := types.GenesisState{ + Params: &defaultParams, + CrosschainFlags: types.DefaultCrosschainFlags(), + ChainParamsList: localnetChainParams, + Tss: &types.TSS{}, + Keygen: &types.Keygen{}, + LastObserverCount: &types.LastObserverCount{}, + NodeAccountList: []*types.NodeAccount{}, + } + + require.Equal(t, expectedGenesisState, *got) + }) + + t.Run("genState fields not defined except tss", func(t *testing.T) { + tss := sample.Tss() + genesisState := types.GenesisState{ + Tss: &tss, + } + + k, ctx, _, _ := keepertest.ObserverKeeper(t) + observer.InitGenesis(ctx, *k, genesisState) + got := observer.ExportGenesis(ctx, *k) + require.NotNil(t, got) + + defaultParams := types.DefaultParams() + btcChainParams := types.GetDefaultBtcRegtestChainParams() + btcChainParams.IsSupported = true + goerliChainParams := types.GetDefaultGoerliLocalnetChainParams() + goerliChainParams.IsSupported = true + zetaPrivnetChainParams := types.GetDefaultZetaPrivnetChainParams() + zetaPrivnetChainParams.IsSupported = true + localnetChainParams := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + btcChainParams, + goerliChainParams, + zetaPrivnetChainParams, + }, + } + pendingNonces, err := k.GetAllPendingNonces(ctx) + require.NoError(t, err) + require.NotEmpty(t, pendingNonces) + expectedGenesisState := types.GenesisState{ + Params: &defaultParams, + CrosschainFlags: types.DefaultCrosschainFlags(), + ChainParamsList: localnetChainParams, + Tss: &tss, + Keygen: &types.Keygen{}, + LastObserverCount: &types.LastObserverCount{}, + NodeAccountList: []*types.NodeAccount{}, + PendingNonces: pendingNonces, + } + + require.Equal(t, expectedGenesisState, *got) + }) + + t.Run("export without init", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + got := observer.ExportGenesis(ctx, *k) + require.NotNil(t, got) + + params := k.GetParamsIfExists(ctx) + expectedGenesisState := types.GenesisState{ + Params: ¶ms, + CrosschainFlags: types.DefaultCrosschainFlags(), + ChainParamsList: types.ChainParamsList{}, + Tss: &types.TSS{}, + Keygen: &types.Keygen{}, + LastObserverCount: &types.LastObserverCount{}, + NodeAccountList: []*types.NodeAccount{}, + Ballots: k.GetAllBallots(ctx), + TssHistory: k.GetAllTSS(ctx), + TssFundMigrators: k.GetAllTssFundMigrators(ctx), + BlameList: k.GetAllBlame(ctx), + ChainNonces: k.GetAllChainNonces(ctx), + NonceToCctx: k.GetAllNonceToCctx(ctx), + } + + require.Equal(t, expectedGenesisState, *got) + }) } diff --git a/x/observer/keeper/ballot_test.go b/x/observer/keeper/ballot_test.go index 13415cdaac..8d71aaa720 100644 --- a/x/observer/keeper/ballot_test.go +++ b/x/observer/keeper/ballot_test.go @@ -1,23 +1,162 @@ -package keeper +package keeper_test import ( + "math" "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "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/observer/types" ) func TestKeeper_GetBallot(t *testing.T) { - k, ctx := SetupKeeper(t) - identifier := "0x9ea007f0f60e32d58577a8cf25678942d2b10791c2a34f48e237b76a7e998e4d" - k.SetBallot(ctx, &types.Ballot{ - Index: "", - BallotIdentifier: identifier, - VoterList: nil, - ObservationType: 0, - BallotThreshold: sdk.Dec{}, - BallotStatus: 0, + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "123", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + _, found := k.GetBallot(ctx, identifier) + require.False(t, found) + + k.SetBallot(ctx, b) + + ballot, found := k.GetBallot(ctx, identifier) + require.True(t, found) + require.Equal(t, *b, ballot) + + // overwrite existing ballot + b = &types.Ballot{ + Index: "123", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 1, + BallotThreshold: sdk.Dec{}, + BallotStatus: 1, + BallotCreationHeight: 2, + } + _, found = k.GetBallot(ctx, identifier) + require.True(t, found) + + k.SetBallot(ctx, b) + + ballot, found = k.GetBallot(ctx, identifier) + require.True(t, found) + require.Equal(t, *b, ballot) +} + +func TestKeeper_GetBallotList(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + _, found := k.GetBallotList(ctx, 1) + require.False(t, found) + + k.AddBallotToList(ctx, *b) + list, found := k.GetBallotList(ctx, 1) + require.True(t, found) + require.Equal(t, 1, len(list.BallotsIndexList)) + require.Equal(t, identifier, list.BallotsIndexList[0]) +} + +func TestKeeper_GetAllBallots(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + ballots := k.GetAllBallots(ctx) + require.Empty(t, ballots) + + k.SetBallot(ctx, b) + ballots = k.GetAllBallots(ctx) + require.Equal(t, 1, len(ballots)) + require.Equal(t, b, ballots[0]) +} + +func TestKeeper_GetMaturedBallotList(t *testing.T) { + t.Run("should return if maturity blocks less than height", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + list := k.GetMaturedBallotList(ctx) + require.Empty(t, list) + ctx = ctx.WithBlockHeight(101) + k.AddBallotToList(ctx, *b) + list = k.GetMaturedBallotList(ctx) + require.Equal(t, 1, len(list)) + require.Equal(t, identifier, list[0]) + }) + + t.Run("should return empty for max maturity blocks", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + k.SetParams(ctx, types.Params{ + BallotMaturityBlocks: math.MaxInt64, + }) + list := k.GetMaturedBallotList(ctx) + require.Empty(t, list) + k.AddBallotToList(ctx, *b) + list = k.GetMaturedBallotList(ctx) + require.Empty(t, list) }) - k.GetBallot(ctx, identifier) + t.Run("should return empty if maturity blocks greater than height", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.Dec{}, + BallotStatus: 0, + BallotCreationHeight: 1, + } + list := k.GetMaturedBallotList(ctx) + require.Empty(t, list) + ctx = ctx.WithBlockHeight(1) + k.AddBallotToList(ctx, *b) + list = k.GetMaturedBallotList(ctx) + require.Empty(t, list) + }) } diff --git a/x/observer/keeper/blame_test.go b/x/observer/keeper/blame_test.go new file mode 100644 index 0000000000..420e6f7d8f --- /dev/null +++ b/x/observer/keeper/blame_test.go @@ -0,0 +1,110 @@ +package keeper_test + +import ( + "sort" + "testing" + + "github.com/cosmos/cosmos-sdk/types/query" + "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/observer/types" +) + +func TestKeeper_GetBlame(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := sample.ZetaIndex(t) + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + + k.SetBlame(ctx, types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, + }) + + blameRecords, found := k.GetBlame(ctx, index) + require.True(t, found) + require.Equal(t, index, blameRecords.Index) +} + +func TestKeeper_GetBlameByChainAndNonce(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := sample.ZetaIndex(t) + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + + k.SetBlame(ctx, types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, + }) + + blameRecords, found := k.GetBlamesByChainAndNonce(ctx, chainId, int64(nonce)) + require.True(t, found) + require.Equal(t, 1, len(blameRecords)) + require.Equal(t, index, blameRecords[0].Index) +} + +func TestKeeper_BlameAll(t *testing.T) { + t.Run("GetBlameRecord by limit ", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + blameList := sample.BlameRecordsList(t, 10) + for _, record := range blameList { + k.SetBlame(ctx, record) + } + sort.Slice(blameList, func(i, j int) bool { + return blameList[i].Index < blameList[j].Index + }) + rst, pageRes, err := k.GetAllBlamePaginated(ctx, &query.PageRequest{Limit: 10, CountTotal: true}) + require.NoError(t, err) + sort.Slice(rst, func(i, j int) bool { + return rst[i].Index < rst[j].Index + }) + require.Equal(t, blameList, rst) + require.Equal(t, len(blameList), int(pageRes.Total)) + }) + t.Run("GetBlameRecord by offset ", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + blameList := sample.BlameRecordsList(t, 20) + offset := 10 + for _, record := range blameList { + k.SetBlame(ctx, record) + } + sort.Slice(blameList, func(i, j int) bool { + return blameList[i].Index < blameList[j].Index + }) + rst, pageRes, err := k.GetAllBlamePaginated(ctx, &query.PageRequest{Offset: uint64(offset), CountTotal: true}) + require.NoError(t, err) + sort.Slice(rst, func(i, j int) bool { + return rst[i].Index < rst[j].Index + }) + require.Subset(t, blameList, rst) + require.Equal(t, len(blameList)-offset, len(rst)) + require.Equal(t, len(blameList), int(pageRes.Total)) + }) + t.Run("GetAllBlameRecord", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + blameList := sample.BlameRecordsList(t, 100) + for _, record := range blameList { + k.SetBlame(ctx, record) + } + rst := k.GetAllBlame(ctx) + sort.Slice(rst, func(i, j int) bool { + return rst[i].Index < rst[j].Index + }) + sort.Slice(blameList, func(i, j int) bool { + return blameList[i].Index < blameList[j].Index + }) + require.Equal(t, blameList, rst) + }) + t.Run("Get no records if nothing is set", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + rst := k.GetAllBlame(ctx) + require.Len(t, rst, 0) + }) +} diff --git a/x/observer/keeper/block_header_test.go b/x/observer/keeper/block_header_test.go new file mode 100644 index 0000000000..5ab61ed20f --- /dev/null +++ b/x/observer/keeper/block_header_test.go @@ -0,0 +1,32 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/proofs" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" +) + +func TestKeeper_GetBlockHeader(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + blockHash := sample.Hash().Bytes() + _, found := k.GetBlockHeader(ctx, blockHash) + require.False(t, found) + + bh := proofs.BlockHeader{ + Height: 1, + Hash: blockHash, + ParentHash: sample.Hash().Bytes(), + ChainId: 1, + Header: proofs.HeaderData{}, + } + k.SetBlockHeader(ctx, bh) + _, found = k.GetBlockHeader(ctx, blockHash) + require.True(t, found) + + k.RemoveBlockHeader(ctx, blockHash) + _, found = k.GetBlockHeader(ctx, blockHash) + require.False(t, found) +} diff --git a/x/observer/keeper/chain_params_test.go b/x/observer/keeper/chain_params_test.go index 3464c950fa..84f28e5cff 100644 --- a/x/observer/keeper/chain_params_test.go +++ b/x/observer/keeper/chain_params_test.go @@ -23,7 +23,6 @@ func TestKeeper_GetSupportedChainFromChainID(t *testing.T) { // chain params list but chain not supported chainParams := sample.ChainParams(getValidEthChainIDWithIndex(t, 0)) - chainParams.IsSupported = false k.SetChainParamsList(ctx, types.ChainParamsList{ ChainParams: []*types.ChainParams{chainParams}, }) @@ -40,6 +39,35 @@ func TestKeeper_GetSupportedChainFromChainID(t *testing.T) { }) } +func TestKeeper_GetChainParamsByChainID(t *testing.T) { + t.Run("return false if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + _, found := k.GetChainParamsByChainID(ctx, getValidEthChainIDWithIndex(t, 0)) + require.False(t, found) + }) + + t.Run("return true if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainParams := sample.ChainParams(getValidEthChainIDWithIndex(t, 0)) + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{chainParams}, + }) + res, found := k.GetChainParamsByChainID(ctx, getValidEthChainIDWithIndex(t, 0)) + require.True(t, found) + require.Equal(t, chainParams, res) + }) + + t.Run("return false if chain not found in params", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainParams := sample.ChainParams(getValidEthChainIDWithIndex(t, 0)) + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{chainParams}, + }) + _, found := k.GetChainParamsByChainID(ctx, getValidEthChainIDWithIndex(t, 1)) + require.False(t, found) + }) +} func TestKeeper_GetSupportedChains(t *testing.T) { t.Run("return empty list if no core params list", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) diff --git a/x/observer/keeper/crosschain_flags_test.go b/x/observer/keeper/crosschain_flags_test.go new file mode 100644 index 0000000000..4d3f003b92 --- /dev/null +++ b/x/observer/keeper/crosschain_flags_test.go @@ -0,0 +1,83 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_IsInboundEnabled(t *testing.T) { + t.Run("should return false if flags not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + enabled := k.IsInboundEnabled(ctx) + require.False(t, enabled) + }) + + t.Run("should return if flags found and set", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsInboundEnabled: false, + }) + enabled := k.IsInboundEnabled(ctx) + require.False(t, enabled) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsInboundEnabled: true, + }) + + enabled = k.IsInboundEnabled(ctx) + require.True(t, enabled) + }) +} + +func TestKeeper_IsOutboundEnabled(t *testing.T) { + t.Run("should return false if flags not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + enabled := k.IsOutboundEnabled(ctx) + require.False(t, enabled) + }) + + t.Run("should return if flags found and set", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsOutboundEnabled: false, + }) + enabled := k.IsOutboundEnabled(ctx) + require.False(t, enabled) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsOutboundEnabled: true, + }) + + enabled = k.IsOutboundEnabled(ctx) + require.True(t, enabled) + }) +} + +func TestKeeper_DisableInboundOnly(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + k.DisableInboundOnly(ctx) + enabled := k.IsOutboundEnabled(ctx) + require.True(t, enabled) + + enabled = k.IsInboundEnabled(ctx) + require.False(t, enabled) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsOutboundEnabled: false, + }) + + k.DisableInboundOnly(ctx) + enabled = k.IsOutboundEnabled(ctx) + require.False(t, enabled) + + enabled = k.IsInboundEnabled(ctx) + require.False(t, enabled) +} diff --git a/x/observer/keeper/grpc_query_ballot_test.go b/x/observer/keeper/grpc_query_ballot_test.go new file mode 100644 index 0000000000..32bbe6265d --- /dev/null +++ b/x/observer/keeper/grpc_query_ballot_test.go @@ -0,0 +1,136 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "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/observer/types" +) + +func TestKeeper_HasVoted(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.HasVoted(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return false if ballot not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.HasVoted(wctx, &types.QueryHasVotedRequest{ + BallotIdentifier: "test", + }) + require.NoError(t, err) + require.Equal(t, &types.QueryHasVotedResponse{ + HasVoted: false, + }, res) + }) + + t.Run("should return true if ballot found and voted", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + voter := sample.AccAddress() + ballot := types.Ballot{ + Index: "index", + BallotIdentifier: "index", + VoterList: []string{voter}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + } + k.SetBallot(ctx, &ballot) + + res, err := k.HasVoted(wctx, &types.QueryHasVotedRequest{ + BallotIdentifier: "index", + VoterAddress: voter, + }) + require.NoError(t, err) + require.Equal(t, &types.QueryHasVotedResponse{ + HasVoted: true, + }, res) + }) + + t.Run("should return false if ballot found and not voted", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + voter := sample.AccAddress() + ballot := types.Ballot{ + Index: "index", + BallotIdentifier: "index", + VoterList: []string{voter}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + } + k.SetBallot(ctx, &ballot) + + res, err := k.HasVoted(wctx, &types.QueryHasVotedRequest{ + BallotIdentifier: "index", + VoterAddress: sample.AccAddress(), + }) + require.NoError(t, err) + require.Equal(t, &types.QueryHasVotedResponse{ + HasVoted: false, + }, res) + }) +} + +func TestKeeper_BallotByIdentifier(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.BallotByIdentifier(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return nil if ballot not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.BallotByIdentifier(wctx, &types.QueryBallotByIdentifierRequest{ + BallotIdentifier: "test", + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return ballot if exists", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + voter := sample.AccAddress() + ballot := types.Ballot{ + Index: "index", + BallotIdentifier: "index", + VoterList: []string{voter}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + } + k.SetBallot(ctx, &ballot) + + res, err := k.BallotByIdentifier(wctx, &types.QueryBallotByIdentifierRequest{ + BallotIdentifier: "index", + }) + require.NoError(t, err) + require.Equal(t, &types.QueryBallotByIdentifierResponse{ + BallotIdentifier: ballot.BallotIdentifier, + Voters: []*types.VoterList{ + { + VoterAddress: voter, + VoteType: types.VoteType_SuccessObservation, + }, + }, + ObservationType: ballot.ObservationType, + BallotStatus: ballot.BallotStatus, + }, res) + }) +} diff --git a/x/observer/keeper/grpc_query_blame_test.go b/x/observer/keeper/grpc_query_blame_test.go index 36d95ed23e..728d1748d0 100644 --- a/x/observer/keeper/grpc_query_blame_test.go +++ b/x/observer/keeper/grpc_query_blame_test.go @@ -1,10 +1,9 @@ package keeper_test import ( - "sort" "testing" - "github.com/cosmos/cosmos-sdk/types/query" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -12,99 +11,126 @@ import ( ) func TestKeeper_BlameByIdentifier(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - var chainId int64 = 97 - var nonce uint64 = 101 - digest := "85f5e10431f69bc2a14046a13aabaefc660103b6de7a84f75c4b96181d03f0b5" - - index := types.GetBlameIndex(chainId, nonce, digest, 123) + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) - k.SetBlame(ctx, types.Blame{ - Index: index, - FailureReason: "failed to join party", - Nodes: nil, + res, err := k.BlameByIdentifier(wctx, nil) + require.Nil(t, res) + require.Error(t, err) }) - blameRecords, found := k.GetBlame(ctx, index) - require.True(t, found) - require.Equal(t, index, blameRecords.Index) -} - -func TestKeeper_BlameByChainAndNonce(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - var chainId int64 = 97 - var nonce uint64 = 101 - digest := "85f5e10431f69bc2a14046a13aabaefc660103b6de7a84f75c4b96181d03f0b5" - - index := types.GetBlameIndex(chainId, nonce, digest, 123) + t.Run("should error if blame not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) - k.SetBlame(ctx, types.Blame{ - Index: index, - FailureReason: "failed to join party", - Nodes: nil, + res, err := k.BlameByIdentifier(wctx, &types.QueryBlameByIdentifierRequest{ + BlameIdentifier: "test", + }) + require.Error(t, err) + require.Nil(t, res) }) - blameRecords, found := k.GetBlamesByChainAndNonce(ctx, chainId, int64(nonce)) - require.True(t, found) - require.Equal(t, 1, len(blameRecords)) - require.Equal(t, index, blameRecords[0].Index) -} - -func TestKeeper_BlameAll(t *testing.T) { - t.Run("GetBlameRecord by limit ", func(t *testing.T) { + t.Run("should return blame info if found", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - blameList := sample.BlameRecordsList(t, 10) - for _, record := range blameList { - k.SetBlame(ctx, record) + wctx := sdk.WrapSDKContext(ctx) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := sample.ZetaIndex(t) + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + blame := types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, } - sort.Slice(blameList, func(i, j int) bool { - return blameList[i].Index < blameList[j].Index + k.SetBlame(ctx, blame) + + res, err := k.BlameByIdentifier(wctx, &types.QueryBlameByIdentifierRequest{ + BlameIdentifier: index, }) - rst, pageRes, err := k.GetAllBlamePaginated(ctx, &query.PageRequest{Limit: 10, CountTotal: true}) require.NoError(t, err) - sort.Slice(rst, func(i, j int) bool { - return rst[i].Index < rst[j].Index - }) - require.Equal(t, blameList, rst) - require.Equal(t, len(blameList), int(pageRes.Total)) + require.Equal(t, &types.QueryBlameByIdentifierResponse{ + BlameInfo: &blame, + }, res) }) - t.Run("GetBlameRecord by offset ", func(t *testing.T) { +} + +func TestKeeper_GetAllBlameRecords(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - blameList := sample.BlameRecordsList(t, 20) - offset := 10 - for _, record := range blameList { - k.SetBlame(ctx, record) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetAllBlameRecords(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return all if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := sample.ZetaIndex(t) + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + blame := types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, } - sort.Slice(blameList, func(i, j int) bool { - return blameList[i].Index < blameList[j].Index - }) - rst, pageRes, err := k.GetAllBlamePaginated(ctx, &query.PageRequest{Offset: uint64(offset), CountTotal: true}) + k.SetBlame(ctx, blame) + + res, err := k.GetAllBlameRecords(wctx, &types.QueryAllBlameRecordsRequest{}) require.NoError(t, err) - sort.Slice(rst, func(i, j int) bool { - return rst[i].Index < rst[j].Index - }) - require.Subset(t, blameList, rst) - require.Equal(t, len(blameList)-offset, len(rst)) - require.Equal(t, len(blameList), int(pageRes.Total)) + require.Equal(t, []types.Blame{blame}, res.BlameInfo) }) - t.Run("GetAllBlameRecord", func(t *testing.T) { +} + +func TestKeeper_BlamesByChainAndNonce(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - blameList := sample.BlameRecordsList(t, 100) - for _, record := range blameList { - k.SetBlame(ctx, record) - } - rst := k.GetAllBlame(ctx) - sort.Slice(rst, func(i, j int) bool { - return rst[i].Index < rst[j].Index - }) - sort.Slice(blameList, func(i, j int) bool { - return blameList[i].Index < blameList[j].Index + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.BlamesByChainAndNonce(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if blame not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.BlamesByChainAndNonce(wctx, &types.QueryBlameByChainAndNonceRequest{ + ChainId: 1, + Nonce: 1, }) - require.Equal(t, blameList, rst) + require.Error(t, err) + require.Nil(t, res) }) - t.Run("Get no records if nothing is set", func(t *testing.T) { + + t.Run("should return blame info if found", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - rst := k.GetAllBlame(ctx) - require.Len(t, rst, 0) + wctx := sdk.WrapSDKContext(ctx) + var chainId int64 = 97 + var nonce uint64 = 101 + digest := sample.ZetaIndex(t) + + index := types.GetBlameIndex(chainId, nonce, digest, 123) + blame := types.Blame{ + Index: index, + FailureReason: "failed to join party", + Nodes: nil, + } + k.SetBlame(ctx, blame) + + res, err := k.BlamesByChainAndNonce(wctx, &types.QueryBlameByChainAndNonceRequest{ + ChainId: chainId, + Nonce: int64(nonce), + }) + require.NoError(t, err) + require.Equal(t, &types.QueryBlameByChainAndNonceResponse{ + BlameInfo: []*types.Blame{&blame}, + }, res) }) } diff --git a/x/observer/keeper/grpc_query_block_header_test.go b/x/observer/keeper/grpc_query_block_header_test.go new file mode 100644 index 0000000000..9cf50f07a4 --- /dev/null +++ b/x/observer/keeper/grpc_query_block_header_test.go @@ -0,0 +1,119 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/proofs" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_GetAllBlockHeaders(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetAllBlockHeaders(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if block header is found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + bh := proofs.BlockHeader{ + Height: 1, + Hash: sample.Hash().Bytes(), + ParentHash: sample.Hash().Bytes(), + ChainId: 1, + Header: proofs.HeaderData{}, + } + k.SetBlockHeader(ctx, bh) + + res, err := k.GetAllBlockHeaders(wctx, &types.QueryAllBlockHeaderRequest{}) + require.NoError(t, err) + require.Equal(t, &bh, res.BlockHeaders[0]) + }) +} + +func TestKeeper_GetBlockHeaderByHash(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetBlockHeaderByHash(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetBlockHeaderByHash(wctx, &types.QueryGetBlockHeaderByHashRequest{ + BlockHash: sample.Hash().Bytes(), + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if block header is found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + bh := proofs.BlockHeader{ + Height: 1, + Hash: sample.Hash().Bytes(), + ParentHash: sample.Hash().Bytes(), + ChainId: 1, + Header: proofs.HeaderData{}, + } + k.SetBlockHeader(ctx, bh) + + res, err := k.GetBlockHeaderByHash(wctx, &types.QueryGetBlockHeaderByHashRequest{ + BlockHash: bh.Hash, + }) + require.NoError(t, err) + require.Equal(t, &bh, res.BlockHeader) + }) +} + +func TestKeeper_GetBlockHeaderStateByChain(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetBlockHeaderStateByChain(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetBlockHeaderStateByChain(wctx, &types.QueryGetBlockHeaderStateRequest{ + ChainId: 1, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if block header state is found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + bhs := types.BlockHeaderState{ + ChainId: 1, + } + k.SetBlockHeaderState(ctx, bhs) + + res, err := k.GetBlockHeaderStateByChain(wctx, &types.QueryGetBlockHeaderStateRequest{ + ChainId: 1, + }) + require.NoError(t, err) + require.Equal(t, &bhs, res.BlockHeaderState) + }) +} diff --git a/x/observer/keeper/grpc_query_chain_params_test.go b/x/observer/keeper/grpc_query_chain_params_test.go new file mode 100644 index 0000000000..0e7145e5cd --- /dev/null +++ b/x/observer/keeper/grpc_query_chain_params_test.go @@ -0,0 +1,97 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_GetChainParamsForChain(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetChainParamsForChain(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetChainParamsForChain(wctx, &types.QueryGetChainParamsForChainRequest{ + ChainId: 987, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if chain params found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + list := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + { + ChainId: chains.ZetaPrivnetChain().ChainId, + IsSupported: false, + }, + }, + } + k.SetChainParamsList(ctx, list) + + res, err := k.GetChainParamsForChain(wctx, &types.QueryGetChainParamsForChainRequest{ + ChainId: chains.ZetaPrivnetChain().ChainId, + }) + require.NoError(t, err) + require.Equal(t, &types.QueryGetChainParamsForChainResponse{ + ChainParams: list.ChainParams[0], + }, res) + }) +} + +func TestKeeper_GetChainParams(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetChainParams(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetChainParams(wctx, &types.QueryGetChainParamsRequest{}) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if chain params found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + list := types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + { + ChainId: chains.ZetaPrivnetChain().ChainId, + IsSupported: false, + }, + }, + } + k.SetChainParamsList(ctx, list) + + res, err := k.GetChainParams(wctx, &types.QueryGetChainParamsRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryGetChainParamsResponse{ + ChainParams: &list, + }, res) + }) +} diff --git a/x/observer/keeper/grpc_query_crosschain_flags_test.go b/x/observer/keeper/grpc_query_crosschain_flags_test.go new file mode 100644 index 0000000000..172df715d9 --- /dev/null +++ b/x/observer/keeper/grpc_query_crosschain_flags_test.go @@ -0,0 +1,47 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_CrosschainFlags(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.CrosschainFlags(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if crosschain flags not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.CrosschainFlags(wctx, &types.QueryGetCrosschainFlagsRequest{}) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if crosschain flags found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + flags := types.CrosschainFlags{ + IsInboundEnabled: false, + } + k.SetCrosschainFlags(ctx, flags) + + res, err := k.CrosschainFlags(wctx, &types.QueryGetCrosschainFlagsRequest{}) + + require.NoError(t, err) + require.Equal(t, &types.QueryGetCrosschainFlagsResponse{ + CrosschainFlags: flags, + }, res) + }) +} diff --git a/x/observer/keeper/grpc_query_keygen_test.go b/x/observer/keeper/grpc_query_keygen_test.go index f4c61aeabd..f081382452 100644 --- a/x/observer/keeper/grpc_query_keygen_test.go +++ b/x/observer/keeper/grpc_query_keygen_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "github.com/stretchr/testify/require" @@ -6,33 +6,32 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestKeygenQuery(t *testing.T) { - keeper, ctx := SetupKeeper(t) - wctx := sdk.WrapSDKContext(ctx) - item := createTestKeygen(keeper, ctx) - for _, tc := range []struct { - desc string - request *types.QueryGetKeygenRequest - response *types.QueryGetKeygenResponse - err error - }{ - { - desc: "First", - request: &types.QueryGetKeygenRequest{}, - response: &types.QueryGetKeygenResponse{Keygen: &item}, - }, - } { - tc := tc - t.Run(tc.desc, func(t *testing.T) { - response, err := keeper.Keygen(wctx, tc.request) - if tc.err != nil { - require.ErrorIs(t, err, tc.err) - } else { - require.Equal(t, tc.response, response) - } - }) - } +func TestKeeper_Keygen(t *testing.T) { + t.Run("should error if keygen not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Keygen(wctx, &types.QueryGetKeygenRequest{}) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if keygen found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + keygen := types.Keygen{ + BlockNumber: 10, + } + k.SetKeygen(ctx, keygen) + + res, err := k.Keygen(wctx, &types.QueryGetKeygenRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryGetKeygenResponse{ + Keygen: &keygen, + }, res) + }) } diff --git a/x/observer/keeper/grpc_query_node_account_test.go b/x/observer/keeper/grpc_query_node_account_test.go index 03facb08b4..8645357a0c 100644 --- a/x/observer/keeper/grpc_query_node_account_test.go +++ b/x/observer/keeper/grpc_query_node_account_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "testing" @@ -6,15 +6,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestNodeAccountQuerySingle(t *testing.T) { - keeper, ctx := SetupKeeper(t) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) - msgs := createNNodeAccount(keeper, ctx, 2) + msgs := createNNodeAccount(k, ctx, 2) for _, tc := range []struct { desc string request *types.QueryGetNodeAccountRequest @@ -43,7 +45,7 @@ func TestNodeAccountQuerySingle(t *testing.T) { } { tc := tc t.Run(tc.desc, func(t *testing.T) { - response, err := keeper.NodeAccount(wctx, tc.request) + response, err := k.NodeAccount(wctx, tc.request) if tc.err != nil { require.ErrorIs(t, err, tc.err) } else { @@ -54,9 +56,9 @@ func TestNodeAccountQuerySingle(t *testing.T) { } func TestNodeAccountQueryPaginated(t *testing.T) { - keeper, ctx := SetupKeeper(t) + k, ctx, _, _ := keepertest.ObserverKeeper(t) wctx := sdk.WrapSDKContext(ctx) - msgs := createNNodeAccount(keeper, ctx, 5) + msgs := createNNodeAccount(k, ctx, 5) request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllNodeAccountRequest { return &types.QueryAllNodeAccountRequest{ @@ -71,7 +73,7 @@ func TestNodeAccountQueryPaginated(t *testing.T) { t.Run("ByOffset", func(t *testing.T) { step := 2 for i := 0; i < len(msgs); i += step { - resp, err := keeper.NodeAccountAll(wctx, request(nil, uint64(i), uint64(step), false)) + resp, err := k.NodeAccountAll(wctx, request(nil, uint64(i), uint64(step), false)) require.NoError(t, err) for j := i; j < len(msgs) && j < i+step; j++ { require.Equal(t, &msgs[j], resp.NodeAccount[j-i]) @@ -82,7 +84,7 @@ func TestNodeAccountQueryPaginated(t *testing.T) { step := 2 var next []byte for i := 0; i < len(msgs); i += step { - resp, err := keeper.NodeAccountAll(wctx, request(next, 0, uint64(step), false)) + resp, err := k.NodeAccountAll(wctx, request(next, 0, uint64(step), false)) require.NoError(t, err) for j := i; j < len(msgs) && j < i+step; j++ { require.Equal(t, &msgs[j], resp.NodeAccount[j-i]) @@ -91,12 +93,12 @@ func TestNodeAccountQueryPaginated(t *testing.T) { } }) t.Run("Total", func(t *testing.T) { - resp, err := keeper.NodeAccountAll(wctx, request(nil, 0, 0, true)) + resp, err := k.NodeAccountAll(wctx, request(nil, 0, 0, true)) require.NoError(t, err) require.Equal(t, len(msgs), int(resp.Pagination.Total)) }) t.Run("InvalidRequest", func(t *testing.T) { - _, err := keeper.NodeAccountAll(wctx, nil) + _, err := k.NodeAccountAll(wctx, nil) require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) }) } diff --git a/x/observer/keeper/grpc_query_nonces_test.go b/x/observer/keeper/grpc_query_nonces_test.go index 657eb59008..5a66eebfbf 100644 --- a/x/observer/keeper/grpc_query_nonces_test.go +++ b/x/observer/keeper/grpc_query_nonces_test.go @@ -108,3 +108,84 @@ func TestChainNoncesQueryPaginated(t *testing.T) { require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) }) } + +func TestPendingNoncesQuerySingle(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.PendingNoncesByChain(wctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.PendingNoncesByChain(wctx, &types.QueryPendingNoncesByChainRequest{ + ChainId: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + tss := sample.Tss() + k.SetTSS(ctx, tss) + res, err := k.PendingNoncesByChain(wctx, &types.QueryPendingNoncesByChainRequest{ + ChainId: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + tss := sample.Tss() + k.SetTSS(ctx, tss) + pendingNonces := sample.PendingNoncesList(t, "sample", 5) + pendingNonces[1].Tss = tss.TssPubkey + for _, nonce := range pendingNonces { + k.SetPendingNonces(ctx, nonce) + } + res, err := k.PendingNoncesByChain(wctx, &types.QueryPendingNoncesByChainRequest{ + ChainId: 1, + }) + require.NoError(t, err) + require.Equal(t, pendingNonces[1], res.PendingNonces) + }) +} + +func TestPendingNoncesQueryPaginated(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + pendingNonces := sample.PendingNoncesList(t, "sample", 5) + for _, nonce := range pendingNonces { + k.SetPendingNonces(ctx, nonce) + } + + request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllPendingNoncesRequest { + return &types.QueryAllPendingNoncesRequest{ + Pagination: &query.PageRequest{ + Key: next, + Offset: offset, + Limit: limit, + CountTotal: total, + }, + } + } + + t.Run("Total", func(t *testing.T) { + resp, err := k.PendingNoncesAll(wctx, request(nil, 0, 0, true)) + require.NoError(t, err) + require.Equal(t, len(pendingNonces), int(resp.Pagination.Total)) + }) + t.Run("InvalidRequest", func(t *testing.T) { + _, err := k.PendingNoncesAll(wctx, nil) + require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) + }) +} diff --git a/x/observer/keeper/grpc_query_observer_test.go b/x/observer/keeper/grpc_query_observer_test.go new file mode 100644 index 0000000000..73675fae0d --- /dev/null +++ b/x/observer/keeper/grpc_query_observer_test.go @@ -0,0 +1,78 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "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/observer/types" +) + +func TestKeeper_ShowObserverCount(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.ShowObserverCount(wctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.ShowObserverCount(wctx, &types.QueryShowObserverCountRequest{}) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + count := 1 + loc := &types.LastObserverCount{ + Count: uint64(count), + } + k.SetLastObserverCount(ctx, loc) + + res, err := k.ShowObserverCount(wctx, &types.QueryShowObserverCountRequest{}) + require.NoError(t, err) + require.Equal(t, loc, res.LastObserverCount) + }) +} + +func TestKeeper_ObserverSet(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.ObserverSet(wctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.ObserverSet(wctx, &types.QueryObserverSet{}) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + os := sample.ObserverSet(10) + k.SetObserverSet(ctx, os) + + res, err := k.ObserverSet(wctx, &types.QueryObserverSet{}) + require.NoError(t, err) + require.Equal(t, os.ObserverList, res.Observers) + }) +} diff --git a/x/observer/keeper/grpc_query_params_test.go b/x/observer/keeper/grpc_query_params_test.go index 4cd534fa59..a1de6c63b2 100644 --- a/x/observer/keeper/grpc_query_params_test.go +++ b/x/observer/keeper/grpc_query_params_test.go @@ -1,20 +1,21 @@ -package keeper +package keeper_test import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) func TestParamsQuery(t *testing.T) { - keeper, ctx := SetupKeeper(t) + k, ctx, _, _ := keepertest.ObserverKeeper(t) wctx := sdk.WrapSDKContext(ctx) params := types.DefaultParams() - keeper.SetParams(ctx, params) + k.SetParams(ctx, params) - response, err := keeper.Params(wctx, &types.QueryParamsRequest{}) + response, err := k.Params(wctx, &types.QueryParamsRequest{}) require.NoError(t, err) require.Equal(t, &types.QueryParamsResponse{Params: params}, response) } diff --git a/x/observer/keeper/grpc_query_prove_test.go b/x/observer/keeper/grpc_query_prove_test.go new file mode 100644 index 0000000000..7eb11b00f5 --- /dev/null +++ b/x/observer/keeper/grpc_query_prove_test.go @@ -0,0 +1,72 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/proofs" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_Prove(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Prove(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if invalid hash", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Prove(wctx, &types.QueryProveRequest{ + ChainId: 987, + BlockHash: sample.Hash().String(), + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if header not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Prove(wctx, &types.QueryProveRequest{ + ChainId: 5, + BlockHash: sample.Hash().String(), + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if proof not valid", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + hash := sample.Hash() + bh := proofs.BlockHeader{ + Height: 1, + Hash: hash.Bytes(), + ParentHash: sample.Hash().Bytes(), + ChainId: 1, + Header: proofs.HeaderData{}, + } + k.SetBlockHeader(ctx, bh) + + res, err := k.Prove(wctx, &types.QueryProveRequest{ + ChainId: 5, + BlockHash: hash.String(), + Proof: &proofs.Proof{}, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + // TODO: // https://github.com/zeta-chain/node/issues/1875 add more tests +} diff --git a/x/observer/keeper/grpc_query_supported_chain_test.go b/x/observer/keeper/grpc_query_supported_chain_test.go new file mode 100644 index 0000000000..50acd5703a --- /dev/null +++ b/x/observer/keeper/grpc_query_supported_chain_test.go @@ -0,0 +1,21 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" +) + +func TestKeeper_SupportedChains(t *testing.T) { + t.Run("should return supported chains", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.SupportedChains(wctx, nil) + require.NoError(t, err) + require.Equal(t, []*chains.Chain{}, res.Chains) + }) +} diff --git a/x/observer/keeper/grpc_query_tss_test.go b/x/observer/keeper/grpc_query_tss_test.go new file mode 100644 index 0000000000..105d7c1cf9 --- /dev/null +++ b/x/observer/keeper/grpc_query_tss_test.go @@ -0,0 +1,230 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/crypto" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func TestTSSQuerySingle(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + tss := sample.Tss() + wctx := sdk.WrapSDKContext(ctx) + + for _, tc := range []struct { + desc string + request *types.QueryGetTSSRequest + response *types.QueryGetTSSResponse + skipSettingTss bool + err error + }{ + { + desc: "Skip setting tss", + request: &types.QueryGetTSSRequest{}, + skipSettingTss: true, + err: status.Error(codes.InvalidArgument, "not found"), + }, + { + desc: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "invalid request"), + }, + { + desc: "Should return tss", + request: &types.QueryGetTSSRequest{}, + response: &types.QueryGetTSSResponse{TSS: tss}, + }, + } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + if !tc.skipSettingTss { + k.SetTSS(ctx, tss) + } + response, err := k.TSS(wctx, tc.request) + if tc.err != nil { + require.ErrorIs(t, err, tc.err) + } else { + require.Equal(t, tc.response, response) + } + }) + } +} + +func TestTSSQueryHistory(t *testing.T) { + keeper, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + for _, tc := range []struct { + desc string + tssCount int + foundPrevious bool + err error + }{ + { + desc: "1 Tss addresses", + tssCount: 1, + foundPrevious: false, + err: nil, + }, + { + desc: "10 Tss addresses", + tssCount: 10, + foundPrevious: true, + err: nil, + }, + } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + tssList := sample.TssList(tc.tssCount) + for _, tss := range tssList { + keeper.SetTSS(ctx, tss) + keeper.SetTSSHistory(ctx, tss) + } + request := &types.QueryTssHistoryRequest{} + response, err := keeper.TssHistory(wctx, request) + if tc.err != nil { + require.ErrorIs(t, err, tc.err) + } else { + require.Equal(t, len(tssList), len(response.TssList)) + prevTss, found := keeper.GetPreviousTSS(ctx) + require.Equal(t, tc.foundPrevious, found) + if found { + require.Equal(t, tssList[len(tssList)-2], prevTss) + } + } + }) + } +} + +func TestKeeper_GetTssAddress(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetTssAddress(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetTssAddress(wctx, &types.QueryGetTssAddressRequest{ + BitcoinChainId: 1, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if invalid chain id", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + tss := sample.Tss() + k.SetTSS(ctx, tss) + + res, err := k.GetTssAddress(wctx, &types.QueryGetTssAddressRequest{ + BitcoinChainId: 987, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if valid chain id", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + tss := sample.Tss() + k.SetTSS(ctx, tss) + + res, err := k.GetTssAddress(wctx, &types.QueryGetTssAddressRequest{ + BitcoinChainId: chains.BtcRegtestChain().ChainId, + }) + require.NoError(t, err) + expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain().ChainId) + require.NoError(t, err) + expectedBtcAddress, err := crypto.GetTssAddrBTC(tss.TssPubkey, expectedBitcoinParams) + require.NoError(t, err) + expectedEthAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) + require.NoError(t, err) + require.NotNil(t, &types.QueryGetTssAddressByFinalizedHeightResponse{ + Eth: expectedEthAddress.String(), + Btc: expectedBtcAddress, + }, res) + }) +} + +func TestKeeper_GetTssAddressByFinalizedHeight(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetTssAddressByFinalizedHeight(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.GetTssAddressByFinalizedHeight(wctx, &types.QueryGetTssAddressByFinalizedHeightRequest{ + BitcoinChainId: 1, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should error if invalid chain id", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + tssList := sample.TssList(100) + r := rand.Intn((len(tssList)-1)-0) + 0 + for _, tss := range tssList { + k.SetTSSHistory(ctx, tss) + } + + res, err := k.GetTssAddressByFinalizedHeight(wctx, &types.QueryGetTssAddressByFinalizedHeightRequest{ + BitcoinChainId: 987, + FinalizedZetaHeight: tssList[r].FinalizedZetaHeight, + }) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return if valid chain id", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + tssList := sample.TssList(100) + r := rand.Intn((len(tssList)-1)-0) + 0 + for _, tss := range tssList { + k.SetTSSHistory(ctx, tss) + } + + res, err := k.GetTssAddressByFinalizedHeight(wctx, &types.QueryGetTssAddressByFinalizedHeightRequest{ + BitcoinChainId: chains.BtcRegtestChain().ChainId, + FinalizedZetaHeight: tssList[r].FinalizedZetaHeight, + }) + require.NoError(t, err) + expectedBitcoinParams, err := chains.BitcoinNetParamsFromChainID(chains.BtcRegtestChain().ChainId) + require.NoError(t, err) + expectedBtcAddress, err := crypto.GetTssAddrBTC(tssList[r].TssPubkey, expectedBitcoinParams) + require.NoError(t, err) + expectedEthAddress, err := crypto.GetTssAddrEVM(tssList[r].TssPubkey) + require.NoError(t, err) + require.NotNil(t, &types.QueryGetTssAddressByFinalizedHeightResponse{ + Eth: expectedEthAddress.String(), + Btc: expectedBtcAddress, + }, res) + }) +} diff --git a/x/observer/keeper/hooks_test.go b/x/observer/keeper/hooks_test.go new file mode 100644 index 0000000000..ec782663ee --- /dev/null +++ b/x/observer/keeper/hooks_test.go @@ -0,0 +1,213 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "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/observer/types" +) + +func TestKeeper_NotImplementedHooks(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + hooks := k.Hooks() + require.Nil(t, hooks.AfterValidatorCreated(ctx, nil)) + require.Nil(t, hooks.BeforeValidatorModified(ctx, nil)) + require.Nil(t, hooks.AfterValidatorBonded(ctx, nil, nil)) + require.Nil(t, hooks.BeforeDelegationCreated(ctx, nil, nil)) + require.Nil(t, hooks.BeforeDelegationSharesModified(ctx, nil, nil)) + require.Nil(t, hooks.BeforeDelegationRemoved(ctx, nil, nil)) +} + +func TestKeeper_AfterValidatorRemoved(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + // #nosec G404 test purpose - weak randomness is not an issue here + r := rand.New(rand.NewSource(1)) + valAddr := sample.ValAddress(r) + accAddress, err := types.GetAccAddressFromOperatorAddress(valAddr.String()) + require.NoError(t, err) + os := types.ObserverSet{ + ObserverList: []string{accAddress.String()}, + } + k.SetObserverSet(ctx, os) + + hooks := k.Hooks() + err = hooks.AfterValidatorRemoved(ctx, nil, valAddr) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + // observer for validator is removed from set + require.Empty(t, os.ObserverList) +} + +func TestKeeper_AfterValidatorBeginUnbonding(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.GetStakingKeeper().SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: accAddressOfValidator.String(), + ValidatorAddress: validator.GetOperator().String(), + Shares: sdk.NewDec(10), + }) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + hooks := k.Hooks() + err = hooks.AfterValidatorBeginUnbonding(ctx, nil, validator.GetOperator()) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Empty(t, os.ObserverList) +} + +func TestKeeper_AfterDelegationModified(t *testing.T) { + t.Run("should not clean observer if not self delegation", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.GetStakingKeeper().SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: accAddressOfValidator.String(), + ValidatorAddress: validator.GetOperator().String(), + Shares: sdk.NewDec(10), + }) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + hooks := k.Hooks() + err = hooks.AfterDelegationModified(ctx, sdk.AccAddress(sample.AccAddress()), validator.GetOperator()) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Equal(t, 1, len(os.ObserverList)) + require.Equal(t, accAddressOfValidator.String(), os.ObserverList[0]) + }) + + t.Run("should clean observer if self delegation", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.GetStakingKeeper().SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: accAddressOfValidator.String(), + ValidatorAddress: validator.GetOperator().String(), + Shares: sdk.NewDec(10), + }) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + hooks := k.Hooks() + err = hooks.AfterDelegationModified(ctx, accAddressOfValidator, validator.GetOperator()) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Empty(t, os.ObserverList) + }) +} + +func TestKeeper_BeforeValidatorSlashed(t *testing.T) { + t.Run("should error if validator not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + + hooks := k.Hooks() + err := hooks.BeforeValidatorSlashed(ctx, validator.GetOperator(), sdk.NewDec(1)) + require.Error(t, err) + }) + + t.Run("should not error if observer set not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + + hooks := k.Hooks() + err := hooks.BeforeValidatorSlashed(ctx, validator.GetOperator(), sdk.NewDec(1)) + require.NoError(t, err) + }) + + t.Run("should remove from observer set", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + validator.Tokens = sdk.NewInt(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + hooks := k.Hooks() + err = hooks.BeforeValidatorSlashed(ctx, validator.GetOperator(), sdk.MustNewDecFromStr("0.1")) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Empty(t, os.ObserverList) + }) + + t.Run("should not remove from observer set", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + validator.Tokens = sdk.NewInt(1000000000000000000) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + hooks := k.Hooks() + err = hooks.BeforeValidatorSlashed(ctx, validator.GetOperator(), sdk.MustNewDecFromStr("0")) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Equal(t, 1, len(os.ObserverList)) + require.Equal(t, accAddressOfValidator.String(), os.ObserverList[0]) + }) +} diff --git a/x/observer/keeper/keeper_test.go b/x/observer/keeper/keeper_test.go deleted file mode 100644 index c34cdb5392..0000000000 --- a/x/observer/keeper/keeper_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package keeper - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/store" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - typesparams "github.com/cosmos/cosmos-sdk/x/params/types" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmdb "github.com/tendermint/tm-db" - authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" - "github.com/zeta-chain/zetacore/x/observer/types" -) - -func SetupKeeper(t testing.TB) (*Keeper, sdk.Context) { - storeKey := sdk.NewKVStoreKey(types.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - - db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) - - registry := codectypes.NewInterfaceRegistry() - cdc := codec.NewProtoCodec(registry) - - paramsSubspace := typesparams.NewSubspace(cdc, - types.Amino, - storeKey, - memStoreKey, - "ZetaObsParams", - ) - - k := NewKeeper( - codec.NewProtoCodec(registry), - storeKey, - memStoreKey, - paramsSubspace, - stakingkeeper.Keeper{}, - slashingkeeper.Keeper{}, - authoritykeeper.Keeper{}, - ) - - ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, nil) - return k, ctx -} diff --git a/x/observer/keeper/keygen_test.go b/x/observer/keeper/keygen_test.go index f14fa3aeef..ef9a5e6991 100644 --- a/x/observer/keeper/keygen_test.go +++ b/x/observer/keeper/keygen_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "testing" @@ -6,11 +6,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/observer/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) // Keeper Tests -func createTestKeygen(keeper *Keeper, ctx sdk.Context) types.Keygen { +func createTestKeygen(keeper *keeper.Keeper, ctx sdk.Context) types.Keygen { item := types.Keygen{ BlockNumber: 10, } @@ -19,16 +21,16 @@ func createTestKeygen(keeper *Keeper, ctx sdk.Context) types.Keygen { } func TestKeygenGet(t *testing.T) { - keeper, ctx := SetupKeeper(t) - item := createTestKeygen(keeper, ctx) - rst, found := keeper.GetKeygen(ctx) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + item := createTestKeygen(k, ctx) + rst, found := k.GetKeygen(ctx) require.True(t, found) require.Equal(t, item, rst) } func TestKeygenRemove(t *testing.T) { - keeper, ctx := SetupKeeper(t) - createTestKeygen(keeper, ctx) - keeper.RemoveKeygen(ctx) - _, found := keeper.GetKeygen(ctx) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + createTestKeygen(k, ctx) + k.RemoveKeygen(ctx) + _, found := k.GetKeygen(ctx) require.False(t, found) } diff --git a/x/observer/keeper/msg_server_add_blame_vote_test.go b/x/observer/keeper/msg_server_add_blame_vote_test.go new file mode 100644 index 0000000000..28ada869b0 --- /dev/null +++ b/x/observer/keeper/msg_server_add_blame_vote_test.go @@ -0,0 +1,182 @@ +package keeper_test + +import ( + "math/rand" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "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/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_AddBlameVote(t *testing.T) { + t.Run("should error if supported chain not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + res, err := srv.AddBlameVote(ctx, &types.MsgAddBlameVote{ + ChainId: 1, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not tombstoned observer", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chainId := getValidEthChainIDWithIndex(t, 0) + setSupportedChain(ctx, *k, chainId) + + res, err := srv.AddBlameVote(ctx, &types.MsgAddBlameVote{ + ChainId: chainId, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return response and set blame if finalizing vote", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chainId := getValidEthChainIDWithIndex(t, 0) + setSupportedChain(ctx, *k, chainId) + + r := rand.New(rand.NewSource(9)) + // Set validator in the store + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + consAddress, err := validator.GetConsAddr() + require.NoError(t, err) + k.GetSlashingKeeper().SetValidatorSigningInfo(ctx, consAddress, slashingtypes.ValidatorSigningInfo{ + Address: consAddress.String(), + StartHeight: 0, + JailedUntil: ctx.BlockHeader().Time.Add(1000000 * time.Second), + Tombstoned: false, + MissedBlocksCounter: 1, + }) + + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + + blameInfo := sample.BlameRecord(t, "index") + res, err := srv.AddBlameVote(ctx, &types.MsgAddBlameVote{ + Creator: accAddressOfValidator.String(), + ChainId: chainId, + BlameInfo: blameInfo, + }) + require.NoError(t, err) + require.Equal(t, &types.MsgAddBlameVoteResponse{}, res) + + blame, found := k.GetBlame(ctx, blameInfo.Index) + require.True(t, found) + require.Equal(t, blameInfo, blame) + }) + + t.Run("should error if add vote fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chainId := getValidEthChainIDWithIndex(t, 1) + setSupportedChain(ctx, *k, chainId) + + r := rand.New(rand.NewSource(9)) + // Set validator in the store + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + consAddress, err := validator.GetConsAddr() + require.NoError(t, err) + k.GetSlashingKeeper().SetValidatorSigningInfo(ctx, consAddress, slashingtypes.ValidatorSigningInfo{ + Address: consAddress.String(), + StartHeight: 0, + JailedUntil: ctx.BlockHeader().Time.Add(1000000 * time.Second), + Tombstoned: false, + MissedBlocksCounter: 1, + }) + + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String(), "Observer2"}, + }) + blameInfo := sample.BlameRecord(t, "index") + vote := &types.MsgAddBlameVote{ + Creator: accAddressOfValidator.String(), + ChainId: chainId, + BlameInfo: blameInfo, + } + ballot := types.Ballot{ + Index: vote.Digest(), + BallotIdentifier: vote.Digest(), + VoterList: []string{accAddressOfValidator.String()}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotThreshold: sdk.NewDec(2), + } + k.SetBallot(ctx, &ballot) + + _, err = srv.AddBlameVote(ctx, vote) + require.Error(t, err) + }) + + t.Run("should return response and not set blame if not finalizing vote", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + srv := keeper.NewMsgServerImpl(*k) + + chainId := getValidEthChainIDWithIndex(t, 1) + setSupportedChain(ctx, *k, chainId) + + r := rand.New(rand.NewSource(9)) + // Set validator in the store + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + consAddress, err := validator.GetConsAddr() + require.NoError(t, err) + k.GetSlashingKeeper().SetValidatorSigningInfo(ctx, consAddress, slashingtypes.ValidatorSigningInfo{ + Address: consAddress.String(), + StartHeight: 0, + JailedUntil: ctx.BlockHeader().Time.Add(1000000 * time.Second), + Tombstoned: false, + MissedBlocksCounter: 1, + }) + + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String(), "Observer2"}, + }) + blameInfo := sample.BlameRecord(t, "index") + vote := &types.MsgAddBlameVote{ + Creator: accAddressOfValidator.String(), + ChainId: chainId, + BlameInfo: blameInfo, + } + ballot := types.Ballot{ + Index: vote.Digest(), + BallotIdentifier: vote.Digest(), + VoterList: []string{accAddressOfValidator.String()}, + Votes: []types.VoteType{types.VoteType_NotYetVoted}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotThreshold: sdk.NewDec(2), + } + k.SetBallot(ctx, &ballot) + + res, err := srv.AddBlameVote(ctx, vote) + require.NoError(t, err) + require.Equal(t, &types.MsgAddBlameVoteResponse{}, res) + + _, found := k.GetBlame(ctx, blameInfo.Index) + require.False(t, found) + }) +} diff --git a/x/observer/keeper/msg_server_add_observer_test.go b/x/observer/keeper/msg_server_add_observer_test.go new file mode 100644 index 0000000000..0cbb9df514 --- /dev/null +++ b/x/observer/keeper/msg_server_add_observer_test.go @@ -0,0 +1,117 @@ +package keeper_test + +import ( + "math" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + "github.com/zeta-chain/zetacore/x/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_AddObserver(t *testing.T) { + t.Run("should error if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, false) + wctx := sdk.WrapSDKContext(ctx) + + srv := keeper.NewMsgServerImpl(*k) + res, err := srv.AddObserver(wctx, &types.MsgAddObserver{ + Creator: admin, + }) + require.Error(t, err) + require.Equal(t, &types.MsgAddObserverResponse{}, res) + }) + + t.Run("should error if pub key not valid", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) + wctx := sdk.WrapSDKContext(ctx) + + srv := keeper.NewMsgServerImpl(*k) + res, err := srv.AddObserver(wctx, &types.MsgAddObserver{ + Creator: admin, + ZetaclientGranteePubkey: "invalid", + }) + require.Error(t, err) + require.Equal(t, &types.MsgAddObserverResponse{}, res) + }) + + t.Run("should add if add node account only false", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) + wctx := sdk.WrapSDKContext(ctx) + + _, found := k.GetLastObserverCount(ctx) + require.False(t, found) + srv := keeper.NewMsgServerImpl(*k) + observerAddress := sdk.AccAddress(crypto.AddressHash([]byte("ObserverAddress"))) + res, err := srv.AddObserver(wctx, &types.MsgAddObserver{ + Creator: admin, + ZetaclientGranteePubkey: sample.PubKeyString(), + AddNodeAccountOnly: false, + ObserverAddress: observerAddress.String(), + }) + require.NoError(t, err) + require.Equal(t, &types.MsgAddObserverResponse{}, res) + + loc, found := k.GetLastObserverCount(ctx) + require.True(t, found) + require.Equal(t, uint64(1), loc.Count) + }) + + t.Run("should add to node account if add node account only true", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupOperational, true) + wctx := sdk.WrapSDKContext(ctx) + + _, found := k.GetLastObserverCount(ctx) + require.False(t, found) + srv := keeper.NewMsgServerImpl(*k) + observerAddress := sdk.AccAddress(crypto.AddressHash([]byte("ObserverAddress"))) + _, found = k.GetKeygen(ctx) + require.False(t, found) + _, found = k.GetNodeAccount(ctx, observerAddress.String()) + require.False(t, found) + + res, err := srv.AddObserver(wctx, &types.MsgAddObserver{ + Creator: admin, + ZetaclientGranteePubkey: sample.PubKeyString(), + AddNodeAccountOnly: true, + ObserverAddress: observerAddress.String(), + }) + require.NoError(t, err) + require.Equal(t, &types.MsgAddObserverResponse{}, res) + + _, found = k.GetLastObserverCount(ctx) + require.False(t, found) + + keygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.Equal(t, types.Keygen{BlockNumber: math.MaxInt64}, keygen) + + _, found = k.GetNodeAccount(ctx, observerAddress.String()) + require.True(t, found) + }) +} diff --git a/x/observer/keeper/msg_server_update_keygen_test.go b/x/observer/keeper/msg_server_update_keygen_test.go new file mode 100644 index 0000000000..8b3201c5ed --- /dev/null +++ b/x/observer/keeper/msg_server_update_keygen_test.go @@ -0,0 +1,105 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + "github.com/zeta-chain/zetacore/x/observer/keeper" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestMsgServer_UpdateKeygen(t *testing.T) { + t.Run("should error if not authorized", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, false) + wctx := sdk.WrapSDKContext(ctx) + + srv := keeper.NewMsgServerImpl(*k) + res, err := srv.UpdateKeygen(wctx, &types.MsgUpdateKeygen{ + Creator: admin, + }) + require.Error(t, err) + require.Equal(t, &types.MsgUpdateKeygenResponse{}, res) + }) + + t.Run("should error if keygen not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) + wctx := sdk.WrapSDKContext(ctx) + + srv := keeper.NewMsgServerImpl(*k) + res, err := srv.UpdateKeygen(wctx, &types.MsgUpdateKeygen{ + Creator: admin, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if msg block too low", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) + wctx := sdk.WrapSDKContext(ctx) + item := types.Keygen{ + BlockNumber: 10, + } + k.SetKeygen(ctx, item) + srv := keeper.NewMsgServerImpl(*k) + res, err := srv.UpdateKeygen(wctx, &types.MsgUpdateKeygen{ + Creator: admin, + Block: 2, + }) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should update", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMockOptions{ + UseAuthorityMock: true, + }) + authorityMock := keepertest.GetObserverAuthorityMock(t, k) + admin := sample.AccAddress() + keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) + wctx := sdk.WrapSDKContext(ctx) + item := types.Keygen{ + BlockNumber: 10, + } + k.SetKeygen(ctx, item) + srv := keeper.NewMsgServerImpl(*k) + + granteePubKey := sample.PubKeySet() + k.SetNodeAccount(ctx, types.NodeAccount{ + Operator: "operator", + GranteePubkey: granteePubKey, + }) + + res, err := srv.UpdateKeygen(wctx, &types.MsgUpdateKeygen{ + Creator: admin, + Block: ctx.BlockHeight() + 30, + }) + require.NoError(t, err) + require.Equal(t, &types.MsgUpdateKeygenResponse{}, res) + + keygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.Equal(t, 1, len(keygen.GranteePubkeys)) + require.Equal(t, granteePubKey.Secp256k1.String(), keygen.GranteePubkeys[0]) + require.Equal(t, ctx.BlockHeight()+30, keygen.BlockNumber) + require.Equal(t, types.KeygenStatus_PendingKeygen, keygen.Status) + }) +} diff --git a/x/observer/keeper/node_account_test.go b/x/observer/keeper/node_account_test.go index 26a5c47d1c..c20501f8b2 100644 --- a/x/observer/keeper/node_account_test.go +++ b/x/observer/keeper/node_account_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "fmt" @@ -6,12 +6,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/x/observer/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) // Keeper Tests -func createNNodeAccount(keeper *Keeper, ctx sdk.Context, n int) []types.NodeAccount { +func createNNodeAccount(keeper *keeper.Keeper, ctx sdk.Context, n int) []types.NodeAccount { items := make([]types.NodeAccount, n) for i := range items { items[i].Operator = fmt.Sprintf("%d", i) @@ -21,26 +23,28 @@ func createNNodeAccount(keeper *Keeper, ctx sdk.Context, n int) []types.NodeAcco } func TestNodeAccountGet(t *testing.T) { - keeper, ctx := SetupKeeper(t) - items := createNNodeAccount(keeper, ctx, 10) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + items := createNNodeAccount(k, ctx, 10) for _, item := range items { - rst, found := keeper.GetNodeAccount(ctx, item.Operator) + rst, found := k.GetNodeAccount(ctx, item.Operator) require.True(t, found) require.Equal(t, item, rst) } } func TestNodeAccountRemove(t *testing.T) { - keeper, ctx := SetupKeeper(t) - items := createNNodeAccount(keeper, ctx, 10) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + items := createNNodeAccount(k, ctx, 10) for _, item := range items { - keeper.RemoveNodeAccount(ctx, item.Operator) - _, found := keeper.GetNodeAccount(ctx, item.Operator) + k.RemoveNodeAccount(ctx, item.Operator) + _, found := k.GetNodeAccount(ctx, item.Operator) require.False(t, found) } } func TestNodeAccountGetAll(t *testing.T) { - keeper, ctx := SetupKeeper(t) - items := createNNodeAccount(keeper, ctx, 10) - require.Equal(t, items, keeper.GetAllNodeAccount(ctx)) + k, ctx, _, _ := keepertest.ObserverKeeper(t) + items := createNNodeAccount(k, ctx, 10) + require.Equal(t, items, k.GetAllNodeAccount(ctx)) } diff --git a/x/observer/keeper/nonce_to_cctx_test.go b/x/observer/keeper/nonce_to_cctx_test.go index 760e4f7111..a16a21f5ec 100644 --- a/x/observer/keeper/nonce_to_cctx_test.go +++ b/x/observer/keeper/nonce_to_cctx_test.go @@ -20,6 +20,14 @@ func TestKeeper_GetNonceToCctx(t *testing.T) { require.True(t, found) require.Equal(t, n, rst) } + + for _, n := range nonceToCctxList { + k.RemoveNonceToCctx(ctx, n) + } + for _, n := range nonceToCctxList { + _, found := k.GetNonceToCctx(ctx, n.Tss, n.ChainId, n.Nonce) + require.False(t, found) + } }) t.Run("Get nonce to cctx not found", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) diff --git a/x/observer/keeper/observer_set_test.go b/x/observer/keeper/observer_set_test.go index cd4a4239a7..d17e496fae 100644 --- a/x/observer/keeper/observer_set_test.go +++ b/x/observer/keeper/observer_set_test.go @@ -12,6 +12,8 @@ func TestKeeper_GetObserverSet(t *testing.T) { t.Run("get observer set", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) os := sample.ObserverSet(10) + _, found := k.GetObserverSet(ctx) + require.False(t, found) k.SetObserverSet(ctx, os) tfm, found := k.GetObserverSet(ctx) require.True(t, found) @@ -23,6 +25,7 @@ func TestKeeper_IsAddressPartOfObserverSet(t *testing.T) { t.Run("address is part of observer set", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) os := sample.ObserverSet(10) + require.False(t, k.IsAddressPartOfObserverSet(ctx, os.ObserverList[0])) k.SetObserverSet(ctx, os) require.True(t, k.IsAddressPartOfObserverSet(ctx, os.ObserverList[0])) require.False(t, k.IsAddressPartOfObserverSet(ctx, sample.AccAddress())) @@ -42,12 +45,30 @@ func TestKeeper_AddObserverToSet(t *testing.T) { require.True(t, found) require.Len(t, osNew.ObserverList, len(os.ObserverList)+1) }) + + t.Run("add observer to set if set doesn't exist", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + newObserver := sample.AccAddress() + k.AddObserverToSet(ctx, newObserver) + require.True(t, k.IsAddressPartOfObserverSet(ctx, newObserver)) + osNew, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Len(t, osNew.ObserverList, 1) + + // add same address again, len doesn't change + k.AddObserverToSet(ctx, newObserver) + require.True(t, k.IsAddressPartOfObserverSet(ctx, newObserver)) + osNew, found = k.GetObserverSet(ctx) + require.True(t, found) + require.Len(t, osNew.ObserverList, 1) + }) } func TestKeeper_RemoveObserverFromSet(t *testing.T) { t.Run("remove observer from set", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) os := sample.ObserverSet(10) + k.RemoveObserverFromSet(ctx, os.ObserverList[0]) k.SetObserverSet(ctx, os) k.RemoveObserverFromSet(ctx, os.ObserverList[0]) require.False(t, k.IsAddressPartOfObserverSet(ctx, os.ObserverList[0])) @@ -64,13 +85,25 @@ func TestKeeper_UpdateObserverAddress(t *testing.T) { newObserverAddress := sample.AccAddress() observerSet := sample.ObserverSet(10) observerSet.ObserverList = append(observerSet.ObserverList, oldObserverAddress) - k.SetObserverSet(ctx, observerSet) err := k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) + require.Error(t, err) + k.SetObserverSet(ctx, observerSet) + err = k.UpdateObserverAddress(ctx, oldObserverAddress, newObserverAddress) require.NoError(t, err) observerSet, found := k.GetObserverSet(ctx) require.True(t, found) require.Equal(t, newObserverAddress, observerSet.ObserverList[len(observerSet.ObserverList)-1]) }) + t.Run("should error if observer address not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + oldObserverAddress := sample.AccAddress() + newObserverAddress := sample.AccAddress() + observerSet := sample.ObserverSet(10) + observerSet.ObserverList = append(observerSet.ObserverList, oldObserverAddress) + k.SetObserverSet(ctx, observerSet) + err := k.UpdateObserverAddress(ctx, sample.AccAddress(), newObserverAddress) + require.Error(t, err) + }) t.Run("update observer address long observerList", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) oldObserverAddress := sample.AccAddress() diff --git a/x/observer/keeper/params_test.go b/x/observer/keeper/params_test.go index c487ea0f73..309d66df9b 100644 --- a/x/observer/keeper/params_test.go +++ b/x/observer/keeper/params_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "fmt" @@ -9,11 +9,12 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/x/observer/types" ) func TestGetParams(t *testing.T) { - k, ctx := SetupKeeper(t) + k, ctx, _, _ := keepertest.ObserverKeeper(t) params := types.DefaultParams() k.SetParams(ctx, params) @@ -22,7 +23,6 @@ func TestGetParams(t *testing.T) { } func TestGenerateAddress(t *testing.T) { - types.SetConfig(false) addr := sdk.AccAddress(crypto.AddressHash([]byte("Output1" + strconv.Itoa(1)))) addrString := addr.String() fmt.Println(addrString) diff --git a/x/observer/keeper/pending_nonces_test.go b/x/observer/keeper/pending_nonces_test.go index 6185e80bf1..37ff74fb22 100644 --- a/x/observer/keeper/pending_nonces_test.go +++ b/x/observer/keeper/pending_nonces_test.go @@ -62,5 +62,74 @@ func TestKeeper_PendingNoncesAll(t *testing.T) { return rst[i].ChainId < rst[j].ChainId }) require.Equal(t, nonces, rst) + + k.RemovePendingNonces(ctx, nonces[0]) + rst, err = k.GetAllPendingNonces(ctx) + require.NoError(t, err) + sort.SliceStable(rst, func(i, j int) bool { + return rst[i].ChainId < rst[j].ChainId + }) + require.Equal(t, nonces[1:], rst) + }) +} + +func TestKeeper_SetTssAndUpdateNonce(t *testing.T) { + t.Run("should set tss and update nonces", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + _, found := k.GetTSS(ctx) + require.False(t, found) + pendingNonces, err := k.GetAllPendingNonces(ctx) + require.NoError(t, err) + require.Empty(t, pendingNonces) + chainNonces := k.GetAllChainNonces(ctx) + require.NoError(t, err) + require.Empty(t, chainNonces) + + tss := sample.Tss() + // core params list but chain not in list + setSupportedChain(ctx, *k, getValidEthChainIDWithIndex(t, 0)) + k.SetTssAndUpdateNonce(ctx, tss) + + _, found = k.GetTSS(ctx) + require.True(t, found) + pendingNonces, err = k.GetAllPendingNonces(ctx) + require.NoError(t, err) + require.Equal(t, 1, len(pendingNonces)) + chainNonces = k.GetAllChainNonces(ctx) + require.NoError(t, err) + require.Equal(t, 1, len(chainNonces)) + }) +} + +func TestKeeper_RemoveFromPendingNonces(t *testing.T) { + t.Run("should remove from pending nonces", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + nonces := sample.PendingNoncesList(t, "sample", 10) + tss := sample.Tss() + // make nonces and pubkey deterministic for test + for i := range nonces { + nonces[i].NonceLow = int64(i) + nonces[i].NonceHigh = nonces[i].NonceLow + 3 + nonces[i].Tss = tss.TssPubkey + } + sort.SliceStable(nonces, func(i, j int) bool { + return nonces[i].ChainId < nonces[j].ChainId + }) + for _, nonce := range nonces { + k.SetPendingNonces(ctx, nonce) + } + + k.RemoveFromPendingNonces(ctx, tss.TssPubkey, 1, 1) + pendingNonces, err := k.GetAllPendingNonces(ctx) + require.NoError(t, err) + nonceUpdated := false + for _, pn := range pendingNonces { + if pn.ChainId == 1 { + require.Equal(t, int64(2), pn.NonceLow) + nonceUpdated = true + } + } + require.True(t, nonceUpdated) }) } diff --git a/x/observer/keeper/tss_funds_migrator_test.go b/x/observer/keeper/tss_funds_migrator_test.go index 1d32f19f92..620fa2ca06 100644 --- a/x/observer/keeper/tss_funds_migrator_test.go +++ b/x/observer/keeper/tss_funds_migrator_test.go @@ -12,10 +12,16 @@ func TestKeeper_GetTssFundMigrator(t *testing.T) { t.Run("Successfully set funds migrator for chain", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) chain := sample.TssFundsMigrator(1) + _, found := k.GetFundMigrator(ctx, chain.ChainId) + require.False(t, found) k.SetFundMigrator(ctx, chain) tfm, found := k.GetFundMigrator(ctx, chain.ChainId) require.True(t, found) require.Equal(t, chain, tfm) + + k.RemoveAllExistingMigrators(ctx) + _, found = k.GetFundMigrator(ctx, chain.ChainId) + require.False(t, found) }) t.Run("Verify only one migrator can be created for a chain", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) @@ -28,5 +34,4 @@ func TestKeeper_GetTssFundMigrator(t *testing.T) { require.Equal(t, 1, len(migratorList)) require.Equal(t, tfm2, migratorList[0]) }) - } diff --git a/x/observer/keeper/tss_test.go b/x/observer/keeper/tss_test.go index 6408f4f49a..a1f1ca6ddc 100644 --- a/x/observer/keeper/tss_test.go +++ b/x/observer/keeper/tss_test.go @@ -9,14 +9,10 @@ import ( "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestTSSGet(t *testing.T) { +func TestKeeper_GetTSS(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) tss := sample.Tss() k.SetTSS(ctx, tss) @@ -25,7 +21,7 @@ func TestTSSGet(t *testing.T) { require.Equal(t, tss, tssQueried) } -func TestTSSRemove(t *testing.T) { +func TestKeeper_RemoveTSS(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) tss := sample.Tss() k.SetTSS(ctx, tss) @@ -34,83 +30,34 @@ func TestTSSRemove(t *testing.T) { require.False(t, found) } -func TestTSSQuerySingle(t *testing.T) { +func TestKeeper_CheckIfTssPubkeyHasBeenGenerated(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - wctx := sdk.WrapSDKContext(ctx) - //msgs := createTSS(keeper, ctx, 1) tss := sample.Tss() - k.SetTSS(ctx, tss) - for _, tc := range []struct { - desc string - request *types.QueryGetTSSRequest - response *types.QueryGetTSSResponse - err error - }{ - { - desc: "First", - request: &types.QueryGetTSSRequest{}, - response: &types.QueryGetTSSResponse{TSS: tss}, - }, - { - desc: "InvalidRequest", - err: status.Error(codes.InvalidArgument, "invalid request"), - }, - } { - tc := tc - t.Run(tc.desc, func(t *testing.T) { - response, err := k.TSS(wctx, tc.request) - if tc.err != nil { - require.ErrorIs(t, err, tc.err) - } else { - require.Equal(t, tc.response, response) - } - }) - } + + generated, found := k.CheckIfTssPubkeyHasBeenGenerated(ctx, tss.TssPubkey) + require.False(t, found) + require.Equal(t, types.TSS{}, generated) + + k.AppendTss(ctx, tss) + + generated, found = k.CheckIfTssPubkeyHasBeenGenerated(ctx, tss.TssPubkey) + require.True(t, found) + require.Equal(t, tss, generated) } -func TestTSSQueryHistory(t *testing.T) { +func TestKeeper_GetHistoricalTssByFinalizedHeight(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) - wctx := sdk.WrapSDKContext(ctx) - for _, tc := range []struct { - desc string - tssCount int - foundPrevious bool - err error - }{ - { - desc: "1 Tss addresses", - tssCount: 1, - foundPrevious: false, - err: nil, - }, - { - desc: "10 Tss addresses", - tssCount: 10, - foundPrevious: true, - err: nil, - }, - } { - tc := tc - t.Run(tc.desc, func(t *testing.T) { - tssList := sample.TssList(tc.tssCount) - for _, tss := range tssList { - k.SetTSS(ctx, tss) - k.SetTSSHistory(ctx, tss) - } - request := &types.QueryTssHistoryRequest{} - response, err := k.TssHistory(wctx, request) - if tc.err != nil { - require.ErrorIs(t, err, tc.err) - } else { - require.Equal(t, len(tssList), len(response.TssList)) - prevTss, found := k.GetPreviousTSS(ctx) - require.Equal(t, tc.foundPrevious, found) - if found { - require.Equal(t, tssList[len(tssList)-2], prevTss) - } - } - }) + tssList := sample.TssList(100) + r := rand.Intn((len(tssList)-1)-0) + 0 + _, found := k.GetHistoricalTssByFinalizedHeight(ctx, tssList[r].FinalizedZetaHeight) + require.False(t, found) + + for _, tss := range tssList { + k.SetTSSHistory(ctx, tss) } + tss, found := k.GetHistoricalTssByFinalizedHeight(ctx, tssList[r].FinalizedZetaHeight) + require.True(t, found) + require.Equal(t, tssList[r], tss) } func TestKeeper_TssHistory(t *testing.T) { @@ -165,15 +112,4 @@ func TestKeeper_TssHistory(t *testing.T) { }) require.Equal(t, tssList, rst) }) - t.Run("Get historical TSS", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - tssList := sample.TssList(100) - for _, tss := range tssList { - k.SetTSSHistory(ctx, tss) - } - r := rand.Intn((len(tssList)-1)-0) + 0 - tss, found := k.GetHistoricalTssByFinalizedHeight(ctx, tssList[r].FinalizedZetaHeight) - require.True(t, found) - require.Equal(t, tssList[r], tss) - }) } diff --git a/x/observer/keeper/utils.go b/x/observer/keeper/utils.go index 322d45387f..566b559630 100644 --- a/x/observer/keeper/utils.go +++ b/x/observer/keeper/utils.go @@ -88,7 +88,7 @@ func (k Keeper) IsValidator(ctx sdk.Context, creator string) error { return types.ErrNotValidator } - if validator.Jailed == true || validator.IsBonded() == false { + if validator.Jailed || !validator.IsBonded() { return types.ErrValidatorStatus } return nil @@ -135,7 +135,6 @@ func (k Keeper) CheckObserverSelfDelegation(ctx sdk.Context, accAddress string) return err } tokens := validator.TokensFromShares(delegation.Shares) - if tokens.LT(minDelegation) { k.RemoveObserverFromSet(ctx, accAddress) } diff --git a/x/observer/keeper/utils_test.go b/x/observer/keeper/utils_test.go index 9d4b8c54e2..4aedd8ad13 100644 --- a/x/observer/keeper/utils_test.go +++ b/x/observer/keeper/utils_test.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" @@ -61,13 +62,14 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) k.SetObserverSet(ctx, types.ObserverSet{ ObserverList: []string{accAddressOfValidator.String()}, }) require.True(t, k.IsNonTombstonedObserver(ctx, accAddressOfValidator.String())) - }) + t.Run("not authorized for tombstoned observer", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) @@ -87,13 +89,15 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + k.SetObserverSet(ctx, types.ObserverSet{ ObserverList: []string{accAddressOfValidator.String()}, }) require.False(t, k.IsNonTombstonedObserver(ctx, accAddressOfValidator.String())) - }) + t.Run("not authorized for non-validator observer", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) @@ -113,11 +117,205 @@ func TestKeeper_IsAuthorized(t *testing.T) { }) accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + k.SetObserverSet(ctx, types.ObserverSet{ ObserverList: []string{accAddressOfValidator.String()}, }) require.False(t, k.IsNonTombstonedObserver(ctx, accAddressOfValidator.String())) + }) +} + +func TestKeeper_CheckObserverSelfDelegation(t *testing.T) { + t.Run("should error if accAddress invalid", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + err := k.CheckObserverSelfDelegation(ctx, "invalid") + require.Error(t, err) + }) + + t.Run("should error if validator not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + accAddress := sample.AccAddress() + err := k.CheckObserverSelfDelegation(ctx, accAddress) + require.Error(t, err) + }) + + t.Run("should error if delegation not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + err = k.CheckObserverSelfDelegation(ctx, accAddressOfValidator.String()) + require.Error(t, err) + }) + + t.Run("should remove from observer list if tokens less than min del", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.DelegatorShares = sdk.NewDec(100) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + k.GetStakingKeeper().SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: accAddressOfValidator.String(), + ValidatorAddress: validator.GetOperator().String(), + Shares: sdk.NewDec(10), + }) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + err = k.CheckObserverSelfDelegation(ctx, accAddressOfValidator.String()) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Empty(t, os.ObserverList) + }) + + t.Run("should not remove from observer list if tokens gte than min del", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + + validator.DelegatorShares = sdk.NewDec(1) + validator.Tokens = sdk.NewInt(1) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + minDelegation, err := types.GetMinObserverDelegationDec() + require.NoError(t, err) + k.GetStakingKeeper().SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: accAddressOfValidator.String(), + ValidatorAddress: validator.GetOperator().String(), + Shares: minDelegation, + }) + + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{accAddressOfValidator.String()}, + }) + err = k.CheckObserverSelfDelegation(ctx, accAddressOfValidator.String()) + require.NoError(t, err) + + os, found := k.GetObserverSet(ctx) + require.True(t, found) + require.Equal(t, 1, len(os.ObserverList)) + require.Equal(t, accAddressOfValidator.String(), os.ObserverList[0]) + }) +} + +func TestKeeper_IsOpeartorTombstoned(t *testing.T) { + t.Run("should err if invalid addr", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + res, err := k.IsOperatorTombstoned(ctx, "invalid") + require.Error(t, err) + require.False(t, res) + }) + + t.Run("should error if validator not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + accAddress := sample.AccAddress() + res, err := k.IsOperatorTombstoned(ctx, accAddress) + require.Error(t, err) + require.False(t, res) + }) + + t.Run("should not error if validator found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + res, err := k.IsOperatorTombstoned(ctx, accAddressOfValidator.String()) + require.NoError(t, err) + require.False(t, res) + }) +} + +func TestKeeper_IsValidator(t *testing.T) { + t.Run("should err if invalid addr", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + err := k.IsValidator(ctx, "invalid") + require.Error(t, err) + }) + + t.Run("should error if validator not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + accAddress := sample.AccAddress() + err := k.IsValidator(ctx, accAddress) + require.Error(t, err) + }) + + t.Run("should err if validator not bonded", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + err = k.IsValidator(ctx, accAddressOfValidator.String()) + require.Error(t, err) + }) + + t.Run("should err if validator jailed", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.Status = stakingtypes.Bonded + validator.Jailed = true + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + err = k.IsValidator(ctx, accAddressOfValidator.String()) + require.Error(t, err) + }) + + t.Run("should not err if validator not jailed and bonded", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + + r := rand.New(rand.NewSource(9)) + validator := sample.Validator(t, r) + validator.Status = stakingtypes.Bonded + validator.Jailed = false + k.GetStakingKeeper().SetValidator(ctx, validator) + accAddressOfValidator, err := types.GetAccAddressFromOperatorAddress(validator.OperatorAddress) + require.NoError(t, err) + + err = k.IsValidator(ctx, accAddressOfValidator.String()) + require.NoError(t, err) + }) +} + +func TestKeeper_FindBallot(t *testing.T) { + t.Run("should err if chain params not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + _, _, err := k.FindBallot(ctx, "index", &chains.Chain{ + ChainId: 987, + }, types.ObservationType_InBoundTx) + require.Error(t, err) }) } diff --git a/x/observer/keeper/vote_inbound_test.go b/x/observer/keeper/vote_inbound_test.go index 41a3999b75..5b1c09e81b 100644 --- a/x/observer/keeper/vote_inbound_test.go +++ b/x/observer/keeper/vote_inbound_test.go @@ -258,6 +258,57 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) { require.True(t, isNew) }) + t.Run("fail if can not add vote", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll) + + observer := sample.AccAddress() + stakingMock := keepertest.GetObserverStakingMock(t, k) + slashingMock := keepertest.GetObserverSlashingMock(t, k) + + k.SetCrosschainFlags(ctx, types.CrosschainFlags{ + IsInboundEnabled: true, + }) + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + { + ChainId: getValidEthChainIDWithIndex(t, 0), + IsSupported: true, + }, + { + ChainId: getValidEthChainIDWithIndex(t, 1), + IsSupported: true, + }, + }, + }) + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{observer}, + }) + stakingMock.MockGetValidator(sample.Validator(t, sample.Rand())) + slashingMock.MockIsTombstoned(false) + ballot := types.Ballot{ + Index: "index", + BallotIdentifier: "index", + VoterList: []string{observer}, + // already voted + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotThreshold: sdk.NewDec(2), + } + k.SetBallot(ctx, &ballot) + isFinalized, isNew, err := k.VoteOnInboundBallot( + ctx, + getValidEthChainIDWithIndex(t, 0), + getValidEthChainIDWithIndex(t, 1), + coin.CoinType_ERC20, + observer, + "index", + "inTxHash", + ) + require.Error(t, err) + require.False(t, isFinalized) + require.False(t, isNew) + }) + t.Run("can add vote and create ballot without finalizing ballot", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll) diff --git a/x/observer/keeper/vote_outbound_test.go b/x/observer/keeper/vote_outbound_test.go index fa34a11ca6..c92fec5927 100644 --- a/x/observer/keeper/vote_outbound_test.go +++ b/x/observer/keeper/vote_outbound_test.go @@ -133,6 +133,48 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) { require.Equal(t, expectedBallot, ballot) }) + t.Run("fail if can not add vote", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll) + + observer := sample.AccAddress() + stakingMock := keepertest.GetObserverStakingMock(t, k) + slashingMock := keepertest.GetObserverSlashingMock(t, k) + + k.SetChainParamsList(ctx, types.ChainParamsList{ + ChainParams: []*types.ChainParams{ + { + ChainId: getValidEthChainIDWithIndex(t, 0), + IsSupported: true, + }, + }, + }) + k.SetObserverSet(ctx, types.ObserverSet{ + ObserverList: []string{observer}, + }) + stakingMock.MockGetValidator(sample.Validator(t, sample.Rand())) + slashingMock.MockIsTombstoned(false) + ballot := types.Ballot{ + Index: "index", + BallotIdentifier: "index", + VoterList: []string{observer}, + // already voted + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotThreshold: sdk.NewDec(2), + } + k.SetBallot(ctx, &ballot) + isFinalized, isNew, ballot, _, err := k.VoteOnOutboundBallot( + ctx, + "index", + getValidEthChainIDWithIndex(t, 0), + chains.ReceiveStatus_Success, + observer, + ) + require.Error(t, err) + require.False(t, isFinalized) + require.False(t, isNew) + }) + t.Run("can add vote and create ballot without finalizing ballot", func(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll) diff --git a/x/observer/types/ballot.go b/x/observer/types/ballot.go index 811a1b7688..71512c9f11 100644 --- a/x/observer/types/ballot.go +++ b/x/observer/types/ballot.go @@ -14,12 +14,18 @@ func (m Ballot) AddVote(address string, vote VoteType) (Ballot, error) { // `index` is the index of the `address` in the `VoterList` // `index` is used to set the vote in the `Votes` array index := m.GetVoterIndex(address) + if index == -1 { + return m, cosmoserrors.Wrap(ErrUnableToAddVote, fmt.Sprintf("Voter %s not in voter list", address)) + } m.Votes[index] = vote return m, nil } func (m Ballot) HasVoted(address string) bool { index := m.GetVoterIndex(address) + if index == -1 { + return false + } return m.Votes[index] != VoteType_NotYetVoted } diff --git a/x/observer/types/ballot.pb.go b/x/observer/types/ballot.pb.go index 7e8c40afeb..8e9313d1dd 100644 --- a/x/observer/types/ballot.pb.go +++ b/x/observer/types/ballot.pb.go @@ -81,6 +81,7 @@ func (BallotStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor_9eac86b249c97b5b, []int{1} } +// https://github.com/zeta-chain/node/issues/939 type Ballot struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` BallotIdentifier string `protobuf:"bytes,2,opt,name=ballot_identifier,json=ballotIdentifier,proto3" json:"ballot_identifier,omitempty"` diff --git a/x/observer/types/ballot_test.go b/x/observer/types/ballot_test.go index 2bd6441c48..322affd728 100644 --- a/x/observer/types/ballot_test.go +++ b/x/observer/types/ballot_test.go @@ -21,6 +21,7 @@ func TestBallot_AddVote(t *testing.T) { finalVotes []VoteType finalStatus BallotStatus isFinalized bool + wantErr bool }{ { name: "All success", @@ -188,6 +189,18 @@ func TestBallot_AddVote(t *testing.T) { finalStatus: BallotStatus_BallotInProgress, isFinalized: false, }, + { + name: "Voter not in voter list", + threshold: sdk.MustNewDecFromStr("0.66"), + voterList: []string{}, + votes: []votes{ + {"Observer5", VoteType_SuccessObservation}, + }, + wantErr: true, + finalVotes: []VoteType{}, + finalStatus: BallotStatus_BallotInProgress, + isFinalized: false, + }, } for _, test := range tt { test := test @@ -202,7 +215,11 @@ func TestBallot_AddVote(t *testing.T) { BallotStatus: BallotStatus_BallotInProgress, } for _, vote := range test.votes { - ballot, _ = ballot.AddVote(vote.address, vote.vote) + b, err := ballot.AddVote(vote.address, vote.vote) + if test.wantErr { + require.Error(t, err) + } + ballot = b } finalBallot, isFinalized := ballot.IsFinalizingVote() diff --git a/x/observer/types/chain_params_test.go b/x/observer/types/chain_params_test.go index 0bdc9d814d..2100fe2071 100644 --- a/x/observer/types/chain_params_test.go +++ b/x/observer/types/chain_params_test.go @@ -3,6 +3,7 @@ package types_test import ( "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/zeta-chain/zetacore/x/observer/types" @@ -196,4 +197,23 @@ func (s *UpdateChainParamsSuite) Validate(params *types.ChainParams) { copy.OutboundTxScheduleLookahead = 501 err = types.ValidateChainParams(©) require.NotNil(s.T(), err) + + copy = *params + copy.BallotThreshold = sdk.Dec{} + err = types.ValidateChainParams(©) + require.NotNil(s.T(), err) + copy.BallotThreshold = sdk.MustNewDecFromStr("1.2") + err = types.ValidateChainParams(©) + require.NotNil(s.T(), err) + copy.BallotThreshold = sdk.MustNewDecFromStr("0.9") + err = types.ValidateChainParams(©) + require.Nil(s.T(), err) + + copy = *params + copy.MinObserverDelegation = sdk.Dec{} + err = types.ValidateChainParams(©) + require.NotNil(s.T(), err) + copy.MinObserverDelegation = sdk.MustNewDecFromStr("0.9") + err = types.ValidateChainParams(©) + require.Nil(s.T(), err) } diff --git a/x/observer/types/crosschain_flags_test.go b/x/observer/types/crosschain_flags_test.go new file mode 100644 index 0000000000..9939f8b909 --- /dev/null +++ b/x/observer/types/crosschain_flags_test.go @@ -0,0 +1,19 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestDefaultDefaultCrosschainFlags(t *testing.T) { + defaultCrosschainFlags := types.DefaultCrosschainFlags() + + require.Equal(t, &types.CrosschainFlags{ + IsInboundEnabled: true, + IsOutboundEnabled: true, + GasPriceIncreaseFlags: &types.DefaultGasPriceIncreaseFlags, + BlockHeaderVerificationFlags: &types.DefaultBlockHeaderVerificationFlags, + }, defaultCrosschainFlags) +} diff --git a/x/observer/types/expected_keepers.go b/x/observer/types/expected_keepers.go index ba1c9ab9c2..5f402c2689 100644 --- a/x/observer/types/expected_keepers.go +++ b/x/observer/types/expected_keepers.go @@ -11,6 +11,7 @@ type StakingKeeper interface { GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation stakingtypes.Delegation, found bool) SetValidator(ctx sdk.Context, validator stakingtypes.Validator) + SetDelegation(ctx sdk.Context, delegation stakingtypes.Delegation) } type SlashingKeeper interface { diff --git a/x/observer/types/genesis_test.go b/x/observer/types/genesis_test.go index 1ba8212a35..676bca7d62 100644 --- a/x/observer/types/genesis_test.go +++ b/x/observer/types/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -12,6 +13,14 @@ func TestGenesisState_Validate(t *testing.T) { chainParams := types.GetDefaultChainParams().ChainParams invalidChainParamsGen.ChainParamsList.ChainParams = append(chainParams, chainParams[0]) + gsWithDuplicateNodeAccountList := types.DefaultGenesis() + nodeAccount := sample.NodeAccount() + gsWithDuplicateNodeAccountList.NodeAccountList = []*types.NodeAccount{nodeAccount, nodeAccount} + + gsWithDuplicateChainNonces := types.DefaultGenesis() + chainNonce := sample.ChainNonces(t, "0") + gsWithDuplicateChainNonces.ChainNonces = []types.ChainNonces{chainNonce, chainNonce} + for _, tc := range []struct { desc string genState *types.GenesisState @@ -32,6 +41,16 @@ func TestGenesisState_Validate(t *testing.T) { genState: invalidChainParamsGen, valid: false, }, + { + desc: "invalid genesis state duplicate node account list", + genState: gsWithDuplicateNodeAccountList, + valid: false, + }, + { + desc: "invalid genesis state duplicate chain nonces", + genState: gsWithDuplicateChainNonces, + valid: false, + }, } { t.Run(tc.desc, func(t *testing.T) { err := tc.genState.Validate() diff --git a/x/observer/types/observer_set_test.go b/x/observer/types/observer_set_test.go new file mode 100644 index 0000000000..5efce2cd81 --- /dev/null +++ b/x/observer/types/observer_set_test.go @@ -0,0 +1,32 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestObserverSet(t *testing.T) { + observerSet := sample.ObserverSet(4) + + require.Equal(t, int(4), observerSet.Len()) + require.Equal(t, uint64(4), observerSet.LenUint()) + err := observerSet.Validate() + require.NoError(t, err) + + observerSet.ObserverList[0] = "invalid" + err = observerSet.Validate() + require.Error(t, err) +} + +func TestCheckReceiveStatus(t *testing.T) { + err := types.CheckReceiveStatus(chains.ReceiveStatus_Success) + require.NoError(t, err) + err = types.CheckReceiveStatus(chains.ReceiveStatus_Failed) + require.NoError(t, err) + err = types.CheckReceiveStatus(chains.ReceiveStatus_Created) + require.Error(t, err) +} diff --git a/x/observer/types/params.go b/x/observer/types/params.go index 7fc72c1e89..ea1db66657 100644 --- a/x/observer/types/params.go +++ b/x/observer/types/params.go @@ -100,6 +100,7 @@ func validateAdminPolicy(i interface{}) error { return nil } +// https://github.com/zeta-chain/node/issues/1983 func validateBallotMaturityBlocks(i interface{}) error { _, ok := i.(int64) if !ok { @@ -108,12 +109,3 @@ func validateBallotMaturityBlocks(i interface{}) error { return nil } - -func (p Params) GetAdminPolicyAccount(policyType Policy_Type) string { - for _, admin := range p.AdminPolicy { - if admin.PolicyType == policyType { - return admin.Address - } - } - return "" -} diff --git a/x/observer/types/params_test.go b/x/observer/types/params_test.go new file mode 100644 index 0000000000..3b7b177565 --- /dev/null +++ b/x/observer/types/params_test.go @@ -0,0 +1,74 @@ +package types + +import ( + "reflect" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" +) + +func TestParamKeyTable(t *testing.T) { + kt := ParamKeyTable() + + ps := Params{} + for _, psp := range ps.ParamSetPairs() { + require.PanicsWithValue(t, "duplicate parameter key", func() { + kt.RegisterType(psp) + }) + } +} + +func TestParamSetPairs(t *testing.T) { + params := DefaultParams() + pairs := params.ParamSetPairs() + + require.Equal(t, 3, len(pairs), "The number of param set pairs should match the expected count") + + assertParamSetPair(t, pairs, KeyPrefix(ObserverParamsKey), ¶ms.ObserverParams, validateVotingThresholds) + assertParamSetPair(t, pairs, KeyPrefix(AdminPolicyParamsKey), ¶ms.AdminPolicy, validateAdminPolicy) + assertParamSetPair(t, pairs, KeyPrefix(BallotMaturityBlocksParamsKey), ¶ms.BallotMaturityBlocks, validateBallotMaturityBlocks) +} + +func assertParamSetPair(t *testing.T, pairs paramtypes.ParamSetPairs, key []byte, expectedValue interface{}, valFunc paramtypes.ValueValidatorFn) { + for _, pair := range pairs { + if string(pair.Key) == string(key) { + require.Equal(t, expectedValue, pair.Value, "Value does not match for key %s", string(key)) + + actualValFunc := pair.ValidatorFn + require.Equal(t, reflect.ValueOf(valFunc).Pointer(), reflect.ValueOf(actualValFunc).Pointer(), "Val func doesnt match for key %s", string(key)) + return + } + } + + t.Errorf("Key %s not found in ParamSetPairs", string(key)) +} + +func TestParamsString(t *testing.T) { + params := DefaultParams() + out, err := yaml.Marshal(params) + require.NoError(t, err) + require.Equal(t, string(out), params.String()) +} + +func TestValidateVotingThresholds(t *testing.T) { + require.Error(t, validateVotingThresholds("invalid")) + + params := DefaultParams() + require.NoError(t, validateVotingThresholds(params.ObserverParams)) + + params.ObserverParams[0].BallotThreshold = sdk.MustNewDecFromStr("1.1") + require.Error(t, validateVotingThresholds(params.ObserverParams)) +} + +func TestValidateAdminPolicy(t *testing.T) { + require.Error(t, validateAdminPolicy("invalid")) + require.NoError(t, validateAdminPolicy([]*Admin_Policy{})) +} + +func TestValidateBallotMaturityBlocks(t *testing.T) { + require.Error(t, validateBallotMaturityBlocks("invalid")) + require.NoError(t, validateBallotMaturityBlocks(int64(1))) +} diff --git a/x/observer/types/parsers_test.go b/x/observer/types/parsers_test.go new file mode 100644 index 0000000000..1c108fcee8 --- /dev/null +++ b/x/observer/types/parsers_test.go @@ -0,0 +1,98 @@ +package types_test + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestConvertReceiveStatusToVoteType(t *testing.T) { + tests := []struct { + name string + status chains.ReceiveStatus + expected types.VoteType + }{ + {"TestSuccessStatus", chains.ReceiveStatus_Success, types.VoteType_SuccessObservation}, + {"TestFailedStatus", chains.ReceiveStatus_Failed, types.VoteType_FailureObservation}, + {"TestDefaultStatus", chains.ReceiveStatus_Created, types.VoteType_NotYetVoted}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := types.ConvertReceiveStatusToVoteType(tt.status) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestParseStringToObservationType(t *testing.T) { + tests := []struct { + name string + observationType string + expected types.ObservationType + }{ + {"TestValidObservationType1", "EmptyObserverType", types.ObservationType(0)}, + {"TestValidObservationType1", "InBoundTx", types.ObservationType(1)}, + {"TestValidObservationType1", "OutBoundTx", types.ObservationType(2)}, + {"TestValidObservationType1", "TSSKeyGen", types.ObservationType(3)}, + {"TestValidObservationType1", "TSSKeySign", types.ObservationType(4)}, + {"TestInvalidObservationType", "InvalidType", types.ObservationType(0)}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := types.ParseStringToObservationType(tt.observationType) + require.Equal(t, tt.expected, result) + }) + } +} + +func TestGetOperatorAddressFromAccAddress(t *testing.T) { + tests := []struct { + name string + accAddr string + wantErr bool + }{ + {"TestValidAccAddress", sample.AccAddress(), false}, + {"TestInvalidAccAddress", "invalid", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := types.GetOperatorAddressFromAccAddress(tt.accAddr) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestGetAccAddressFromOperatorAddress(t *testing.T) { + // #nosec G404 test purpose - weak randomness is not an issue here + r := rand.New(rand.NewSource(1)) + tests := []struct { + name string + valAddress string + wantErr bool + }{ + {"TestValidValAddress", sample.ValAddress(r).String(), false}, + {"TestInvalidValAddress", "invalid", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := types.GetAccAddressFromOperatorAddress(tt.valAddress) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/observer/types/test_data.go b/x/observer/types/test_data.go deleted file mode 100644 index 3a43ca4306..0000000000 --- a/x/observer/types/test_data.go +++ /dev/null @@ -1,27 +0,0 @@ -package types - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -const ( - AccountAddressPrefix = "zeta" -) - -var ( - AccountPubKeyPrefix = AccountAddressPrefix + "pub" - ValidatorAddressPrefix = AccountAddressPrefix + "valoper" - ValidatorPubKeyPrefix = AccountAddressPrefix + "valoperpub" - ConsNodeAddressPrefix = AccountAddressPrefix + "valcons" - ConsNodePubKeyPrefix = AccountAddressPrefix + "valconspub" -) - -func SetConfig(seal bool) { - config := sdk.GetConfig() - config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix) - config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix) - config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix) - if seal { - config.Seal() - } -} diff --git a/x/observer/types/utils_test.go b/x/observer/types/utils_test.go new file mode 100644 index 0000000000..ac42ea127c --- /dev/null +++ b/x/observer/types/utils_test.go @@ -0,0 +1,55 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/go-tss/blame" + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestConvertNodes(t *testing.T) { + tests := []struct { + name string + input []blame.Node + expected []*types.Node + }{ + { + name: "TestEmptyInput", + input: []blame.Node{}, + expected: nil, + }, + { + name: "TestNilInput", + input: nil, + expected: nil, + }, + { + name: "TestSingleInput", + input: []blame.Node{ + {Pubkey: "pubkey1", BlameSignature: []byte("signature1"), BlameData: []byte("data1")}, + }, + expected: []*types.Node{ + {PubKey: "pubkey1", BlameSignature: []byte("signature1"), BlameData: []byte("data1")}, + }, + }, + { + name: "TestMultipleInputs", + input: []blame.Node{ + {Pubkey: "pubkey1", BlameSignature: []byte("signature1"), BlameData: []byte("data1")}, + {Pubkey: "pubkey2", BlameSignature: []byte("signature2"), BlameData: []byte("data2")}, + }, + expected: []*types.Node{ + {PubKey: "pubkey1", BlameSignature: []byte("signature1"), BlameData: []byte("data1")}, + {PubKey: "pubkey2", BlameSignature: []byte("signature2"), BlameData: []byte("data2")}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := types.ConvertNodes(tt.input) + require.Equal(t, tt.expected, result) + }) + } +}