diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f5030b1152..3cbbc56594 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -13,46 +13,10 @@ on: - cron: "0 6 * * *" workflow_dispatch: inputs: - default-test: - type: boolean - required: false - default: false - upgrade-light-test: - type: boolean - required: false - default: false - upgrade-test: - type: boolean - required: false - default: false - admin-test: - type: boolean - required: false - default: false - upgrade-import-mainnet-test: - type: boolean - required: false - default: false - performance-test: - type: boolean - required: false - default: false - stateful-data-test: - type: boolean - required: false - default: false - tss-migration-test: - type: boolean - required: false - default: false - solana-test: - type: boolean - required: false - default: false - v2-test: - type: boolean - required: false - default: false + make-targets: + description: 'Comma separated list of make targets to run (without the start- prefix)' + required: true + default: '' concurrency: group: e2e-${{ github.head_ref || github.sha }} @@ -124,16 +88,17 @@ jobs: core.setOutput('SOLANA_TESTS', true); core.setOutput('V2_TESTS', true); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) } else if (context.eventName === 'workflow_dispatch') { - core.setOutput('DEFAULT_TESTS', context.payload.inputs['default-test']); - core.setOutput('UPGRADE_TESTS', context.payload.inputs['upgrade-test']); - core.setOutput('UPGRADE_LIGHT_TESTS', context.payload.inputs['upgrade-light-test']); - core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', context.payload.inputs['upgrade-import-mainnet-test']); - core.setOutput('ADMIN_TESTS', context.payload.inputs['admin-test']); - core.setOutput('PERFORMANCE_TESTS', context.payload.inputs['performance-test']); - core.setOutput('STATEFUL_DATA_TESTS', context.payload.inputs['stateful-data-test']); - core.setOutput('TSS_MIGRATION_TESTS', context.payload.inputs['tss-migration-test']); - core.setOutput('SOLANA_TESTS', context.payload.inputs['solana-test']); - core.setOutput('V2_TESTS', context.payload.inputs['v2-test']); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) + const makeTargets = context.payload.inputs['make-targets'].split(','); + core.setOutput('DEFAULT_TESTS', makeTargets.includes('default-test')); + core.setOutput('UPGRADE_TESTS', makeTargets.includes('upgrade-test')); + core.setOutput('UPGRADE_LIGHT_TESTS', makeTargets.includes('upgrade-test-light')); + core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', makeTargets.includes('upgrade-import-mainnet-test')); + core.setOutput('ADMIN_TESTS', makeTargets.includes('admin-test')); + core.setOutput('PERFORMANCE_TESTS', makeTargets.includes('performance-test')); + core.setOutput('STATEFUL_DATA_TESTS', makeTargets.includes('import-mainnet-test')); + core.setOutput('TSS_MIGRATION_TESTS', makeTargets.includes('tss-migration-test')); + core.setOutput('SOLANA_TESTS', makeTargets.includes('solana-test')); + core.setOutput('V2_TESTS', makeTargets.includes('v2-test')); // for v2 tests, TODO: remove this once we fully migrate to v2 (https://github.com/zeta-chain/node/issues/2627) } e2e: @@ -168,6 +133,7 @@ jobs: - make-target: "start-tss-migration-test" runs-on: ubuntu-20.04 run: ${{ needs.matrix-conditionals.outputs.TSS_MIGRATION_TESTS == 'true' }} + timeout-minutes: 40 - make-target: "start-solana-test" runs-on: ubuntu-20.04 run: ${{ needs.matrix-conditionals.outputs.SOLANA_TESTS == 'true' }} diff --git a/.github/workflows/generate-files.yml b/.github/workflows/generate-files.yml index a5f9f6d4e1..1abbbb91ee 100644 --- a/.github/workflows/generate-files.yml +++ b/.github/workflows/generate-files.yml @@ -18,6 +18,10 @@ jobs: run: | echo "$HOME/go/bin" >> $GITHUB_PATH + - name: Install solc-select + run: | + pip3 install solc-select + - name: Generate Go code, docs and specs env: TEST_ENV: ${{ github.workspace }} diff --git a/Dockerfile-localnet b/Dockerfile-localnet index f5df2a671a..6be3ba3e03 100644 --- a/Dockerfile-localnet +++ b/Dockerfile-localnet @@ -24,7 +24,7 @@ RUN --mount=type=cache,target="/root/.cache/go-build" make install RUN --mount=type=cache,target="/root/.cache/go-build" make install-zetae2e FROM ghcr.io/zeta-chain/golang:1.22.5-bookworm AS cosmovisor-build -RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.5.0 +RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@v1.6.0 FROM ghcr.io/zeta-chain/golang:1.22.5-bookworm AS base-runtime diff --git a/Makefile b/Makefile index 51931ea89b..aa4fcff5d0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ .PHONY: build +PACKAGE_NAME := github.com/zeta-chain/node VERSION := $(shell ./version.sh) COMMIT := $(shell [ -z "${COMMIT_ID}" ] && git log -1 --format='%H' || echo ${COMMIT_ID} ) BUILDTIME := $(shell date -u +"%Y%m%d.%H%M%S" ) @@ -8,7 +9,9 @@ DOCKER ?= docker # useful for setting profiles DOCKER_COMPOSE ?= $(DOCKER) compose $(COMPOSE_ARGS) DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf -GOFLAGS:="" +GOFLAGS := "" +GOLANG_CROSS_VERSION ?= v1.22.4 +GOPATH ?= '$(HOME)/go' ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=zetacore \ -X github.com/cosmos/cosmos-sdk/version.ServerName=zetacored \ @@ -23,7 +26,7 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=zetacore \ BUILD_FLAGS := -ldflags '$(ldflags)' -tags pebbledb,ledger -TEST_DIR?="./..." +TEST_DIR ?= "./..." TEST_BUILD_FLAGS := -tags pebbledb,ledger HSM_BUILD_FLAGS := -tags pebbledb,ledger,hsm_test @@ -53,11 +56,11 @@ go.sum: go.mod ### Test commands ### ############################################################################### +test: clean-test-dir run-test + run-test: @go test ${TEST_BUILD_FLAGS} ${TEST_DIR} -test :clean-test-dir run-test - test-hsm: @go test ${HSM_BUILD_FLAGS} ${TEST_DIR} @@ -199,8 +202,13 @@ mocks: @bash ./scripts/mocks-generate.sh .PHONY: mocks +precompiles: + @echo "--> Generating bindings for precompiled contracts" + @bash ./scripts/bindings-stateful-precompiles.sh +.PHONY: precompiles + # generate also includes Go code formatting -generate: proto-gen openapi specs typescript docs-zetacored mocks fmt +generate: proto-gen openapi specs typescript docs-zetacored mocks precompiles fmt .PHONY: generate @@ -262,7 +270,8 @@ start-stress-test: zetanode cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile stress -f docker-compose.yml up -d start-tss-migration-test: zetanode - @echo "--> Starting migration test" + @echo "--> Starting tss migration test" + export LOCALNET_MODE=tss-migrate && \ export E2E_ARGS="--test-tss-migration" && \ cd contrib/localnet/ && $(DOCKER_COMPOSE) up -d @@ -293,7 +302,6 @@ zetanode-upgrade: zetanode .PHONY: zetanode-upgrade endif - start-upgrade-test: zetanode-upgrade @echo "--> Starting upgrade test" export LOCALNET_MODE=upgrade && \ @@ -306,7 +314,6 @@ start-upgrade-test-light: zetanode-upgrade export UPGRADE_HEIGHT=90 && \ cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile upgrade -f docker-compose.yml -f docker-compose-upgrade.yml up -d - start-upgrade-test-admin: zetanode-upgrade @echo "--> Starting admin upgrade test" export LOCALNET_MODE=upgrade && \ @@ -326,9 +333,6 @@ start-upgrade-import-mainnet-test: zetanode-upgrade ### GoReleaser ### ############################################################################### -PACKAGE_NAME := github.com/zeta-chain/node -GOLANG_CROSS_VERSION ?= v1.22.4 -GOPATH ?= '$(HOME)/go' release-dry-run: docker run \ --rm \ diff --git a/app/ante/ante.go b/app/ante/ante.go index eee2dd27ec..7c7be0604c 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package ante import ( diff --git a/app/ante/fees.go b/app/ante/fees.go index 054cca7c4f..20c30bcea6 100644 --- a/app/ante/fees.go +++ b/app/ante/fees.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE // Copyright 2023 ZetaChain // modified to exclude gentx transaction type from the min gas price check @@ -26,7 +26,7 @@ import ( errortypes "github.com/cosmos/cosmos-sdk/types/errors" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ethtypes "github.com/ethereum/go-ethereum/core/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) var ( diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index 71d77de243..8af3a82593 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package ante @@ -29,9 +29,9 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - ethante "github.com/evmos/ethermint/app/ante" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + ethante "github.com/zeta-chain/ethermint/app/ante" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" ) diff --git a/app/ante/interfaces.go b/app/ante/interfaces.go index af423e6592..ffe1090121 100644 --- a/app/ante/interfaces.go +++ b/app/ante/interfaces.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package ante @@ -24,10 +24,9 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" - "github.com/evmos/ethermint/x/evm/statedb" - evmtypes "github.com/evmos/ethermint/x/evm/types" - evm "github.com/evmos/ethermint/x/evm/vm" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + "github.com/zeta-chain/ethermint/x/evm/statedb" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" ) // DynamicFeeEVMKeeper is a subset of EVMKeeper interface that supports dynamic fee checker @@ -42,7 +41,7 @@ type EVMKeeper interface { statedb.Keeper DynamicFeeEVMKeeper - NewEVM(ctx sdk.Context, msg core.Message, cfg *statedb.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) evm.EVM + NewEVM(ctx sdk.Context, msg core.Message, cfg *statedb.EVMConfig, tracer vm.EVMLogger, stateDB vm.StateDB) *vm.EVM DeductTxCostsFromUserBalance(ctx sdk.Context, fees sdk.Coins, from common.Address) error GetBalance(ctx sdk.Context, addr common.Address) *big.Int ResetTransientGasUsed(ctx sdk.Context) diff --git a/app/app.go b/app/app.go index 99bca14347..32d85214eb 100644 --- a/app/app.go +++ b/app/app.go @@ -7,7 +7,6 @@ import ( "time" cosmoserrors "cosmossdk.io/errors" - appparams "cosmossdk.io/simapp/params" dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" @@ -78,22 +77,22 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - evmante "github.com/evmos/ethermint/app/ante" - ethermint "github.com/evmos/ethermint/types" - "github.com/evmos/ethermint/x/evm" - evmkeeper "github.com/evmos/ethermint/x/evm/keeper" - evmtypes "github.com/evmos/ethermint/x/evm/types" - "github.com/evmos/ethermint/x/evm/vm/geth" - "github.com/evmos/ethermint/x/feemarket" - feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cast" + evmante "github.com/zeta-chain/ethermint/app/ante" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/ethermint/x/evm" + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/x/feemarket" + feemarketkeeper "github.com/zeta-chain/ethermint/x/feemarket/keeper" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "github.com/zeta-chain/zetacore/app/ante" "github.com/zeta-chain/zetacore/docs/openapi" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" + "github.com/zeta-chain/zetacore/precompiles" srvflags "github.com/zeta-chain/zetacore/server/flags" authoritymodule "github.com/zeta-chain/zetacore/x/authority" authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" @@ -146,16 +145,11 @@ func init() { var ( AccountAddressPrefix = "zeta" NodeDir = ".zetacored" + DefaultNodeHome = os.ExpandEnv("$HOME/") + NodeDir // AddrLen is the allowed length (in bytes) for an address. - // // NOTE: In the SDK, the default value is 255. AddrLen = 20 -) - -var ( - // DefaultNodeHome default home directories for wasmd - DefaultNodeHome = os.ExpandEnv("$HOME/") + NodeDir // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address Bech32PrefixAccAddr = AccountAddressPrefix @@ -315,7 +309,7 @@ func New( skipUpgradeHeights map[int64]bool, homePath string, invCheckPeriod uint, - encodingConfig appparams.EncodingConfig, + encodingConfig ethermint.EncodingConfig, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *App { @@ -356,9 +350,9 @@ func New( consensusparamtypes.StoreKey, crisistypes.StoreKey, ) - tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey) + tKeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey) memKeys := sdk.NewMemoryStoreKeys( - //capabilitytypes.MemStoreKey, + // capabilitytypes.MemStoreKey, ) app := &App{ @@ -368,7 +362,7 @@ func New( interfaceRegistry: interfaceRegistry, invCheckPeriod: invCheckPeriod, keys: keys, - tkeys: tkeys, + tkeys: tKeys, memKeys: memKeys, } if homePath == "" { @@ -378,7 +372,7 @@ func New( // get authority address authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() - app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey]) + app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tKeys[paramstypes.TStoreKey]) // set the BaseApp's parameter store app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.StoreKey], authAddr) bApp.SetParamStore(&app.ConsensusParamsKeeper) @@ -556,25 +550,26 @@ func New( appCodec, authtypes.NewModuleAddress(govtypes.ModuleName), keys[feemarkettypes.StoreKey], - tkeys[feemarkettypes.TransientKey], + tKeys[feemarkettypes.TransientKey], feeSs, app.ConsensusParamsKeeper, ) evmSs := app.GetSubspace(evmtypes.ModuleName) + app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], - tkeys[evmtypes.TransientKey], + tKeys[evmtypes.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, &app.FeeMarketKeeper, - nil, - geth.NewEVM, tracer, evmSs, + precompiles.StatefulContracts(&app.FungibleKeeper, appCodec, storetypes.TransientGasConfig()), app.ConsensusParamsKeeper, + aggregateAllKeys(keys, tKeys, memKeys), ) app.FungibleKeeper = *fungiblekeeper.NewKeeper( @@ -813,7 +808,7 @@ func New( // initialize stores app.MountKVStores(keys) - app.MountTransientStores(tkeys) + app.MountTransientStores(tKeys) app.MountMemoryStores(memKeys) // initialize BaseApp @@ -1055,9 +1050,42 @@ func (app *App) SimulationManager() *module.SimulationManager { func (app *App) BlockedAddrs() map[string]bool { blockList := make(map[string]bool) + for k, v := range blockedReceivingModAcc { addr := authtypes.NewModuleAddress(k) blockList[addr.String()] = v } + + // Each enabled precompiled stateful contract should be added as a BlockedAddrs. + // That way it's marked as non payable by the bank keeper. + for addr, enabled := range precompiles.EnabledStatefulContracts { + if enabled { + blockList[addr.String()] = enabled + } + } + return blockList } + +// aggregateAllKeys aggregates all the keys in a single map. +func aggregateAllKeys( + keys map[string]*storetypes.KVStoreKey, + tKeys map[string]*storetypes.TransientStoreKey, + memKeys map[string]*storetypes.MemoryStoreKey, +) map[string]storetypes.StoreKey { + allKeys := make(map[string]storetypes.StoreKey, len(keys)+len(tKeys)+len(memKeys)) + + for k, v := range keys { + allKeys[k] = v + } + + for k, v := range tKeys { + allKeys[k] = v + } + + for k, v := range memKeys { + allKeys[k] = v + } + + return allKeys +} diff --git a/app/encoding.go b/app/encoding.go index 5d4e7f5305..fed40e3286 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -1,12 +1,12 @@ package app import ( - "cosmossdk.io/simapp/params" - evmenc "github.com/evmos/ethermint/encoding" + evmenc "github.com/zeta-chain/ethermint/encoding" + ethermint "github.com/zeta-chain/ethermint/types" ) // MakeEncodingConfig creates an EncodingConfig for testing -func MakeEncodingConfig() params.EncodingConfig { +func MakeEncodingConfig() ethermint.EncodingConfig { //encodingConfig := params.MakeEncodingConfig() encodingConfig := evmenc.MakeConfig(ModuleBasics) //std.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/init_genesis.go b/app/init_genesis.go index 9f82daefa4..a8765c28d7 100644 --- a/app/init_genesis.go +++ b/app/init_genesis.go @@ -16,8 +16,8 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" diff --git a/app/prefix.go b/app/prefix.go index 7a96bc6292..a0b3cb1936 100644 --- a/app/prefix.go +++ b/app/prefix.go @@ -2,7 +2,7 @@ package app import ( sdk "github.com/cosmos/cosmos-sdk/types" - ethcfg "github.com/evmos/ethermint/cmd/config" + ethcfg "github.com/zeta-chain/ethermint/cmd/config" cmdcfg "github.com/zeta-chain/zetacore/cmd/zetacored/config" ) diff --git a/changelog.md b/changelog.md index 56ac1c8d67..c250691e61 100644 --- a/changelog.md +++ b/changelog.md @@ -14,20 +14,26 @@ * [2681](https://github.com/zeta-chain/node/pull/2681) - implement `MsgUpdateERC20CustodyPauseStatus` to pause or unpause ERC20 Custody contract (to be used for the migration process for smart contract V2) * [2644](https://github.com/zeta-chain/node/pull/2644) - add created_timestamp to cctx status * [2673](https://github.com/zeta-chain/node/pull/2673) - add relayer key importer, encryption and decryption +* [2633](https://github.com/zeta-chain/node/pull/2633) - support for stateful precompiled contracts. * [2751](https://github.com/zeta-chain/node/pull/2751) - add RPC status check for Solana chain +* [2788](https://github.com/zeta-chain/node/pull/2788) - add common importable zetacored rpc package ### Refactor * [2615](https://github.com/zeta-chain/node/pull/2615) - Refactor cleanup of outbound trackers * [2749](https://github.com/zeta-chain/node/pull/2749) - fix all lint errors from govet +* [2725](https://github.com/zeta-chain/node/pull/2725) - refactor SetCctxAndNonceToCctxAndInboundHashToCctx to receive tsspubkey as an argument ### Tests +* [2661](https://github.com/zeta-chain/node/pull/2661) - update connector and erc20Custody addresses in tss migration e2e tests * [2726](https://github.com/zeta-chain/node/pull/2726) - add e2e tests for deposit and call, deposit and revert +* [2703](https://github.com/zeta-chain/node/pull/2703) - add e2e tests for stateful precompiled contracts ### Fixes * [2654](https://github.com/zeta-chain/node/pull/2654) - add validation for authorization list in when validating genesis state for authorization module +* [2674](https://github.com/zeta-chain/node/pull/2674) - allow operators to vote on ballots associated with discarded keygen without affecting the status of the current keygen. * [2672](https://github.com/zeta-chain/node/pull/2672) - check observer set for duplicates when adding a new observer or updating an existing one ## v19.0.0 @@ -70,6 +76,7 @@ * [2524](https://github.com/zeta-chain/node/pull/2524) - add inscription envelop parsing * [2560](https://github.com/zeta-chain/node/pull/2560) - add support for Solana SOL token withdraw * [2533](https://github.com/zeta-chain/node/pull/2533) - parse memo from both OP_RETURN and inscription +* [2765](https://github.com/zeta-chain/node/pull/2765) - bitcoin depositor fee improvement ### Refactor @@ -81,7 +88,7 @@ * [2118](https://github.com/zeta-chain/node/pull/2118) - consolidate inbound and outbound naming * [2124](https://github.com/zeta-chain/node/pull/2124) - removed unused variables and method * [2150](https://github.com/zeta-chain/node/pull/2150) - created `chains` `zetacore` `orchestrator` packages in zetaclient and reorganized source files accordingly -* [2210](https://github.com/zeta-chain/node/pull/2210) - removed uncessary panics in the zetaclientd process +* [2210](https://github.com/zeta-chain/node/pull/2210) - removed unnecessary panics in the zetaclientd process * [2205](https://github.com/zeta-chain/node/pull/2205) - remove deprecated variables pre-v17 * [2226](https://github.com/zeta-chain/node/pull/2226) - improve Go formatting with imports standardization and max line length to 120 * [2262](https://github.com/zeta-chain/node/pull/2262) - refactor MsgUpdateZRC20 into MsgPauseZrc20 and MsgUnPauseZRC20 @@ -149,7 +156,7 @@ ### CI * [2388](https://github.com/zeta-chain/node/pull/2388) - added GitHub attestations of binaries produced in the release workflow. -* [2285](https://github.com/zeta-chain/node/pull/2285) - added nightly EVM performance testing pipeline, modified localnet testing docker image to utilitze debian:bookworm, removed build-jet runners where applicable, removed deprecated/removed upgrade path testing pipeline +* [2285](https://github.com/zeta-chain/node/pull/2285) - added nightly EVM performance testing pipeline, modified localnet testing docker image to utilize debian:bookworm, removed build-jet runners where applicable, removed deprecated/removed upgrade path testing pipeline * [2268](https://github.com/zeta-chain/node/pull/2268) - updated the publish-release pipeline to utilize the Github Actions Ubuntu 20.04 Runners * [2070](https://github.com/zeta-chain/node/pull/2070) - Added commands to build binaries from the working branch as a live full node rpc to test non-governance changes * [2119](https://github.com/zeta-chain/node/pull/2119) - Updated the release pipeline to only run on hotfix/ and release/ branches. Added option to only run pre-checks and not cut release as well. Switched approval steps to use environments @@ -355,8 +362,8 @@ * [1584](https://github.com/zeta-chain/node/pull/1584) - allow to run E2E tests on any networks * [1746](https://github.com/zeta-chain/node/pull/1746) - rename smoke tests to e2e tests * [1753](https://github.com/zeta-chain/node/pull/1753) - fix gosec errors on usage of rand package -* [1762](https://github.com/zeta-chain/node/pull/1762) - improve coverage for fungibile module -* [1782](https://github.com/zeta-chain/node/pull/1782) - improve coverage for fungibile module system contract +* [1762](https://github.com/zeta-chain/node/pull/1762) - improve coverage for fungible module +* [1782](https://github.com/zeta-chain/node/pull/1782) - improve coverage for fungible module system contract ### CI @@ -458,7 +465,7 @@ Observer params and core params have been merged into chain params: * `GetCoreParams`: Renamed into `GetChainParams`. `/zeta-chain/observer/get_core_params` moved to `/zeta-chain/observer/get_chain_params` * `GetCoreParamsByChain`: Renamed into `GetChainParamsForChain`. `/zeta-chain/observer/get_core_params_by_chain` moved to `/zeta-chain/observer/get_chain_params_by_chain` -Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin chain id: +Getting the correct TSS address for Bitcoin now requires providing the Bitcoin chain id: * `GetTssAddress` : Changed from `/zeta-chain/observer/get_tss_address/` to `/zeta-chain/observer/getTssAddress/{bitcoin_chain_id}` . Optional bitcoin chain id can now be passed as a parameter to fetch the correct tss for required BTC chain. This parameter only affects the BTC tss address in the response ### Features @@ -485,7 +492,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * masked zetaclient config at startup * set limit for queried pending cctxs * add check to verify new tss has been produced when triggering tss funds migration -* fix Athens-3 log print issue - avoid posting uncessary outtx confirmation +* fix Athens-3 log print issue - avoid posting unnecessary outtx confirmation * fix docker build issues with version: golang:1.20-alpine3.18 * [1525](https://github.com/zeta-chain/node/pull/1525) - relax EVM chain block header length check 1024->4096 * [1522](https://github.com/zeta-chain/node/pull/1522/files) - block `distribution` module account from receiving zeta @@ -522,7 +529,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1446](https://github.com/zeta-chain/node/pull/1446) - renamed file `zetaclientd/aux.go` to `zetaclientd/utils.go` to avoid complaints from go package resolver * [1499](https://github.com/zeta-chain/node/pull/1499) - Add scripts to localnet to help test gov proposals * [1442](https://github.com/zeta-chain/node/pull/1442) - remove build types in `.goreleaser.yaml` -* [1504](https://github.com/zeta-chain/node/pull/1504) - remove `-race` in the `make install` commmand +* [1504](https://github.com/zeta-chain/node/pull/1504) - remove `-race` in the `make install` command * [1564](https://github.com/zeta-chain/node/pull/1564) - bump ti-actions/changed-files ### Tests @@ -584,7 +591,7 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c * [1128](https://github.com/zeta-chain/node/pull/1228) - adding namespaces back in rpc * [1245](https://github.com/zeta-chain/node/pull/1245) - set unique index for generate cctx * [1250](https://github.com/zeta-chain/node/pull/1250) - remove error return in `IsAuthorized` -* [1261](https://github.com/zeta-chain/node/pull/1261) - Ethereum comparaison checksum/non-checksum format +* [1261](https://github.com/zeta-chain/node/pull/1261) - Ethereum comparison checksum/non-checksum format * [1264](https://github.com/zeta-chain/node/pull/1264) - Blame index update * [1243](https://github.com/zeta-chain/node/pull/1243) - feed sataoshi/B to zetacore and check actual outTx size * [1235](https://github.com/zeta-chain/node/pull/1235) - cherry pick all hotfix from v10.0.x (zero-amount, precision, etc.) diff --git a/cmd/zetaclientd/start_utils.go b/cmd/zetaclientd/start_utils.go index 9692f32b29..e8070ab5d0 100644 --- a/cmd/zetaclientd/start_utils.go +++ b/cmd/zetaclientd/start_utils.go @@ -10,6 +10,7 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/zeta-chain/zetacore/zetaclient/config" ) @@ -20,7 +21,7 @@ func waitForZetaCore(config config.Config, logger zerolog.Logger) { for { _, err := grpc.Dial( fmt.Sprintf("%s:9090", config.ZetaCoreURL), - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { logger.Warn().Err(err).Msg("grpc dial fail") diff --git a/cmd/zetacored/add_observer_list.go b/cmd/zetacored/add_observer_list.go index e2dd16a5b5..2faf122cc2 100644 --- a/cmd/zetacored/add_observer_list.go +++ b/cmd/zetacored/add_observer_list.go @@ -18,9 +18,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ethcommon "github.com/ethereum/go-ethereum/common" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/spf13/cobra" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/app" "github.com/zeta-chain/zetacore/cmd/zetacored/config" diff --git a/cmd/zetacored/config/config.go b/cmd/zetacored/config/config.go index 4036a7cd72..09c62182da 100644 --- a/cmd/zetacored/config/config.go +++ b/cmd/zetacored/config/config.go @@ -2,7 +2,7 @@ package config import ( sdk "github.com/cosmos/cosmos-sdk/types" - ethermint "github.com/evmos/ethermint/types" + ethermint "github.com/zeta-chain/ethermint/types" ) // SetBech32Prefixes sets the global prefixes to be used when serializing addresses and public keys to Bech32 strings. diff --git a/cmd/zetacored/genaccounts.go b/cmd/zetacored/genaccounts.go index f97ac4d17a..f8d22c3be8 100644 --- a/cmd/zetacored/genaccounts.go +++ b/cmd/zetacored/genaccounts.go @@ -15,9 +15,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/ethereum/go-ethereum/common" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/spf13/cobra" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) const ( diff --git a/cmd/zetacored/parse_genesis.go b/cmd/zetacored/parse_genesis.go index b671519d11..1920f29752 100644 --- a/cmd/zetacored/parse_genesis.go +++ b/cmd/zetacored/parse_genesis.go @@ -25,9 +25,9 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/spf13/cobra" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "github.com/zeta-chain/zetacore/app" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" diff --git a/cmd/zetacored/root.go b/cmd/zetacored/root.go index bcdcc16694..eb63b4c9cd 100644 --- a/cmd/zetacored/root.go +++ b/cmd/zetacored/root.go @@ -6,7 +6,6 @@ import ( "io" "os" - appparams "cosmossdk.io/simapp/params" rosettaCmd "cosmossdk.io/tools/rosetta/cmd" dbm "github.com/cometbft/cometbft-db" tmcfg "github.com/cometbft/cometbft/config" @@ -28,10 +27,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - ethermintclient "github.com/evmos/ethermint/client" - "github.com/evmos/ethermint/crypto/hd" "github.com/spf13/cast" "github.com/spf13/cobra" + ethermintclient "github.com/zeta-chain/ethermint/client" + "github.com/zeta-chain/ethermint/crypto/hd" + "github.com/zeta-chain/ethermint/types" "github.com/zeta-chain/zetacore/app" zetacoredconfig "github.com/zeta-chain/zetacore/cmd/zetacored/config" @@ -45,7 +45,7 @@ const EnvPrefix = "zetacore" // NewRootCmd creates a new root command for wasmd. It is called once in the // main function. -func NewRootCmd() (*cobra.Command, appparams.EncodingConfig) { +func NewRootCmd() (*cobra.Command, types.EncodingConfig) { encodingConfig := app.MakeEncodingConfig() cfg := sdk.GetConfig() @@ -119,7 +119,7 @@ func initTmConfig() *tmcfg.Config { return cfg } -func initRootCmd(rootCmd *cobra.Command, encodingConfig appparams.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig types.EncodingConfig) { ac := appCreator{ encCfg: encodingConfig, } @@ -236,7 +236,7 @@ func txCommand() *cobra.Command { } type appCreator struct { - encCfg appparams.EncodingConfig + encCfg types.EncodingConfig } func (ac appCreator) newApp( diff --git a/cmd/zetae2e/config/clients.go b/cmd/zetae2e/config/clients.go index e70f2c566a..3aec591737 100644 --- a/cmd/zetae2e/config/clients.go +++ b/cmd/zetae2e/config/clients.go @@ -5,98 +5,53 @@ import ( "fmt" "github.com/btcsuite/btcd/rpcclient" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/ethclient" "github.com/gagliardetto/solana-go/rpc" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/zeta-chain/zetacore/e2e/config" - authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "github.com/zeta-chain/zetacore/e2e/runner" + zetacore_rpc "github.com/zeta-chain/zetacore/pkg/rpc" ) -// E2EClients contains all the RPC clients and gRPC clients for E2E tests -type E2EClients struct { - // the RPC clients for external chains in the localnet - BtcRPCClient *rpcclient.Client - SolanaClient *rpc.Client - EvmClient *ethclient.Client - EvmAuth *bind.TransactOpts - - // the gRPC clients for ZetaChain - AuthorityClient authoritytypes.QueryClient - CctxClient crosschaintypes.QueryClient - FungibleClient fungibletypes.QueryClient - AuthClient authtypes.QueryClient - BankClient banktypes.QueryClient - ObserverClient observertypes.QueryClient - LightClient lightclienttypes.QueryClient - - // the RPC clients for ZetaChain - ZevmClient *ethclient.Client - ZevmAuth *bind.TransactOpts -} - -// zetaChainClients contains all the RPC clients and gRPC clients for ZetaChain -type zetaChainClients struct { - AuthorityClient authoritytypes.QueryClient - CctxClient crosschaintypes.QueryClient - FungibleClient fungibletypes.QueryClient - AuthClient authtypes.QueryClient - BankClient banktypes.QueryClient - ObserverClient observertypes.QueryClient - LightClient lightclienttypes.QueryClient -} - // getClientsFromConfig get clients from config func getClientsFromConfig(ctx context.Context, conf config.Config, account config.Account) ( - E2EClients, + runner.Clients, error, ) { var solanaClient *rpc.Client if conf.RPCs.Solana != "" { if solanaClient = rpc.New(conf.RPCs.Solana); solanaClient == nil { - return E2EClients{}, fmt.Errorf("failed to get solana client") + return runner.Clients{}, fmt.Errorf("failed to get solana client") } } btcRPCClient, err := getBtcClient(conf.RPCs.Bitcoin) if err != nil { - return E2EClients{}, fmt.Errorf("failed to get btc client: %w", err) + return runner.Clients{}, fmt.Errorf("failed to get btc client: %w", err) } evmClient, evmAuth, err := getEVMClient(ctx, conf.RPCs.EVM, account) if err != nil { - return E2EClients{}, fmt.Errorf("failed to get evm client: %w", err) + return runner.Clients{}, fmt.Errorf("failed to get evm client: %w", err) } - zetaChainClients, err := getZetaClients( - conf.RPCs.ZetaCoreGRPC, - ) + zetaCoreClients, err := GetZetacoreClient(conf) if err != nil { - return E2EClients{}, fmt.Errorf("failed to get zeta clients: %w", err) + return runner.Clients{}, fmt.Errorf("failed to get zetacore client: %w", err) } zevmClient, zevmAuth, err := getEVMClient(ctx, conf.RPCs.Zevm, account) if err != nil { - return E2EClients{}, fmt.Errorf("failed to get zevm client: %w", err) + return runner.Clients{}, fmt.Errorf("failed to get zevm client: %w", err) } - return E2EClients{ - BtcRPCClient: btcRPCClient, - SolanaClient: solanaClient, - EvmClient: evmClient, - EvmAuth: evmAuth, - AuthorityClient: zetaChainClients.AuthorityClient, - CctxClient: zetaChainClients.CctxClient, - FungibleClient: zetaChainClients.FungibleClient, - AuthClient: zetaChainClients.AuthClient, - BankClient: zetaChainClients.BankClient, - ObserverClient: zetaChainClients.ObserverClient, - LightClient: zetaChainClients.LightClient, - ZevmClient: zevmClient, - ZevmAuth: zevmAuth, + return runner.Clients{ + Zetacore: zetaCoreClients, + BtcRPC: btcRPCClient, + Solana: solanaClient, + Evm: evmClient, + EvmAuth: evmAuth, + Zevm: zevmClient, + ZevmAuth: zevmAuth, }, nil } @@ -151,31 +106,15 @@ func getEVMClient( return evmClient, evmAuth, nil } -// getZetaClients get zeta clients -func getZetaClients(rpc string) ( - zetaChainClients, - error, -) { - grpcConn, err := grpc.Dial(rpc, grpc.WithInsecure()) - if err != nil { - return zetaChainClients{}, err +func GetZetacoreClient(conf config.Config) (zetacore_rpc.Clients, error) { + if conf.RPCs.ZetaCoreGRPC != "" { + return zetacore_rpc.NewGRPCClients( + conf.RPCs.ZetaCoreGRPC, + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) } - - authorityClient := authoritytypes.NewQueryClient(grpcConn) - cctxClient := crosschaintypes.NewQueryClient(grpcConn) - fungibleClient := fungibletypes.NewQueryClient(grpcConn) - authClient := authtypes.NewQueryClient(grpcConn) - bankClient := banktypes.NewQueryClient(grpcConn) - observerClient := observertypes.NewQueryClient(grpcConn) - lightclientClient := lightclienttypes.NewQueryClient(grpcConn) - - return zetaChainClients{ - AuthorityClient: authorityClient, - CctxClient: cctxClient, - FungibleClient: fungibleClient, - AuthClient: authClient, - BankClient: bankClient, - ObserverClient: observerClient, - LightClient: lightclientClient, - }, nil + if conf.RPCs.ZetaCoreRPC != "" { + return zetacore_rpc.NewCometBFTClients(conf.RPCs.ZetaCoreRPC) + } + return zetacore_rpc.Clients{}, fmt.Errorf("no ZetaCore gRPC or RPC specified") } diff --git a/cmd/zetae2e/config/config.go b/cmd/zetae2e/config/config.go index ce1b03717b..7cf2afb461 100644 --- a/cmd/zetae2e/config/config.go +++ b/cmd/zetae2e/config/config.go @@ -30,19 +30,7 @@ func RunnerFromConfig( name, ctxCancel, account, - e2eClients.EvmClient, - e2eClients.ZevmClient, - e2eClients.AuthorityClient, - e2eClients.CctxClient, - e2eClients.FungibleClient, - e2eClients.AuthClient, - e2eClients.BankClient, - e2eClients.ObserverClient, - e2eClients.LightClient, - e2eClients.EvmAuth, - e2eClients.ZevmAuth, - e2eClients.BtcRPCClient, - e2eClients.SolanaClient, + e2eClients, logger, opts..., diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 98410bc368..7f7e8c6c73 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -41,6 +41,10 @@ additional_accounts: bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" private_key: "0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482" + user_precompile: + bech32_address: "zeta1k4f0l2e9qqjccxnstwj0uaarxvn44lj990she9" + evm_address: "0xb552FFAb2500258C1A705Ba4Fe77A333275AFE45" + private_key: "bd6b74387f11b31d21e87c2ae7a23ec269aee08a355dad6c508a6fceb79d1f48" policy_accounts: emergency_policy_account: bech32_address: "zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap" @@ -73,5 +77,4 @@ rpcs: solana: "http://solana:8899" zetacore_grpc: "zetacore0:9090" zetacore_rpc: "http://zetacore0:26657" - -# contracts will be populated on first run \ No newline at end of file +# contracts will be populated on first run diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 3d923b32a8..c8d92fce28 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -9,7 +9,6 @@ import ( "github.com/fatih/color" "github.com/spf13/cobra" - "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" @@ -43,6 +42,7 @@ const ( flagSkipHeaderProof = "skip-header-proof" flagTestV2 = "test-v2" flagSkipTrackerCheck = "skip-tracker-check" + flagSkipPrecompiles = "skip-precompiles" ) var ( @@ -77,6 +77,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagTestTSSMigration, false, "set to true to include a migration test at the end") cmd.Flags().Bool(flagTestV2, false, "set to true to run tests for v2 contracts") cmd.Flags().Bool(flagSkipTrackerCheck, false, "set to true to skip tracker check at the end of the tests") + cmd.Flags().Bool(flagSkipPrecompiles, false, "set to true to skip stateful precompiled contracts test") return cmd } @@ -101,6 +102,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { skipTrackerCheck = must(cmd.Flags().GetBool(flagSkipTrackerCheck)) testTSSMigration = must(cmd.Flags().GetBool(flagTestTSSMigration)) testV2 = must(cmd.Flags().GetBool(flagTestV2)) + skipPrecompiles = must(cmd.Flags().GetBool(flagSkipPrecompiles)) ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -164,7 +166,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { noError(err) // set the authority client to the zeta tx server to be able to query message permissions - deployerRunner.ZetaTxServer.SetAuthorityClient(deployerRunner.AutorithyClient) + deployerRunner.ZetaTxServer.SetAuthorityClient(deployerRunner.AuthorityClient) // wait for keygen to be completed // if setup is skipped, we assume that the keygen is already completed @@ -293,6 +295,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { ethereumAdvancedTests := []string{ e2etests.TestEtherWithdrawRestrictedName, } + precompiledContractTests := []string{} + + if !skipPrecompiles { + precompiledContractTests = []string{ + e2etests.TestZetaPrecompilesPrototypeName, + } + } if !light { erc20Tests = append(erc20Tests, erc20AdvancedTests...) @@ -302,6 +311,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { ethereumTests = append(ethereumTests, ethereumAdvancedTests...) } + eg.Go(statefulPrecompilesTestRoutine(conf, deployerRunner, verbose, precompiledContractTests...)) eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) @@ -439,7 +449,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("โœ… e2e tests completed in %s", time.Since(testStartTime).String()) if testTSSMigration { - runTSSMigrationTest(deployerRunner, logger, verbose, conf) + TSSMigration(deployerRunner, logger, verbose, conf) } // Verify that there are no trackers left over after tests complete if !skipTrackerCheck { @@ -496,48 +506,6 @@ func waitKeygenHeight( } } -func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { - migrationStartTime := time.Now() - logger.Print("๐Ÿ starting tss migration") - - response, err := deployerRunner.CctxClient.LastZetaHeight( - deployerRunner.Ctx, - &crosschaintypes.QueryLastZetaHeightRequest{}, - ) - require.NoError(deployerRunner, err) - err = deployerRunner.ZetaTxServer.UpdateKeygen(response.Height) - require.NoError(deployerRunner, err) - - // Generate new TSS - waitKeygenHeight(deployerRunner.Ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) - - // migration test is a blocking thread, we cannot run other tests in parallel - // The migration test migrates funds to a new TSS and then updates the TSS address on zetacore. - // The necessary restarts are done by the zetaclient supervisor - fn := migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) - - if err := fn(); err != nil { - logger.Print("โŒ %v", err) - logger.Print("โŒ tss migration failed") - os.Exit(1) - } - - logger.Print("โœ… migration completed in %s ", time.Since(migrationStartTime).String()) - logger.Print("๐Ÿ starting post migration tests") - - tests := []string{ - e2etests.TestBitcoinWithdrawSegWitName, - e2etests.TestEtherWithdrawName, - } - fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) - - if err := fn(); err != nil { - logger.Print("โŒ %v", err) - logger.Print("โŒ post migration tests failed") - os.Exit(1) - } -} - func must[T any](v T, err error) T { return testutil.Must(v, err) } diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index d6fab1b709..27d9682990 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -11,8 +11,8 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" ) -// migrationTestRoutine runs migration related e2e tests -func migrationTestRoutine( +// migrationRoutine runs migration related e2e tests +func migrationRoutine( conf config.Config, deployerRunner *runner.E2ERunner, verbose bool, diff --git a/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go deleted file mode 100644 index f339ce0bc1..0000000000 --- a/cmd/zetae2e/local/post_migration.go +++ /dev/null @@ -1,58 +0,0 @@ -package local - -import ( - "time" - - "github.com/fatih/color" - "github.com/pkg/errors" - - "github.com/zeta-chain/zetacore/e2e/config" - "github.com/zeta-chain/zetacore/e2e/e2etests" - "github.com/zeta-chain/zetacore/e2e/runner" -) - -// postMigrationTestRoutine runs post migration tests -func postMigrationTestRoutine( - conf config.Config, - deployerRunner *runner.E2ERunner, - verbose bool, - testNames ...string, -) func() error { - return func() (err error) { - account := conf.AdditionalAccounts.UserBitcoin - // initialize runner for post migration test - postMigrationRunner, err := initTestRunner( - "postMigration", - conf, - deployerRunner, - account, - runner.NewLogger(verbose, color.FgMagenta, "postMigrationRunner"), - ) - if err != nil { - return err - } - - postMigrationRunner.Logger.Print("๐Ÿƒ starting postMigration tests") - startTime := time.Now() - - testsToRun, err := postMigrationRunner.GetE2ETestsToRunByName( - e2etests.AllE2ETests, - testNames..., - ) - if err != nil { - return errors.Wrap(err, "postMigrationRunner tests failed") - } - - if err := postMigrationRunner.RunE2ETests(testsToRun); err != nil { - return errors.Wrap(err, "postMigrationRunner tests failed") - } - - if err := postMigrationRunner.CheckBtcTSSBalance(); err != nil { - return err - } - - postMigrationRunner.Logger.Print("๐Ÿพ PostMigration tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/cmd/zetae2e/local/precompiles.go b/cmd/zetae2e/local/precompiles.go new file mode 100644 index 0000000000..55372431e6 --- /dev/null +++ b/cmd/zetae2e/local/precompiles.go @@ -0,0 +1,54 @@ +package local + +import ( + "fmt" + "time" + + "github.com/fatih/color" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" + "github.com/zeta-chain/zetacore/e2e/runner" +) + +// statefulPrecompilesTestRoutine runs steateful precompiles related e2e tests +func statefulPrecompilesTestRoutine( + conf config.Config, + deployerRunner *runner.E2ERunner, + verbose bool, + testNames ...string, +) func() error { + return func() (err error) { + account := conf.AdditionalAccounts.UserPrecompile + + precompileRunner, err := initTestRunner( + "precompiles", + conf, + deployerRunner, + account, + runner.NewLogger(verbose, color.FgRed, "precompiles"), + ) + if err != nil { + return err + } + + precompileRunner.Logger.Print("๐Ÿƒ starting stateful precompiled contracts tests") + startTime := time.Now() + + testsToRun, err := precompileRunner.GetE2ETestsToRunByName( + e2etests.AllE2ETests, + testNames..., + ) + if err != nil { + return fmt.Errorf("precompiled contracts tests failed: %v", err) + } + + if err := precompileRunner.RunE2ETests(testsToRun); err != nil { + return fmt.Errorf("precompiled contracts tests failed: %v", err) + } + + precompileRunner.Logger.Print("๐Ÿพ precompiled contracts tests completed in %s", time.Since(startTime).String()) + + return err + } +} diff --git a/cmd/zetae2e/local/tss_migration.go b/cmd/zetae2e/local/tss_migration.go new file mode 100644 index 0000000000..a7acf80daa --- /dev/null +++ b/cmd/zetae2e/local/tss_migration.go @@ -0,0 +1,43 @@ +package local + +import ( + "os" + "time" + + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" + "github.com/zeta-chain/zetacore/e2e/runner" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TSSMigration(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { + migrationStartTime := time.Now() + logger.Print("๐Ÿ starting tss migration") + + response, err := deployerRunner.CctxClient.LastZetaHeight( + deployerRunner.Ctx, + &crosschaintypes.QueryLastZetaHeightRequest{}, + ) + require.NoError(deployerRunner, err) + err = deployerRunner.ZetaTxServer.UpdateKeygen(response.Height) + require.NoError(deployerRunner, err) + + // Generate new TSS + waitKeygenHeight(deployerRunner.Ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + + // Run migration + // migrationRoutine runs migration e2e test , which migrates funds from the older TSS to the new one + // The zetaclient restarts required for this process are managed by the background workers in zetaclient (TSSListener) + fn := migrationRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) + + if err := fn(); err != nil { + logger.Print("โŒ %v", err) + logger.Print("โŒ tss migration failed") + os.Exit(1) + } + deployerRunner.UpdateTssAddressForConnector() + deployerRunner.UpdateTssAddressForErc20custody() + logger.Print("โœ… migration completed in %s ", time.Since(migrationStartTime).String()) +} diff --git a/cmd/zetae2e/run.go b/cmd/zetae2e/run.go index 9c36d8e3d2..5f38a39cbd 100644 --- a/cmd/zetae2e/run.go +++ b/cmd/zetae2e/run.go @@ -16,10 +16,14 @@ import ( "github.com/zeta-chain/zetacore/e2e/config" "github.com/zeta-chain/zetacore/e2e/e2etests" "github.com/zeta-chain/zetacore/e2e/runner" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) const flagVerbose = "verbose" const flagConfig = "config" +const flagERC20ChainName = "erc20-chain-name" +const flagERC20Symbol = "erc20-symbol" // NewRunCmd returns the run command // which runs the E2E from a config file describing the tests, networks, and accounts @@ -41,6 +45,9 @@ For example: zetae2e run deposit:1000 withdraw: --config config.yml`, os.Exit(1) } + cmd.Flags().String(flagERC20ChainName, "", "chain_name from /zeta-chain/observer/supportedChains") + cmd.Flags().String(flagERC20Symbol, "", "symbol from /zeta-chain/fungible/foreign_coins") + // Retain the verbose flag cmd.Flags().Bool(flagVerbose, false, "set to true to enable verbose logging") @@ -67,6 +74,29 @@ func runE2ETest(cmd *cobra.Command, args []string) error { // initialize logger logger := runner.NewLogger(verbose, color.FgHiCyan, "e2e") + // update config with dynamic ERC20 + erc20ChainName, err := cmd.Flags().GetString(flagERC20ChainName) + if err != nil { + return err + } + erc20Symbol, err := cmd.Flags().GetString(flagERC20Symbol) + if err != nil { + return err + } + if erc20ChainName != "" && erc20Symbol != "" { + erc20Asset, zrc20ContractAddress, err := findERC20( + cmd.Context(), + conf, + erc20ChainName, + erc20Symbol, + ) + if err != nil { + return err + } + conf.Contracts.EVM.ERC20 = config.DoubleQuotedString(erc20Asset) + conf.Contracts.ZEVM.ERC20ZRC20Addr = config.DoubleQuotedString(zrc20ContractAddress) + } + // set config app.SetConfig() @@ -99,11 +129,6 @@ func runE2ETest(cmd *cobra.Command, args []string) error { testRunner.CctxTimeout = 60 * time.Minute testRunner.ReceiptTimeout = 60 * time.Minute - balancesBefore, err := testRunner.GetAccountBalances(true) - if err != nil { - return err - } - // parse test names and arguments from cmd args and run them userTestsConfigs, err := parseCmdArgsToE2ETestRunConfig(args) if err != nil { @@ -119,15 +144,9 @@ func runE2ETest(cmd *cobra.Command, args []string) error { return err } - balancesAfter, err := testRunner.GetAccountBalances(true) - if err != nil { - return err - } - // Print tests completion info logger.Print("tests finished successfully in %s", time.Since(testStartTime).String()) testRunner.Logger.SetColor(color.FgHiRed) - testRunner.PrintTotalDiff(runner.GetAccountBalancesDiff(balancesBefore, balancesAfter)) testRunner.Logger.SetColor(color.FgHiGreen) testRunner.PrintTestReports(reports) @@ -157,3 +176,43 @@ func parseCmdArgsToE2ETestRunConfig(args []string) ([]runner.E2ETestRunConfig, e } return tests, nil } + +// findERC20 loads ERC20 addresses via gRPC given CLI flags +func findERC20(ctx context.Context, conf config.Config, erc20ChainName, erc20Symbol string) (string, string, error) { + clients, err := zetae2econfig.GetZetacoreClient(conf) + if err != nil { + return "", "", fmt.Errorf("get zeta clients: %w", err) + } + + supportedChainsRes, err := clients.Observer.SupportedChains(ctx, &observertypes.QuerySupportedChains{}) + if err != nil { + return "", "", fmt.Errorf("get chain params: %w", err) + } + + chainID := int64(0) + for _, chain := range supportedChainsRes.Chains { + if chain.Name == erc20ChainName { + chainID = chain.ChainId + break + } + } + if chainID == 0 { + return "", "", fmt.Errorf("chain %s not found", erc20ChainName) + } + + foreignCoinsRes, err := clients.Fungible.ForeignCoinsAll(ctx, &fungibletypes.QueryAllForeignCoinsRequest{}) + if err != nil { + return "", "", fmt.Errorf("get foreign coins: %w", err) + } + + for _, coin := range foreignCoinsRes.ForeignCoins { + if coin.ForeignChainId != chainID { + continue + } + // sometimes symbol is USDT, sometimes it's like USDT.SEPOLIA + if strings.HasPrefix(coin.Symbol, erc20Symbol) || strings.HasSuffix(coin.Symbol, erc20Symbol) { + return coin.Asset, coin.Zrc20ContractAddress, nil + } + } + return "", "", fmt.Errorf("erc20 %s not found on %s", erc20Symbol, erc20ChainName) +} diff --git a/codecov.yml b/codecov.yml index 45df0a7f87..474cfe97ee 100644 --- a/codecov.yml +++ b/codecov.yml @@ -75,4 +75,9 @@ ignore: - "server" - "testutil" - "tool" - - "typescript/**/*" \ No newline at end of file + - "typescript/**/*" + - "precompiles/**/bindings.go" + - "precompiles/**/*.abi" + - "precompiles/**/*.json" + - "precompiles/**/*.sol" + - "precompiles/prototype/IPrototype.go" diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 4ee8192c6d..98ba9060e7 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -107,6 +107,45 @@ fi ### Run zetae2e command depending on the option passed +# Mode migrate is used to run the e2e tests before and after the TSS migration +# It runs the e2e tests with the migrate flag which triggers a TSS migration at the end of the tests. Once the migrationis done the first e2e test is complete +# The second e2e test is run after the migration to ensure the network is still working as expected with the new tss address +if [ "$LOCALNET_MODE" == "tss-migrate" ]; then + if [[ ! -f deployed.yml ]]; then + zetae2e local $E2E_ARGS --setup-only --config config.yml --config-out deployed.yml --skip-header-proof + if [ $? -ne 0 ]; then + echo "e2e setup failed" + exit 1 + fi + else + echo "skipping e2e setup because it has already been completed" + fi + + echo "running e2e test before migrating TSS" + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-header-proof + if [ $? -ne 0 ]; then + echo "first e2e failed" + exit 1 + fi + + echo "waiting 10 seconds for node to restart" + sleep 10 + + zetae2e local --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof + ZETAE2E_EXIT_CODE=$? + if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then + echo "E2E passed after migration" + exit 0 + else + echo "E2E failed after migration" + exit 1 + fi +fi + + +# Mode upgrade is used to run the e2e tests before and after the upgrade +# It runs the e2e tests , waits for the upgrade height to be reached, and then runs the e2e tests again once the ungrade is done. +# The second e2e test is run after the upgrade to ensure the network is still working as expected with the new version if [ "$LOCALNET_MODE" == "upgrade" ]; then # Run the e2e tests, then restart zetaclientd at upgrade height and run the e2e tests again @@ -131,7 +170,7 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then echo "running E2E command to setup the networks and populate the state..." # Use light flag to ensure tests can complete before the upgrade height - zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --light ${COMMON_ARGS} + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --light --skip-precompiles ${COMMON_ARGS} if [ $? -ne 0 ]; then echo "first e2e failed" exit 1 @@ -170,9 +209,9 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then # When the upgrade height is greater than 100 for upgrade test, the Bitcoin tests have been run once, therefore the Bitcoin wallet is already set up # Use light flag to skip advanced tests if [ "$UPGRADE_HEIGHT" -lt 100 ]; then - zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --light ${COMMON_ARGS} + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --light --skip-precompiles ${COMMON_ARGS} else - zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-bitcoin-setup --light ${COMMON_ARGS} + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-precompiles ${COMMON_ARGS} fi ZETAE2E_EXIT_CODE=$? @@ -185,8 +224,7 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then fi else - - # Run the e2e tests normally + # If no mode is passed, run the e2e tests normally echo "running e2e setup..." if [[ ! -f deployed.yml ]]; then diff --git a/docs/cli/zetatool/readme.md b/docs/cli/zetatool/readme.md index c35d5009a7..206e1eb5e5 100644 --- a/docs/cli/zetatool/readme.md +++ b/docs/cli/zetatool/readme.md @@ -11,7 +11,7 @@ configure an ethereum rpc endpoint, then you will have to find an evm rpc endpoi `EthRPCURL` #### Zeta URL -You will need to find an enpoint for zetachain and set the field: `ZetaURL` +You will need to find an endpoint for zetachain and set the field: `ZetaURL` #### Contract Addresses Depending on the network, connector and custody contract addresses must be set using these fields: `ConnectorAddress`, @@ -52,4 +52,4 @@ Running the commands can be simply done through the makefile in the node repo: make filter-missed-btc or ... make filter-missed-eth -``` \ No newline at end of file +``` diff --git a/docs/zetaclient/zetaclient_logging.md b/docs/zetaclient/zetaclient_logging.md index 2782609d78..02eb732c62 100644 --- a/docs/zetaclient/zetaclient_logging.md +++ b/docs/zetaclient/zetaclient_logging.md @@ -6,7 +6,7 @@ - `TRACE`ย (-1): for tracing the code execution path. - `DEBUG`ย (0): messages useful for troubleshooting the program. - `INFO`ย (1): messages describing the normal operation of an application. - - `WARNING`ย (2): for logging events that need may need to be checked later. + - `WARNING`ย (2): for logging events that may need to be checked later. - `ERROR`ย (3): error messages for a specific operation. - `FATAL`ย (4): severe errors where the application cannot recover.ย `os.Exit(1)`ย is called after the message is logged. - `PANIC`ย (5): similar toย `FATAL`, butย `panic()`ย is called instead. @@ -33,4 +33,4 @@ - BTCSigner : chain = `BTC` module=`BTCsigner` - ProcessOutTX : chain = `BTC` module=`BTCsigner` OutboundId = `OutboundID of cctx being signed` SendHash = `Index of cctx being signed` - EVMSigner : chain = `evm_chain_name` module=`EVMSigner` - - ProcessOutTX : chain = `evm_chain_name` module=`BTCsigner` OutboundId = `OutboundID of cctx being signed` SendHash = `Index of cctx being signed` \ No newline at end of file + - ProcessOutTX : chain = `evm_chain_name` module=`BTCsigner` OutboundId = `OutboundID of cctx being signed` SendHash = `Index of cctx being signed` diff --git a/e2e/config/config.go b/e2e/config/config.go index 7e721bcdd3..699a616c3c 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -70,6 +70,7 @@ type AdditionalAccounts struct { UserMisc Account `yaml:"user_misc"` UserAdmin Account `yaml:"user_admin"` UserMigration Account `yaml:"user_migration"` + UserPrecompile Account `yaml:"user_precompile"` } type PolicyAccounts struct { @@ -225,6 +226,7 @@ func (a AdditionalAccounts) AsSlice() []Account { a.UserMisc, a.UserAdmin, a.UserMigration, + a.UserPrecompile, } } @@ -317,6 +319,10 @@ func (c *Config) GenerateKeys() error { if err != nil { return err } + c.AdditionalAccounts.UserPrecompile, err = generateAccount() + if err != nil { + return err + } c.PolicyAccounts.EmergencyPolicyAccount, err = generateAccount() if err != nil { diff --git a/e2e/contracts/contextapp/bindings.go b/e2e/contracts/contextapp/bindings.go index 6b077d4020..cc7c3f8940 100644 --- a/e2e/contracts/contextapp/bindings.go +++ b/e2e/contracts/contextapp/bindings.go @@ -12,7 +12,7 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/accounts/abi" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) type CompiledContract struct { diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index b8f29399db..5b810276db 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -143,6 +143,11 @@ const ( TestDeploy = "deploy" TestOperationAddLiquidityETHName = "add_liquidity_eth" TestOperationAddLiquidityERC20Name = "add_liquidity_erc20" + + /* + Stateful precompiled contracts tests + */ + TestZetaPrecompilesPrototypeName = "precompile_contracts_prototype" ) // AllE2ETests is an ordered list of all e2e tests @@ -805,4 +810,13 @@ var AllE2ETests = []runner.E2ETest{ }, TestOperationAddLiquidityERC20, ), + /* + Stateful precompiled contracts tests + */ + runner.NewE2ETest( + TestZetaPrecompilesPrototypeName, + "test stateful precompiled contracts prototype", + []runner.ArgDefinition{}, + TestPrecompilesRegular, + ), } diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index 798958a652..f41d3d8372 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -15,6 +15,8 @@ import ( ) func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { + stop := r.MineBlocksIfLocalBitcoin() + defer stop() r.ZEVMAuth.GasLimit = 10000000 // TODO: move into setup and skip it if already initialized @@ -23,7 +25,7 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { // if the tx fails due to already initialized, it will be ignored _, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) if err != nil { - r.Logger.Print("โ„น๏ธcreate pair error") + r.Logger.Print("โ„น๏ธ create pair error") } txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) @@ -90,10 +92,6 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { _, err = r.GenerateToAddressIfLocalBitcoin(10, r.BTCDeployerAddress) require.NoError(r, err) - // mine blocks if testing on regnet - stop := r.MineBlocksIfLocalBitcoin() - defer stop() - // cctx1 index acts like the inboundHash for the second cctx (the one that withdraws BTC) cctx2 := utils.WaitCctxMinedByInboundHash(r.Ctx, cctx1.Index, r.CctxClient, r.Logger, r.CctxTimeout) @@ -145,7 +143,9 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info("memo length %d", len(memo)) amount := 0.1 - txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[1:2], memo) + utxos, err = r.ListDeployerUTXOs() + require.NoError(r, err) + txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[0:1], memo) require.NoError(r, err) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, txid.String(), r.CctxClient, r.Logger, r.CctxTimeout) diff --git a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go index 8504aaca56..47957e5678 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go @@ -65,7 +65,6 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri r.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) } } - // expect revert tx to fail cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index 62c9bac84f..b5222a81d7 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -201,19 +201,7 @@ func configureEVM2(r *runner.E2ERunner) (*runner.E2ERunner, error) { "admin-evm2", r.CtxCancel, r.Account, - r.EVMClient, - r.ZEVMClient, - r.AutorithyClient, - r.CctxClient, - r.FungibleClient, - r.AuthClient, - r.BankClient, - r.ObserverClient, - r.LightclientClient, - r.EVMAuth, - r.ZEVMAuth, - r.BtcRPCClient, - r.SolanaClient, + r.Clients, runner.NewLogger(true, color.FgHiYellow, "admin-evm2"), runner.WithZetaTxServer(r.ZetaTxServer), ) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index c1bb79c062..cc7286360b 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -159,7 +159,6 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { require.LessOrEqual(r, btcTSSBalanceNew*1e8, btcTSSBalanceOld*1e8) // ETH - r.TSSAddress = common.HexToAddress(newTss.Eth) ethTSSBalanceNew, err := r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) require.NoError(r, err) diff --git a/e2e/e2etests/test_precompiles_prototype.go b/e2e/e2etests/test_precompiles_prototype.go new file mode 100644 index 0000000000..a78a20385f --- /dev/null +++ b/e2e/e2etests/test_precompiles_prototype.go @@ -0,0 +1,36 @@ +package e2etests + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/e2e/runner" + "github.com/zeta-chain/zetacore/precompiles/prototype" +) + +func TestPrecompilesRegular(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + iPrototype, err := prototype.NewIPrototype(prototype.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create prototype contract caller") + + res, err := iPrototype.Bech32ify(nil, "zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")) + require.NoError(r, err, "Error calling Bech32ify") + require.Equal(r, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", res, "Failed to validate Bech32ify result") + + addr, err := iPrototype.Bech32ToHexAddr(nil, "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u") + require.NoError(r, err, "Error calling Bech32ToHexAddr") + require.Equal( + r, + "0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE", + addr.String(), + "Failed to validate Bech32ToHexAddr result", + ) + + chainID, err := r.EVMClient.ChainID(r.Ctx) + require.NoError(r, err, "Error retrieving ChainID") + + balance, err := iPrototype.GetGasStabilityPoolBalance(nil, chainID.Int64()) + require.NoError(r, err, "Error calling GetGasStabilityPoolBalance") + require.NotNil(r, balance, "GetGasStabilityPoolBalance returned balance is nil") +} diff --git a/e2e/e2etests/test_zrc20_swap.go b/e2e/e2etests/test_zrc20_swap.go index 14febbe800..3008904306 100644 --- a/e2e/e2etests/test_zrc20_swap.go +++ b/e2e/e2etests/test_zrc20_swap.go @@ -19,7 +19,7 @@ func TestZRC20Swap(r *runner.E2ERunner, _ []string) { // if the tx fails due to already initialized, it will be ignored tx, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.ETHZRC20Addr) if err != nil { - r.Logger.Print("โ„น๏ธcreate pair error") + r.Logger.Print("โ„น๏ธ create pair error") } else { utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) } diff --git a/e2e/runner/admin_evm.go b/e2e/runner/admin_evm.go new file mode 100644 index 0000000000..8b357a01f5 --- /dev/null +++ b/e2e/runner/admin_evm.go @@ -0,0 +1,38 @@ +package runner + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/e2e/utils" +) + +func (r *E2ERunner) UpdateTssAddressForConnector() { + require.NoError(r, r.SetTSSAddresses()) + + tx, err := r.ConnectorEth.UpdateTssAddress(r.EVMAuth, r.TSSAddress) + require.NoError(r, err) + r.Logger.Info(fmt.Sprintf("TSS Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + + tssAddressOnConnector, err := r.ConnectorEth.TssAddress(&bind.CallOpts{Context: r.Ctx}) + require.NoError(r, err) + require.Equal(r, r.TSSAddress, tssAddressOnConnector) +} + +func (r *E2ERunner) UpdateTssAddressForErc20custody() { + require.NoError(r, r.SetTSSAddresses()) + + tx, err := r.ERC20Custody.UpdateTSSAddress(r.EVMAuth, r.TSSAddress) + require.NoError(r, err) + r.Logger.Info(fmt.Sprintf("TSS ERC20 Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + + tssAddressOnCustody, err := r.ERC20Custody.TSSAddress(&bind.CallOpts{Context: r.Ctx}) + require.NoError(r, err) + require.Equal(r, r.TSSAddress, tssAddressOnCustody) +} diff --git a/e2e/runner/balances.go b/e2e/runner/balances.go index f7ab0938c1..f1e1fe3f22 100644 --- a/e2e/runner/balances.go +++ b/e2e/runner/balances.go @@ -8,8 +8,11 @@ import ( "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/pkg/errors" + "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" ) +var errNilZRC20 = errors.New("zrc20 contract is nil") + // AccountBalances is a struct that contains the balances of the accounts used in the E2E test type AccountBalances struct { ZetaETH *big.Int @@ -31,6 +34,13 @@ type AccountBalancesDiff struct { ERC20 *big.Int } +func (r *E2ERunner) getZRC20BalanceSafe(z *zrc20.ZRC20) (*big.Int, error) { + if z == nil { + return new(big.Int), errNilZRC20 + } + return z.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) +} + // GetAccountBalances returns the account balances of the accounts used in the E2E test func (r *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, error) { // zevm @@ -42,21 +52,21 @@ func (r *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, error) { if err != nil { return AccountBalances{}, err } - zetaEth, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) + zetaEth, err := r.getZRC20BalanceSafe(r.ETHZRC20) if err != nil { return AccountBalances{}, err } - zetaErc20, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) + zetaErc20, err := r.getZRC20BalanceSafe(r.ERC20ZRC20) if err != nil { return AccountBalances{}, err } - zetaBtc, err := r.BTCZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) + zetaBtc, err := r.getZRC20BalanceSafe(r.BTCZRC20) if err != nil { return AccountBalances{}, err } - zetaSol, err := r.SOLZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) + zetaSol, err := r.getZRC20BalanceSafe(r.SOLZRC20) if err != nil { - return AccountBalances{}, err + r.Logger.Error("get SOL balance: %v", err) } // evm diff --git a/e2e/runner/clients.go b/e2e/runner/clients.go new file mode 100644 index 0000000000..9573a53e29 --- /dev/null +++ b/e2e/runner/clients.go @@ -0,0 +1,25 @@ +package runner + +import ( + "github.com/btcsuite/btcd/rpcclient" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/gagliardetto/solana-go/rpc" + + zetacore_rpc "github.com/zeta-chain/zetacore/pkg/rpc" +) + +// Clients contains all the RPC clients and gRPC clients for E2E tests +type Clients struct { + Zetacore zetacore_rpc.Clients + + // the RPC clients for external chains in the localnet + BtcRPC *rpcclient.Client + Solana *rpc.Client + Evm *ethclient.Client + EvmAuth *bind.TransactOpts + + // the RPC clients for ZetaChain + Zevm *ethclient.Client + ZevmAuth *bind.TransactOpts +} diff --git a/e2e/runner/report.go b/e2e/runner/report.go index 31cd085fc6..d80024e0dd 100644 --- a/e2e/runner/report.go +++ b/e2e/runner/report.go @@ -59,7 +59,7 @@ func (r *E2ERunner) PrintTestReports(tr TestReports) { if err != nil { r.Logger.Print("Error rendering test report: %s", err) } - r.Logger.PrintNoPrefix(table, "") + r.Logger.PrintNoPrefix(table) } // NetworkReport is a struct that contains the report for the network used after running e2e tests diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 77d068c398..90bffd1ed1 100644 --- a/e2e/runner/runner.go +++ b/e2e/runner/runner.go @@ -70,14 +70,18 @@ type E2ERunner struct { BTCDeployerAddress *btcutil.AddressWitnessPubKeyHash SolanaDeployerAddress solana.PublicKey + // all clients. + // a reference to this type is required to enable creating a new E2ERunner. + Clients Clients + // rpc clients ZEVMClient *ethclient.Client EVMClient *ethclient.Client BtcRPCClient *rpcclient.Client SolanaClient *rpc.Client - // grpc clients - AutorithyClient authoritytypes.QueryClient + // zetacored grpc clients + AuthorityClient authoritytypes.QueryClient CctxClient crosschaintypes.QueryClient FungibleClient fungibletypes.QueryClient AuthClient authtypes.QueryClient @@ -165,19 +169,7 @@ func NewE2ERunner( name string, ctxCancel context.CancelFunc, account config.Account, - evmClient *ethclient.Client, - zevmClient *ethclient.Client, - authorityClient authoritytypes.QueryClient, - cctxClient crosschaintypes.QueryClient, - fungibleClient fungibletypes.QueryClient, - authClient authtypes.QueryClient, - bankClient banktypes.QueryClient, - observerClient observertypes.QueryClient, - lightclientClient lightclienttypes.QueryClient, - evmAuth *bind.TransactOpts, - zevmAuth *bind.TransactOpts, - btcRPCClient *rpcclient.Client, - solanaClient *rpc.Client, + clients Clients, logger *Logger, opts ...E2ERunnerOption, ) *E2ERunner { @@ -187,20 +179,22 @@ func NewE2ERunner( Account: account, - ZEVMClient: zevmClient, - EVMClient: evmClient, - AutorithyClient: authorityClient, - CctxClient: cctxClient, - FungibleClient: fungibleClient, - AuthClient: authClient, - BankClient: bankClient, - ObserverClient: observerClient, - LightclientClient: lightclientClient, - - EVMAuth: evmAuth, - ZEVMAuth: zevmAuth, - BtcRPCClient: btcRPCClient, - SolanaClient: solanaClient, + Clients: clients, + + ZEVMClient: clients.Zevm, + EVMClient: clients.Evm, + AuthorityClient: clients.Zetacore.Authority, + CctxClient: clients.Zetacore.Crosschain, + FungibleClient: clients.Zetacore.Fungible, + AuthClient: clients.Zetacore.Auth, + BankClient: clients.Zetacore.Bank, + ObserverClient: clients.Zetacore.Observer, + LightclientClient: clients.Zetacore.Lightclient, + + EVMAuth: clients.EvmAuth, + ZEVMAuth: clients.ZevmAuth, + BtcRPCClient: clients.BtcRPC, + SolanaClient: clients.Solana, Logger: logger, } diff --git a/e2e/runner/solana.go b/e2e/runner/solana.go index ba6f240279..30e089406e 100644 --- a/e2e/runner/solana.go +++ b/e2e/runner/solana.go @@ -65,7 +65,7 @@ func (r *E2ERunner) CreateSignedTransaction( privateKey solana.PrivateKey, ) *solana.Transaction { // get a recent blockhash - recent, err := r.SolanaClient.GetRecentBlockhash(r.Ctx, rpc.CommitmentFinalized) + recent, err := r.SolanaClient.GetLatestBlockhash(r.Ctx, rpc.CommitmentFinalized) require.NoError(r, err) // create the initialize transaction diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index f6723f6575..39a6d8325b 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -33,9 +33,9 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/evmos/ethermint/crypto/hd" - etherminttypes "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/crypto/hd" + etherminttypes "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/app" "github.com/zeta-chain/zetacore/cmd/zetacored/config" diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 9122860d75..b69d9fbc32 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -19,8 +19,11 @@ const ( EmergencyPolicyName = "emergency" AdminPolicyName = "admin" OperationalPolicyName = "operational" + // The timeout was increased from 4 to 6 , which allows for a higher success in test runs + // However this needs to be researched as to why the increase in timeout was needed. + // https://github.com/zeta-chain/node/issues/2690 - DefaultCctxTimeout = 6 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/go.mod b/go.mod index 97c95d67c5..c151309321 100644 --- a/go.mod +++ b/go.mod @@ -5,158 +5,97 @@ go 1.22.2 toolchain go1.22.5 require ( + cosmossdk.io/errors v1.0.1 + cosmossdk.io/math v1.3.0 + cosmossdk.io/tools/rosetta v0.2.1 + github.com/99designs/keyring v1.2.1 + github.com/btcsuite/btcd v0.23.4 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/btcsuite/btcd/btcutil v1.1.3 + github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 + github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce + github.com/cenkalti/backoff/v4 v4.3.0 + github.com/cockroachdb/errors v1.11.1 + github.com/coinbase/rosetta-sdk-go v0.7.9 + github.com/cometbft/cometbft v0.37.4 + github.com/cometbft/cometbft-db v0.12.0 + github.com/cosmos/btcutil v1.0.5 github.com/cosmos/cosmos-sdk v0.47.10 github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-go/v7 v7.4.0 + github.com/davecgh/go-spew v1.1.1 + github.com/emicklei/proto v1.11.1 github.com/ethereum/go-ethereum v1.10.26 + github.com/fatih/color v1.13.0 + github.com/frumioj/crypto11 v1.2.5-0.20210823151709-946ce662cc0e github.com/gagliardetto/solana-go v1.10.0 - github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.0 + github.com/gorilla/websocket v1.5.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-getter v1.7.5 + github.com/huandu/skiplist v1.2.0 + github.com/improbable-eng/grpc-web v0.15.0 + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/libp2p/go-libp2p v0.27.8 + github.com/libp2p/go-libp2p-kad-dht v0.24.2 + github.com/mattn/go-sqlite3 v1.14.19 // indirect github.com/multiformats/go-multiaddr v0.9.0 + github.com/nanmu42/etherscan-api v1.10.0 + github.com/near/borsh-go v0.3.1 + github.com/onrik/ethrpc v1.2.0 + github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 + github.com/rakyll/statik v0.1.7 + github.com/rs/cors v1.8.3 github.com/rs/zerolog v1.32.0 + github.com/samber/lo v1.46.0 + github.com/spf13/afero v1.11.0 github.com/spf13/cast v1.5.1 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.9.0 - github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - gitlab.com/thorchain/tss/go-tss v1.6.5 - google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect - google.golang.org/grpc v1.60.1 - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c -) - -require ( - cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.3.0 - github.com/99designs/keyring v1.2.1 - github.com/btcsuite/btcd v0.23.4 - github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 - github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce - github.com/emicklei/proto v1.11.1 - github.com/evmos/ethermint v0.22.0 - github.com/fatih/color v1.13.0 - github.com/frumioj/crypto11 v1.2.5-0.20210823151709-946ce662cc0e - github.com/pkg/errors v0.9.1 - github.com/rakyll/statik v0.1.7 + github.com/zeta-chain/ethermint v0.0.0-20240729121328-43bf9ddbf82f github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20240816144801-7eb673cf8890 + gitlab.com/thorchain/tss/go-tss v1.6.5 + gitlab.com/thorchain/tss/tss-lib v0.2.0 + go.nhat.io/grpcmock v0.25.0 + golang.org/x/crypto v0.23.0 + golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb + golang.org/x/net v0.25.0 + golang.org/x/sync v0.7.0 google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 + google.golang.org/grpc v1.60.1 + google.golang.org/protobuf v1.32.0 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/yaml.v2 v2.4.0 -) - -require ( - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.19 // indirect + gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/sqlite v1.4.4 gorm.io/gorm v1.24.6 ) -require ( - cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d - cosmossdk.io/tools/rosetta v0.2.1 - github.com/btcsuite/btcd/btcutil v1.1.3 - github.com/cockroachdb/errors v1.11.1 - github.com/cometbft/cometbft v0.37.4 - github.com/cometbft/cometbft-db v0.12.0 - github.com/golang/mock v1.6.0 - github.com/huandu/skiplist v1.2.0 - github.com/nanmu42/etherscan-api v1.10.0 - github.com/near/borsh-go v0.3.1 - github.com/onrik/ethrpc v1.2.0 - github.com/samber/lo v1.46.0 - gitlab.com/thorchain/tss/tss-lib v0.2.0 - go.nhat.io/grpcmock v0.25.0 -) - -require ( - cosmossdk.io/api v0.3.1 // indirect - cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.4 // indirect - cosmossdk.io/log v1.3.1 // indirect - github.com/DataDog/zstd v1.5.0 // indirect - github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 // indirect - github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect - github.com/blendle/zapdriver v1.3.1 // indirect - github.com/bool64/shared v0.1.5 // indirect - github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v1.1.0 // indirect - github.com/cockroachdb/redact v1.1.5 // indirect - github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/ics23/go v0.10.0 // indirect - github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect - github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect - github.com/dgraph-io/badger/v4 v4.2.0 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/gagliardetto/binary v0.8.0 // indirect - github.com/gagliardetto/treeout v0.1.4 // indirect - github.com/getsentry/sentry-go v0.23.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/googleapis v1.4.1 // indirect - github.com/golang/glog v1.1.2 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/s2a-go v0.1.7 // indirect - github.com/iancoleman/orderedmap v0.3.0 // indirect - github.com/ipfs/boxo v0.10.0 // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/libp2p/go-yamux/v4 v4.0.0 // indirect - github.com/linxGnu/grocksdb v1.8.14 // indirect - github.com/logrusorgru/aurora v2.0.3+incompatible // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect - github.com/onsi/gomega v1.27.7 // indirect - github.com/prometheus/tsdb v0.7.1 // indirect - github.com/rjeczalik/notify v0.9.1 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sergi/go-diff v1.3.1 // indirect - github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect - github.com/swaggest/assertjson v1.9.0 // indirect - github.com/tendermint/btcd v0.1.1 // indirect - github.com/thales-e-security/pool v0.0.2 // indirect - github.com/tidwall/gjson v1.14.4 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect - github.com/tidwall/sjson v1.2.5 // indirect - github.com/yudai/gojsondiff v1.0.0 // indirect - github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect - go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect - go.mongodb.org/mongo-driver v1.11.0 // indirect - go.nhat.io/matcher/v2 v2.0.0 // indirect - go.nhat.io/wait v0.1.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.19.2 // indirect - go.uber.org/ratelimit v0.2.0 // indirect - golang.org/x/time v0.5.0 // indirect - gonum.org/v1/gonum v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect - pgregory.net/rapid v1.1.0 // indirect -) - require ( cloud.google.com/go v0.111.0 // indirect cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/storage v1.35.1 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/log v1.3.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/DataDog/zstd v1.5.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 // indirect + github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -164,67 +103,85 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/blang/semver v3.5.1+incompatible // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/bool64/shared v0.1.5 // indirect github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.0 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cosmos/btcutil v1.0.5 github.com/cosmos/cosmos-proto v1.0.0-beta.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v0.20.1 // indirect - github.com/cosmos/ibc-go/v7 v7.4.0 + github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/creachadair/taskgroup v0.4.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set v1.8.0 // indirect + github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v4 v4.2.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/edsrzf/mmap-go v1.0.0 // indirect github.com/elastic/gosigar v0.14.2 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/flynn/noise v1.0.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect + github.com/getsentry/sentry-go v0.23.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/orderedcode v0.0.1 // indirect + github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect - github.com/gorilla/websocket v1.5.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.5 github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d @@ -233,8 +190,9 @@ require ( github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.3 // indirect github.com/huin/goupnp v1.2.0 // indirect - github.com/improbable-eng/grpc-web v0.15.0 + github.com/iancoleman/orderedmap v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/ipfs/boxo v0.10.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect @@ -244,6 +202,8 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect @@ -253,15 +213,16 @@ require ( github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p v0.27.8 github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.3.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/linxGnu/grocksdb v1.8.14 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -270,6 +231,7 @@ require ( github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.54 // indirect + github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect @@ -278,6 +240,9 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -290,6 +255,7 @@ require ( github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/gomega v1.27.7 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect @@ -301,50 +267,71 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/tsdb v0.7.1 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rjeczalik/notify v0.9.1 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/cors v1.8.3 + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sergi/go-diff v1.3.1 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/spf13/afero v1.11.0 github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.16.0 github.com/status-im/keycard-go v0.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect + github.com/swaggest/assertjson v1.9.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/go-amino v0.16.0 // indirect + github.com/thales-e-security/pool v0.0.2 // indirect github.com/tidwall/btree v1.6.0 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/sjson v1.2.5 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/yudai/gojsondiff v1.0.0 // indirect + github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect + go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect + go.mongodb.org/mongo-driver v1.11.0 // indirect + go.nhat.io/matcher/v2 v2.0.0 // indirect + go.nhat.io/wait v0.1.0 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/atomic v1.11.0 // indirect + go.uber.org/dig v1.17.0 // indirect + go.uber.org/fx v1.19.2 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.23.0 - golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.7.0 golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/api v0.152.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.32.0 + google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect - gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.2.1 // indirect nhooyr.io/websocket v1.8.7 // indirect + pgregory.net/rapid v1.1.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) @@ -352,9 +339,7 @@ replace ( github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.22.3 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - github.com/rjeczalik/notify => github.com/rjeczalik/notify v0.9.3 // replace broken goleveldb @@ -362,8 +347,9 @@ replace ( github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) -replace github.com/evmos/ethermint => github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94 - -replace github.com/libp2p/go-libp2p => github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 - -replace gitlab.com/thorchain/tss/go-tss => github.com/zeta-chain/go-tss v0.0.0-20240729195411-9f5ae8189449 +// ZetaChain maintained forks. +replace ( + github.com/ethereum/go-ethereum => github.com/zeta-chain/go-ethereum v1.10.26-spc + github.com/libp2p/go-libp2p => github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 + gitlab.com/thorchain/tss/go-tss => github.com/zeta-chain/go-tss v0.0.0-20240729195411-9f5ae8189449 +) diff --git a/go.sum b/go.sum index bb816367cf..6eb0a71e76 100644 --- a/go.sum +++ b/go.sum @@ -201,8 +201,6 @@ cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d h1:E/8y0oG3u9hBR8l4F9MtC0LdZIamPCUwUoLlrHrX86I= -cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d/go.mod h1:xbjky3L3DJEylaho6gXplkrMvJ5sFgv+qNX+Nn47bzY= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -219,25 +217,13 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8 github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= @@ -259,7 +245,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -286,7 +271,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -296,7 +280,6 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= @@ -340,8 +323,8 @@ github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= github.com/bool64/shared v0.1.5/go.mod h1:081yz68YC9jeFB3+Bbmno2RFWvGKv1lPKkMP6MHJlPs= github.com/btcsuite/btcd v0.22.3 h1:kYNaWFvOw6xvqP0vR20RP1Zq1DVMBxEO8QN5d1/EfNg= github.com/btcsuite/btcd v0.22.3/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= @@ -396,7 +379,6 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -490,6 +472,7 @@ github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFg github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= @@ -507,7 +490,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= @@ -538,21 +520,19 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 h1:kgvzE5wLsLa7XKfV85VZl40QXaMCaeFtHpPwJ8fhotY= github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= @@ -564,12 +544,10 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -589,14 +567,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= -github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= @@ -604,7 +577,7 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= @@ -628,6 +601,7 @@ github.com/gagliardetto/solana-go v1.10.0 h1:lDuHGC+XLxw9j8fCHBZM9tv4trI0PVhev1m github.com/gagliardetto/solana-go v1.10.0/go.mod h1:afBEcIRrDLJst3lvAahTr63m6W2Ns6dajZxe2irF7Jg= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= @@ -682,7 +656,6 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -759,7 +732,6 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -861,12 +833,10 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -940,7 +910,6 @@ github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7H github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= @@ -951,7 +920,7 @@ github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -966,7 +935,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -995,7 +963,6 @@ github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= @@ -1038,12 +1005,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1081,6 +1046,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= @@ -1141,18 +1107,14 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8 github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -1285,14 +1247,13 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onrik/ethrpc v1.2.0 h1:BBcr1iWxW1RBP/eyZfzvSKtGgeqexq5qS0yyf4pmKbc= github.com/onrik/ethrpc v1.2.0/go.mod h1:uvyqpn8+WbsTgBYfouImgEfpIMb0hR8fWGjwdgPHtFU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -1343,7 +1304,6 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -1417,7 +1377,6 @@ github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -1441,11 +1400,9 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo= @@ -1470,7 +1427,6 @@ github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfP github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= @@ -1526,8 +1482,6 @@ github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1Fof github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1548,6 +1502,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -1556,6 +1511,7 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= github.com/swaggest/assertjson v1.9.0/go.mod h1:b+ZKX2VRiUjxfUIal0HDN85W0nHPAYUbYH5WkkSsFsU= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -1642,7 +1598,6 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvS github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= @@ -1664,9 +1619,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94 h1:M54ljayJvy+WlEVdUmX8pgo1nA+XguB3mLhm3wi2z9o= -github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94/go.mod h1:s1zA6OpXv3Tb5I0M6M6j5fo/AssaZL/pgkc7G0W2kN8= +github.com/zeta-chain/ethermint v0.0.0-20240729121328-43bf9ddbf82f h1:M3CQ2Ogbdw0FERKRrHDAUKnWOAjva6Dn5Jmad4UnYC4= +github.com/zeta-chain/ethermint v0.0.0-20240729121328-43bf9ddbf82f/go.mod h1:NeQEwcKBpKAUxIsii2F+jfyOD94jN/3fzPMv/1kVF9M= +github.com/zeta-chain/go-ethereum v1.10.26-spc h1:NvY4rR9yw52wfxWt7YoFsWbaIwVMyOtTsWKqGAXk+sE= +github.com/zeta-chain/go-ethereum v1.10.26-spc/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo= github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 h1:FmO3HfVdZ7LzxBUfg6sVzV7ilKElQU2DZm8PxJ7KcYI= github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4/go.mod h1:TBv5NY/CqWYIfUstXO1fDWrt4bDoqgCw79yihqBspg8= github.com/zeta-chain/go-tss v0.0.0-20240729195411-9f5ae8189449 h1:4U+4g2QQjbrmeLU1ZdCDU6CYsE5kbwMOKZ/PACR/vN8= @@ -1792,7 +1750,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1801,6 +1758,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= @@ -1820,17 +1778,17 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -2010,7 +1968,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2041,7 +1998,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2130,12 +2086,12 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2169,6 +2125,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= @@ -2450,11 +2407,9 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -2476,7 +2431,6 @@ gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s= gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/mempool/custom_proposal_handler_test.go b/pkg/mempool/custom_proposal_handler_test.go index bec2f08a7d..d98d162a09 100644 --- a/pkg/mempool/custom_proposal_handler_test.go +++ b/pkg/mempool/custom_proposal_handler_test.go @@ -23,10 +23,10 @@ import ( signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" zetamempool "github.com/zeta-chain/zetacore/pkg/mempool" ) diff --git a/pkg/mempool/mempool_test.go b/pkg/mempool/mempool_test.go index 95f709d30e..d7d7a6e55a 100644 --- a/pkg/mempool/mempool_test.go +++ b/pkg/mempool/mempool_test.go @@ -13,9 +13,9 @@ import ( authante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // testPubKey is a dummy implementation of PubKey used for testing. diff --git a/pkg/mempool/senders_with_nonce.go b/pkg/mempool/senders_with_nonce.go index 178071a3c8..e9e28cf46f 100644 --- a/pkg/mempool/senders_with_nonce.go +++ b/pkg/mempool/senders_with_nonce.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/signing" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // GetSendersWithNonce is used to extract sender and nonce information txs diff --git a/pkg/rpc/clients.go b/pkg/rpc/clients.go new file mode 100644 index 0000000000..2fef17cf26 --- /dev/null +++ b/pkg/rpc/clients.go @@ -0,0 +1,101 @@ +package rpc + +import ( + "fmt" + + rpcclient "github.com/cometbft/cometbft/rpc/client/http" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" + "google.golang.org/grpc" + + etherminttypes "github.com/zeta-chain/zetacore/rpc/types" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// Clients contains RPC client interfaces to interact with ZetaCore +// +// Clients also has some high level wrappers for the clients +type Clients struct { + // Cosmos SDK clients + + // Auth is a github.com/cosmos/cosmos-sdk/x/auth/types QueryClient + Auth authtypes.QueryClient + // Bank is a github.com/cosmos/cosmos-sdk/x/bank/types QueryClient + Bank banktypes.QueryClient + // Upgrade is a github.com/cosmos/cosmos-sdk/x/upgrade/types QueryClient + Upgrade upgradetypes.QueryClient + + // ZetaCore specific clients + + // Authority is a github.com/zeta-chain/zetacore/x/authority/types QueryClient + Authority authoritytypes.QueryClient + // Crosschain is a github.com/zeta-chain/zetacore/x/crosschain/types QueryClient + Crosschain crosschaintypes.QueryClient + // Fungible is a github.com/zeta-chain/zetacore/x/fungible/types QueryClient + Fungible fungibletypes.QueryClient + // Observer is a github.com/zeta-chain/zetacore/x/observer/types QueryClient + Observer observertypes.QueryClient + // Lightclient is a github.com/zeta-chain/zetacore/x/lightclient/types QueryClient + Lightclient lightclienttypes.QueryClient + + // Ethermint specific clients + + // Ethermint is a github.com/zeta-chain/zetacore/rpc/types QueryClient + Ethermint *etherminttypes.QueryClient + // EthermintFeeMarket is a github.com/zeta-chain/ethermint/x/feemarket/types QueryClient + EthermintFeeMarket feemarkettypes.QueryClient + + // Tendermint specific clients + + // Tendermint is a github.com/cosmos/cosmos-sdk/client/grpc/tmservice QueryClient + Tendermint tmservice.ServiceClient +} + +func newClients(ctx client.Context) (Clients, error) { + return Clients{ + // Cosmos SDK clients + Auth: authtypes.NewQueryClient(ctx), + Bank: banktypes.NewQueryClient(ctx), + Upgrade: upgradetypes.NewQueryClient(ctx), + Authority: authoritytypes.NewQueryClient(ctx), + // ZetaCore specific clients + Crosschain: crosschaintypes.NewQueryClient(ctx), + Fungible: fungibletypes.NewQueryClient(ctx), + Observer: observertypes.NewQueryClient(ctx), + Lightclient: lightclienttypes.NewQueryClient(ctx), + // Ethermint specific clients + Ethermint: etherminttypes.NewQueryClient(ctx), + EthermintFeeMarket: feemarkettypes.NewQueryClient(ctx), + // Tendermint specific clients + Tendermint: tmservice.NewServiceClient(ctx), + }, nil +} + +// NewCometBFTClients creates a Clients which uses cometbft abci_query as the transport +func NewCometBFTClients(url string) (Clients, error) { + cometRPCClient, err := rpcclient.New(url, "/websocket") + if err != nil { + return Clients{}, fmt.Errorf("create cometbft rpc client: %w", err) + } + clientCtx := client.Context{}.WithClient(cometRPCClient) + + return newClients(clientCtx) +} + +// NewGRPCClient creates a Clients which uses gRPC as the transport +func NewGRPCClients(url string, opts ...grpc.DialOption) (Clients, error) { + grpcConn, err := grpc.Dial(url, opts...) + if err != nil { + return Clients{}, err + } + clientCtx := client.Context{}.WithGRPCClient(grpcConn) + return newClients(clientCtx) +} diff --git a/zetaclient/zetacore/client_query_authority.go b/pkg/rpc/clients_authority.go similarity index 58% rename from zetaclient/zetacore/client_query_authority.go rename to pkg/rpc/clients_authority.go index 044a3d47ee..68baa01271 100644 --- a/zetaclient/zetacore/client_query_authority.go +++ b/pkg/rpc/clients_authority.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -8,8 +8,8 @@ import ( ) // GetAdditionalChains returns the additional chains -func (c *Client) GetAdditionalChains(ctx context.Context) ([]chains.Chain, error) { - resp, err := c.client.authority.ChainInfo(ctx, &authoritytypes.QueryGetChainInfoRequest{}) +func (c *Clients) GetAdditionalChains(ctx context.Context) ([]chains.Chain, error) { + resp, err := c.Authority.ChainInfo(ctx, &authoritytypes.QueryGetChainInfoRequest{}) if err != nil { return nil, err } diff --git a/pkg/rpc/clients_cosmos.go b/pkg/rpc/clients_cosmos.go new file mode 100644 index 0000000000..36d41acea2 --- /dev/null +++ b/pkg/rpc/clients_cosmos.go @@ -0,0 +1,37 @@ +package rpc + +import ( + "context" + + sdkmath "cosmossdk.io/math" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/pkg/errors" + + "github.com/zeta-chain/zetacore/cmd/zetacored/config" +) + +// GetUpgradePlan returns the current upgrade plan. +// if there is no active upgrade plan, plan will be nil, err will be nil as well. +func (c *Clients) GetUpgradePlan(ctx context.Context) (*upgradetypes.Plan, error) { + in := &upgradetypes.QueryCurrentPlanRequest{} + + resp, err := c.Upgrade.CurrentPlan(ctx, in) + if err != nil { + return nil, errors.Wrap(err, "failed to get current upgrade plan") + } + + return resp.Plan, nil +} + +// GetZetaTokenSupplyOnNode returns the zeta token supply on the node +func (c *Clients) GetZetaTokenSupplyOnNode(ctx context.Context) (sdkmath.Int, error) { + in := &banktypes.QuerySupplyOfRequest{Denom: config.BaseDenom} + + resp, err := c.Bank.SupplyOf(ctx, in) + if err != nil { + return sdkmath.ZeroInt(), errors.Wrap(err, "failed to get zeta token supply") + } + + return resp.GetAmount().Amount, nil +} diff --git a/zetaclient/zetacore/client_query_crosschain.go b/pkg/rpc/clients_crosschain.go similarity index 66% rename from zetaclient/zetacore/client_query_crosschain.go rename to pkg/rpc/clients_crosschain.go index 262b766a6b..3fa5b06675 100644 --- a/zetaclient/zetacore/client_query_crosschain.go +++ b/pkg/rpc/clients_crosschain.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -17,8 +17,8 @@ import ( var maxSizeOption = grpc.MaxCallRecvMsgSize(32 * 1024 * 1024) // GetLastBlockHeight returns the zetachain block height -func (c *Client) GetLastBlockHeight(ctx context.Context) (uint64, error) { - resp, err := c.client.crosschain.LastBlockHeight(ctx, &types.QueryGetLastBlockHeightRequest{}) +func (c *Clients) GetLastBlockHeight(ctx context.Context) (uint64, error) { + resp, err := c.Crosschain.LastBlockHeight(ctx, &types.QueryGetLastBlockHeightRequest{}) if err != nil { return 0, errors.Wrap(err, "failed to get block height") } @@ -27,8 +27,8 @@ func (c *Client) GetLastBlockHeight(ctx context.Context) (uint64, error) { } // GetBlockHeight returns the zetachain block height -func (c *Client) GetBlockHeight(ctx context.Context) (int64, error) { - resp, err := c.client.crosschain.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) +func (c *Clients) GetBlockHeight(ctx context.Context) (int64, error) { + resp, err := c.Crosschain.LastZetaHeight(ctx, &types.QueryLastZetaHeightRequest{}) if err != nil { return 0, err } @@ -37,8 +37,8 @@ func (c *Client) GetBlockHeight(ctx context.Context) (int64, error) { } // GetAbortedZetaAmount returns the amount of zeta that has been aborted -func (c *Client) GetAbortedZetaAmount(ctx context.Context) (string, error) { - resp, err := c.client.crosschain.ZetaAccounting(ctx, &types.QueryZetaAccountingRequest{}) +func (c *Clients) GetAbortedZetaAmount(ctx context.Context) (string, error) { + resp, err := c.Crosschain.ZetaAccounting(ctx, &types.QueryZetaAccountingRequest{}) if err != nil { return "", errors.Wrap(err, "failed to get aborted zeta amount") } @@ -47,8 +47,8 @@ func (c *Client) GetAbortedZetaAmount(ctx context.Context) (string, error) { } // GetRateLimiterFlags returns the rate limiter flags -func (c *Client) GetRateLimiterFlags(ctx context.Context) (types.RateLimiterFlags, error) { - resp, err := c.client.crosschain.RateLimiterFlags(ctx, &types.QueryRateLimiterFlagsRequest{}) +func (c *Clients) GetRateLimiterFlags(ctx context.Context) (types.RateLimiterFlags, error) { + resp, err := c.Crosschain.RateLimiterFlags(ctx, &types.QueryRateLimiterFlagsRequest{}) if err != nil { return types.RateLimiterFlags{}, errors.Wrap(err, "failed to get rate limiter flags") } @@ -57,10 +57,10 @@ func (c *Client) GetRateLimiterFlags(ctx context.Context) (types.RateLimiterFlag } // GetRateLimiterInput returns input data for the rate limit checker -func (c *Client) GetRateLimiterInput(ctx context.Context, window int64) (*types.QueryRateLimiterInputResponse, error) { +func (c *Clients) GetRateLimiterInput(ctx context.Context, window int64) (*types.QueryRateLimiterInputResponse, error) { in := &types.QueryRateLimiterInputRequest{Window: window} - resp, err := c.client.crosschain.RateLimiterInput(ctx, in, maxSizeOption) + resp, err := c.Crosschain.RateLimiterInput(ctx, in, maxSizeOption) if err != nil { return nil, errors.Wrap(err, "failed to get rate limiter input") } @@ -69,8 +69,8 @@ func (c *Client) GetRateLimiterInput(ctx context.Context, window int64) (*types. } // GetAllCctx returns all cross chain transactions -func (c *Client) GetAllCctx(ctx context.Context) ([]*types.CrossChainTx, error) { - resp, err := c.client.crosschain.CctxAll(ctx, &types.QueryAllCctxRequest{}) +func (c *Clients) GetAllCctx(ctx context.Context) ([]*types.CrossChainTx, error) { + resp, err := c.Crosschain.CctxAll(ctx, &types.QueryAllCctxRequest{}) if err != nil { return nil, errors.Wrap(err, "failed to get all cross chain transactions") } @@ -78,9 +78,9 @@ func (c *Client) GetAllCctx(ctx context.Context) ([]*types.CrossChainTx, error) return resp.CrossChainTx, nil } -func (c *Client) GetCctxByHash(ctx context.Context, sendHash string) (*types.CrossChainTx, error) { +func (c *Clients) GetCctxByHash(ctx context.Context, sendHash string) (*types.CrossChainTx, error) { in := &types.QueryGetCctxRequest{Index: sendHash} - resp, err := c.client.crosschain.Cctx(ctx, in) + resp, err := c.Crosschain.Cctx(ctx, in) if err != nil { return nil, errors.Wrap(err, "failed to get cctx by hash") } @@ -89,8 +89,8 @@ func (c *Client) GetCctxByHash(ctx context.Context, sendHash string) (*types.Cro } // GetCctxByNonce returns a cross chain transaction by nonce -func (c *Client) GetCctxByNonce(ctx context.Context, chainID int64, nonce uint64) (*types.CrossChainTx, error) { - resp, err := c.client.crosschain.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ +func (c *Clients) GetCctxByNonce(ctx context.Context, chainID int64, nonce uint64) (*types.CrossChainTx, error) { + resp, err := c.Crosschain.CctxByNonce(ctx, &types.QueryGetCctxByNonceRequest{ ChainID: chainID, Nonce: nonce, }) @@ -104,12 +104,12 @@ func (c *Client) GetCctxByNonce(ctx context.Context, chainID int64, nonce uint64 // ListPendingCCTXWithinRateLimit returns a list of pending cctxs that do not exceed the outbound rate limit // - The max size of the list is crosschainkeeper.MaxPendingCctxs // - The returned `rateLimitExceeded` flag indicates if the rate limit is exceeded or not -func (c *Client) ListPendingCCTXWithinRateLimit( +func (c *Clients) ListPendingCCTXWithinRateLimit( ctx context.Context, ) (*types.QueryListPendingCctxWithinRateLimitResponse, error) { in := &types.QueryListPendingCctxWithinRateLimitRequest{} - resp, err := c.client.crosschain.ListPendingCctxWithinRateLimit(ctx, in, maxSizeOption) + resp, err := c.Crosschain.ListPendingCctxWithinRateLimit(ctx, in, maxSizeOption) if err != nil { return nil, errors.Wrap(err, "failed to get pending cctxs within rate limit") } @@ -119,10 +119,10 @@ func (c *Client) ListPendingCCTXWithinRateLimit( // ListPendingCCTX returns a list of pending cctxs for a given chainID // - The max size of the list is crosschainkeeper.MaxPendingCctxs -func (c *Client) ListPendingCCTX(ctx context.Context, chainID int64) ([]*types.CrossChainTx, uint64, error) { +func (c *Clients) ListPendingCCTX(ctx context.Context, chainID int64) ([]*types.CrossChainTx, uint64, error) { in := &types.QueryListPendingCctxRequest{ChainId: chainID} - resp, err := c.client.crosschain.ListPendingCctx(ctx, in, maxSizeOption) + resp, err := c.Crosschain.ListPendingCctx(ctx, in, maxSizeOption) if err != nil { return nil, 0, errors.Wrap(err, "failed to get pending cctxs") } @@ -131,14 +131,14 @@ func (c *Client) ListPendingCCTX(ctx context.Context, chainID int64) ([]*types.C } // GetOutboundTracker returns the outbound tracker for a chain and nonce -func (c *Client) GetOutboundTracker( +func (c *Clients) GetOutboundTracker( ctx context.Context, chain chains.Chain, nonce uint64, ) (*types.OutboundTracker, error) { in := &types.QueryGetOutboundTrackerRequest{ChainID: chain.ChainId, Nonce: nonce} - resp, err := c.client.crosschain.OutboundTracker(ctx, in) + resp, err := c.Crosschain.OutboundTracker(ctx, in) if err != nil { return nil, err } @@ -147,10 +147,10 @@ func (c *Client) GetOutboundTracker( } // GetInboundTrackersForChain returns the inbound trackers for a chain -func (c *Client) GetInboundTrackersForChain(ctx context.Context, chainID int64) ([]types.InboundTracker, error) { +func (c *Clients) GetInboundTrackersForChain(ctx context.Context, chainID int64) ([]types.InboundTracker, error) { in := &types.QueryAllInboundTrackerByChainRequest{ChainId: chainID} - resp, err := c.client.crosschain.InboundTrackerAllByChain(ctx, in) + resp, err := c.Crosschain.InboundTrackerAllByChain(ctx, in) if err != nil { return nil, err } @@ -159,7 +159,7 @@ func (c *Client) GetInboundTrackersForChain(ctx context.Context, chainID int64) } // GetAllOutboundTrackerByChain returns all outbound trackers for a chain -func (c *Client) GetAllOutboundTrackerByChain( +func (c *Clients) GetAllOutboundTrackerByChain( ctx context.Context, chainID int64, order interfaces.Order, @@ -175,7 +175,7 @@ func (c *Client) GetAllOutboundTrackerByChain( }, } - resp, err := c.client.crosschain.OutboundTrackerAllByChain(ctx, in) + resp, err := c.Crosschain.OutboundTrackerAllByChain(ctx, in) if err != nil { return nil, errors.Wrap(err, "failed to get all outbound trackers") } diff --git a/zetaclient/zetacore/client_query_ethermint.go b/pkg/rpc/clients_ethermint.go similarity index 56% rename from zetaclient/zetacore/client_query_ethermint.go rename to pkg/rpc/clients_ethermint.go index edb8987360..0a559fbf7f 100644 --- a/zetaclient/zetacore/client_query_ethermint.go +++ b/pkg/rpc/clients_ethermint.go @@ -1,16 +1,16 @@ -package zetacore +package rpc import ( "context" "fmt" "cosmossdk.io/errors" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" ) // GetBaseGasPrice returns the base gas price -func (c *Client) GetBaseGasPrice(ctx context.Context) (int64, error) { - resp, err := c.client.fees.Params(ctx, &feemarkettypes.QueryParamsRequest{}) +func (c *Clients) GetBaseGasPrice(ctx context.Context) (int64, error) { + resp, err := c.EthermintFeeMarket.Params(ctx, &feemarkettypes.QueryParamsRequest{}) if err != nil { return 0, errors.Wrap(err, "failed to get base gas price") } diff --git a/zetaclient/zetacore/client_query_lightclient.go b/pkg/rpc/clients_lightclient.go similarity index 68% rename from zetaclient/zetacore/client_query_lightclient.go rename to pkg/rpc/clients_lightclient.go index f5999a5d2a..cb3e0e0c3c 100644 --- a/zetaclient/zetacore/client_query_lightclient.go +++ b/pkg/rpc/clients_lightclient.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -10,8 +10,8 @@ import ( ) // GetBlockHeaderEnabledChains returns the enabled chains for block headers -func (c *Client) GetBlockHeaderEnabledChains(ctx context.Context) ([]types.HeaderSupportedChain, error) { - resp, err := c.client.light.HeaderEnabledChains(ctx, &types.QueryHeaderEnabledChainsRequest{}) +func (c *Clients) GetBlockHeaderEnabledChains(ctx context.Context) ([]types.HeaderSupportedChain, error) { + resp, err := c.Lightclient.HeaderEnabledChains(ctx, &types.QueryHeaderEnabledChainsRequest{}) if err != nil { return []types.HeaderSupportedChain{}, err } @@ -20,10 +20,10 @@ func (c *Client) GetBlockHeaderEnabledChains(ctx context.Context) ([]types.Heade } // GetBlockHeaderChainState returns the block header chain state -func (c *Client) GetBlockHeaderChainState(ctx context.Context, chainID int64) (*types.ChainState, error) { +func (c *Clients) GetBlockHeaderChainState(ctx context.Context, chainID int64) (*types.ChainState, error) { in := &types.QueryGetChainStateRequest{ChainId: chainID} - resp, err := c.client.light.ChainState(ctx, in) + resp, err := c.Lightclient.ChainState(ctx, in) if err != nil { return nil, errors.Wrap(err, "failed to get chain state") } @@ -32,7 +32,7 @@ func (c *Client) GetBlockHeaderChainState(ctx context.Context, chainID int64) (* } // Prove returns whether a proof is valid -func (c *Client) Prove( +func (c *Clients) Prove( ctx context.Context, blockHash string, txHash string, @@ -48,7 +48,7 @@ func (c *Client) Prove( TxHash: txHash, } - resp, err := c.client.light.Prove(ctx, in) + resp, err := c.Lightclient.Prove(ctx, in) if err != nil { return false, errors.Wrap(err, "failed to prove") } diff --git a/zetaclient/zetacore/client_query_observer.go b/pkg/rpc/clients_observer.go similarity index 61% rename from zetaclient/zetacore/client_query_observer.go rename to pkg/rpc/clients_observer.go index a8ed20c998..a5c7455e91 100644 --- a/zetaclient/zetacore/client_query_observer.go +++ b/pkg/rpc/clients_observer.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -12,8 +12,8 @@ import ( ) // GetCrosschainFlags returns the crosschain flags -func (c *Client) GetCrosschainFlags(ctx context.Context) (types.CrosschainFlags, error) { - resp, err := c.client.observer.CrosschainFlags(ctx, &types.QueryGetCrosschainFlagsRequest{}) +func (c *Clients) GetCrosschainFlags(ctx context.Context) (types.CrosschainFlags, error) { + resp, err := c.Observer.CrosschainFlags(ctx, &types.QueryGetCrosschainFlagsRequest{}) if err != nil { return types.CrosschainFlags{}, err } @@ -22,8 +22,8 @@ func (c *Client) GetCrosschainFlags(ctx context.Context) (types.CrosschainFlags, } // GetSupportedChains returns the supported chains -func (c *Client) GetSupportedChains(ctx context.Context) ([]chains.Chain, error) { - resp, err := c.client.observer.SupportedChains(ctx, &types.QuerySupportedChains{}) +func (c *Clients) GetSupportedChains(ctx context.Context) ([]chains.Chain, error) { + resp, err := c.Observer.SupportedChains(ctx, &types.QuerySupportedChains{}) if err != nil { return nil, errors.Wrap(err, "failed to get supported chains") } @@ -32,11 +32,11 @@ func (c *Client) GetSupportedChains(ctx context.Context) ([]chains.Chain, error) } // GetChainParams returns all the chain params -func (c *Client) GetChainParams(ctx context.Context) ([]*types.ChainParams, error) { +func (c *Clients) GetChainParams(ctx context.Context) ([]*types.ChainParams, error) { in := &types.QueryGetChainParamsRequest{} resp, err := retry.DoTypedWithRetry(func() (*types.QueryGetChainParamsResponse, error) { - return c.client.observer.GetChainParams(ctx, in) + return c.Observer.GetChainParams(ctx, in) }) if err != nil { @@ -47,13 +47,13 @@ func (c *Client) GetChainParams(ctx context.Context) ([]*types.ChainParams, erro } // GetChainParamsForChainID returns the chain params for a given chain ID -func (c *Client) GetChainParamsForChainID( +func (c *Clients) GetChainParamsForChainID( ctx context.Context, externalChainID int64, ) (*types.ChainParams, error) { in := &types.QueryGetChainParamsForChainRequest{ChainId: externalChainID} - resp, err := c.client.observer.GetChainParamsForChain(ctx, in) + resp, err := c.Observer.GetChainParamsForChain(ctx, in) if err != nil { return &types.ChainParams{}, err } @@ -62,11 +62,11 @@ func (c *Client) GetChainParamsForChainID( } // GetObserverList returns the list of observers -func (c *Client) GetObserverList(ctx context.Context) ([]string, error) { +func (c *Clients) GetObserverList(ctx context.Context) ([]string, error) { in := &types.QueryObserverSet{} resp, err := retry.DoTypedWithRetry(func() (*types.QueryObserverSetResponse, error) { - return c.client.observer.ObserverSet(ctx, in) + return c.Observer.ObserverSet(ctx, in) }) if err != nil { @@ -77,17 +77,17 @@ func (c *Client) GetObserverList(ctx context.Context) ([]string, error) { } // GetBallotByID returns a ballot by ID -func (c *Client) GetBallotByID(ctx context.Context, id string) (*types.QueryBallotByIdentifierResponse, error) { +func (c *Clients) GetBallotByID(ctx context.Context, id string) (*types.QueryBallotByIdentifierResponse, error) { in := &types.QueryBallotByIdentifierRequest{BallotIdentifier: id} - return c.client.observer.BallotByIdentifier(ctx, in) + return c.Observer.BallotByIdentifier(ctx, in) } // GetNonceByChain returns the nonce by chain -func (c *Client) GetNonceByChain(ctx context.Context, chain chains.Chain) (types.ChainNonces, error) { +func (c *Clients) GetNonceByChain(ctx context.Context, chain chains.Chain) (types.ChainNonces, error) { in := &types.QueryGetChainNoncesRequest{ChainId: chain.ChainId} - resp, err := c.client.observer.ChainNonces(ctx, in) + resp, err := c.Observer.ChainNonces(ctx, in) if err != nil { return types.ChainNonces{}, errors.Wrap(err, "failed to get nonce by chain") } @@ -96,11 +96,11 @@ func (c *Client) GetNonceByChain(ctx context.Context, chain chains.Chain) (types } // GetKeyGen returns the keygen -func (c *Client) GetKeyGen(ctx context.Context) (types.Keygen, error) { +func (c *Clients) GetKeyGen(ctx context.Context) (types.Keygen, error) { in := &types.QueryGetKeygenRequest{} resp, err := retry.DoTypedWithRetry(func() (*types.QueryGetKeygenResponse, error) { - return c.client.observer.Keygen(ctx, in) + return c.Observer.Keygen(ctx, in) }) switch { @@ -114,25 +114,23 @@ func (c *Client) GetKeyGen(ctx context.Context) (types.Keygen, error) { } // GetAllNodeAccounts returns all node accounts -func (c *Client) GetAllNodeAccounts(ctx context.Context) ([]*types.NodeAccount, error) { - resp, err := c.client.observer.NodeAccountAll(ctx, &types.QueryAllNodeAccountRequest{}) +func (c *Clients) GetAllNodeAccounts(ctx context.Context) ([]*types.NodeAccount, error) { + resp, err := c.Observer.NodeAccountAll(ctx, &types.QueryAllNodeAccountRequest{}) if err != nil { return nil, errors.Wrap(err, "failed to get all node accounts") } - c.logger.Debug().Int("node_account.len", len(resp.NodeAccount)).Msg("GetAllNodeAccounts: OK") - return resp.NodeAccount, nil } // GetBallot returns a ballot by ID -func (c *Client) GetBallot( +func (c *Clients) GetBallot( ctx context.Context, ballotIdentifier string, ) (*types.QueryBallotByIdentifierResponse, error) { in := &types.QueryBallotByIdentifierRequest{BallotIdentifier: ballotIdentifier} - resp, err := c.client.observer.BallotByIdentifier(ctx, in) + resp, err := c.Observer.BallotByIdentifier(ctx, in) if err != nil { return nil, errors.Wrap(err, "failed to get ballot") } @@ -141,8 +139,8 @@ func (c *Client) GetBallot( } // GetEVMTSSAddress returns the current EVM TSS address. -func (c *Client) GetEVMTSSAddress(ctx context.Context) (string, error) { - resp, err := c.client.observer.GetTssAddress(ctx, &types.QueryGetTssAddressRequest{}) +func (c *Clients) GetEVMTSSAddress(ctx context.Context) (string, error) { + resp, err := c.Observer.GetTssAddress(ctx, &types.QueryGetTssAddressRequest{}) if err != nil { return "", errors.Wrap(err, "failed to get eth tss address") } @@ -151,10 +149,10 @@ func (c *Client) GetEVMTSSAddress(ctx context.Context) (string, error) { } // GetBTCTSSAddress returns the current BTC TSS address -func (c *Client) GetBTCTSSAddress(ctx context.Context, chainID int64) (string, error) { +func (c *Clients) GetBTCTSSAddress(ctx context.Context, chainID int64) (string, error) { in := &types.QueryGetTssAddressRequest{BitcoinChainId: chainID} - resp, err := c.client.observer.GetTssAddress(ctx, in) + resp, err := c.Observer.GetTssAddress(ctx, in) if err != nil { return "", errors.Wrap(err, "failed to get btc tss address") } @@ -162,8 +160,8 @@ func (c *Client) GetBTCTSSAddress(ctx context.Context, chainID int64) (string, e } // GetTSS returns the current TSS -func (c *Client) GetTSS(ctx context.Context) (types.TSS, error) { - resp, err := c.client.observer.TSS(ctx, &types.QueryGetTSSRequest{}) +func (c *Clients) GetTSS(ctx context.Context) (types.TSS, error) { + resp, err := c.Observer.TSS(ctx, &types.QueryGetTSSRequest{}) if err != nil { return types.TSS{}, errors.Wrap(err, "failed to get tss") } @@ -171,8 +169,8 @@ func (c *Client) GetTSS(ctx context.Context) (types.TSS, error) { } // GetTSSHistory returns the historical list of TSS -func (c *Client) GetTSSHistory(ctx context.Context) ([]types.TSS, error) { - resp, err := c.client.observer.TssHistory(ctx, &types.QueryTssHistoryRequest{}) +func (c *Clients) GetTSSHistory(ctx context.Context) ([]types.TSS, error) { + resp, err := c.Observer.TssHistory(ctx, &types.QueryTssHistoryRequest{}) if err != nil { return nil, errors.Wrap(err, "failed to get tss history") } @@ -181,8 +179,8 @@ func (c *Client) GetTSSHistory(ctx context.Context) ([]types.TSS, error) { } // GetPendingNonces returns the pending nonces -func (c *Client) GetPendingNonces(ctx context.Context) (*types.QueryAllPendingNoncesResponse, error) { - resp, err := c.client.observer.PendingNoncesAll(ctx, &types.QueryAllPendingNoncesRequest{}) +func (c *Clients) GetPendingNonces(ctx context.Context) (*types.QueryAllPendingNoncesResponse, error) { + resp, err := c.Observer.PendingNoncesAll(ctx, &types.QueryAllPendingNoncesRequest{}) if err != nil { return nil, errors.Wrap(err, "failed to get pending nonces") } @@ -191,10 +189,10 @@ func (c *Client) GetPendingNonces(ctx context.Context) (*types.QueryAllPendingNo } // GetPendingNoncesByChain returns the pending nonces for a chain and current tss address -func (c *Client) GetPendingNoncesByChain(ctx context.Context, chainID int64) (types.PendingNonces, error) { +func (c *Clients) GetPendingNoncesByChain(ctx context.Context, chainID int64) (types.PendingNonces, error) { in := &types.QueryPendingNoncesByChainRequest{ChainId: chainID} - resp, err := c.client.observer.PendingNoncesByChain(ctx, in) + resp, err := c.Observer.PendingNoncesByChain(ctx, in) if err != nil { return types.PendingNonces{}, errors.Wrap(err, "failed to get pending nonces by chain") } @@ -203,13 +201,13 @@ func (c *Client) GetPendingNoncesByChain(ctx context.Context, chainID int64) (ty } // HasVoted returns whether an observer has voted -func (c *Client) HasVoted(ctx context.Context, ballotIndex string, voterAddress string) (bool, error) { +func (c *Clients) HasVoted(ctx context.Context, ballotIndex string, voterAddress string) (bool, error) { in := &types.QueryHasVotedRequest{ BallotIdentifier: ballotIndex, VoterAddress: voterAddress, } - resp, err := c.client.observer.HasVoted(ctx, in) + resp, err := c.Observer.HasVoted(ctx, in) if err != nil { return false, errors.Wrap(err, "failed to check if observer has voted") } diff --git a/zetaclient/zetacore/client_query_tendermint.go b/pkg/rpc/clients_tendermint.go similarity index 60% rename from zetaclient/zetacore/client_query_tendermint.go rename to pkg/rpc/clients_tendermint.go index adb38d0bab..e1df340a71 100644 --- a/zetaclient/zetacore/client_query_tendermint.go +++ b/pkg/rpc/clients_tendermint.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -10,8 +10,8 @@ import ( ) // GetLatestZetaBlock returns the latest zeta block -func (c *Client) GetLatestZetaBlock(ctx context.Context) (*tmservice.Block, error) { - res, err := c.client.tendermint.GetLatestBlock(ctx, &tmservice.GetLatestBlockRequest{}) +func (c *Clients) GetLatestZetaBlock(ctx context.Context) (*tmservice.Block, error) { + res, err := c.Tendermint.GetLatestBlock(ctx, &tmservice.GetLatestBlockRequest{}) if err != nil { return nil, errors.Wrap(err, "failed to get latest zeta block") } @@ -20,11 +20,11 @@ func (c *Client) GetLatestZetaBlock(ctx context.Context) (*tmservice.Block, erro } // GetNodeInfo returns the node info -func (c *Client) GetNodeInfo(ctx context.Context) (*tmservice.GetNodeInfoResponse, error) { +func (c *Clients) GetNodeInfo(ctx context.Context) (*tmservice.GetNodeInfoResponse, error) { var err error res, err := retry.DoTypedWithRetry(func() (*tmservice.GetNodeInfoResponse, error) { - return c.client.tendermint.GetNodeInfo(ctx, &tmservice.GetNodeInfoRequest{}) + return c.Tendermint.GetNodeInfo(ctx, &tmservice.GetNodeInfoRequest{}) }) if err != nil { diff --git a/zetaclient/zetacore/client_query_test.go b/pkg/rpc/clients_test.go similarity index 80% rename from zetaclient/zetacore/client_query_test.go rename to pkg/rpc/clients_test.go index 369e1bda3d..ed4f7ccffa 100644 --- a/zetaclient/zetacore/client_query_test.go +++ b/pkg/rpc/clients_test.go @@ -1,4 +1,4 @@ -package zetacore +package rpc import ( "context" @@ -6,22 +6,17 @@ import ( "testing" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" - abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/proto/tendermint/types" - cosmosclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" - "github.com/cosmos/cosmos-sdk/testutil/mock" "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - "github.com/golang/mock/gomock" - "github.com/rs/zerolog" "github.com/stretchr/testify/require" - keyinterfaces "github.com/zeta-chain/zetacore/zetaclient/keys/interfaces" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "go.nhat.io/grpcmock" "go.nhat.io/grpcmock/planner" @@ -33,11 +28,10 @@ import ( lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" - "github.com/zeta-chain/zetacore/zetaclient/keys" - "github.com/zeta-chain/zetacore/zetaclient/testutils/mocks" ) const skipMethod = "skip" +const gRPCListenPath = "127.0.0.1:47392" // setupMockServer setup mock zetacore GRPC server func setupMockServer( @@ -45,7 +39,7 @@ func setupMockServer( serviceFunc any, method string, input any, expectedOutput any, extra ...grpcmock.ServerOption, ) *grpcmock.Server { - listener, err := net.Listen("tcp", "127.0.0.1:9090") + listener, err := net.Listen("tcp", gRPCListenPath) require.NoError(t, err) opts := []grpcmock.ServerOption{ @@ -76,91 +70,8 @@ func setupMockServer( return server } -func withDummyServer(zetaBlockHeight int64) []grpcmock.ServerOption { - return []grpcmock.ServerOption{ - grpcmock.RegisterService(crosschaintypes.RegisterQueryServer), - grpcmock.RegisterService(crosschaintypes.RegisterMsgServer), - grpcmock.RegisterService(feemarkettypes.RegisterQueryServer), - grpcmock.RegisterService(authtypes.RegisterQueryServer), - grpcmock.RegisterService(abci.RegisterABCIApplicationServer), - func(s *grpcmock.Server) { - // Block Height - s.ExpectUnary("/zetachain.zetacore.crosschain.Query/LastZetaHeight"). - UnlimitedTimes(). - Return(crosschaintypes.QueryLastZetaHeightResponse{Height: zetaBlockHeight}) - - // London Base Fee - s.ExpectUnary("/ethermint.feemarket.v1.Query/Params"). - UnlimitedTimes(). - Return(feemarkettypes.QueryParamsResponse{ - Params: feemarkettypes.Params{BaseFee: types.NewInt(100)}, - }) - }, - } -} - -type clientTestConfig struct { - keys keyinterfaces.ObserverKeys - opts []Opt -} - -type clientTestOpt func(*clientTestConfig) - -func withObserverKeys(keys keyinterfaces.ObserverKeys) clientTestOpt { - return func(cfg *clientTestConfig) { cfg.keys = keys } -} - -func withDefaultObserverKeys() clientTestOpt { - var ( - key = mocks.TestKeyringPair - address = types.AccAddress(key.PubKey().Address().Bytes()) - keyRing = mocks.NewKeyring() - ) - - return withObserverKeys(keys.NewKeysWithKeybase(keyRing, address, testSigner, "")) -} - -func withTendermint(client cosmosclient.TendermintRPC) clientTestOpt { - return func(cfg *clientTestConfig) { cfg.opts = append(cfg.opts, WithTendermintClient(client)) } -} - -func withAccountRetriever(t *testing.T, accNum uint64, accSeq uint64) clientTestOpt { - ctrl := gomock.NewController(t) - ac := mock.NewMockAccountRetriever(ctrl) - ac.EXPECT(). - GetAccountNumberSequence(gomock.Any(), gomock.Any()). - AnyTimes(). - Return(accNum, accSeq, nil) - - return func(cfg *clientTestConfig) { - cfg.opts = append(cfg.opts, WithCustomAccountRetriever(ac)) - } -} - -func setupZetacoreClient(t *testing.T, opts ...clientTestOpt) *Client { - const ( - chainIP = "127.0.0.1" - signer = testSigner - chainID = "zetachain_7000-1" - ) - - var cfg clientTestConfig - for _, opt := range opts { - opt(&cfg) - } - - if cfg.keys == nil { - cfg.keys = &keys.Keys{} - } - - c, err := NewClient( - cfg.keys, - chainIP, signer, - chainID, - false, - zerolog.Nop(), - cfg.opts..., - ) +func setupZetacoreClients(t *testing.T) Clients { + c, err := NewGRPCClients(gRPCListenPath, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) @@ -180,7 +91,7 @@ func TestZetacore_GetBallot(t *testing.T) { method := "/zetachain.zetacore.observer.Query/BallotByIdentifier" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBallotByID(ctx, "123") require.NoError(t, err) @@ -199,7 +110,7 @@ func TestZetacore_GetCrosschainFlags(t *testing.T) { method := "/zetachain.zetacore.observer.Query/CrosschainFlags" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetCrosschainFlags(ctx) require.NoError(t, err) @@ -220,7 +131,7 @@ func TestZetacore_GetRateLimiterFlags(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/RateLimiterFlags" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) // query resp, err := client.GetRateLimiterFlags(ctx) @@ -247,7 +158,7 @@ func TestZetacore_HeaderEnabledChains(t *testing.T) { method := "/zetachain.zetacore.lightclient.Query/HeaderEnabledChains" setupMockServer(t, lightclienttypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBlockHeaderEnabledChains(ctx) require.NoError(t, err) @@ -266,7 +177,7 @@ func TestZetacore_GetChainParamsForChainID(t *testing.T) { method := "/zetachain.zetacore.observer.Query/GetChainParamsForChain" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetChainParamsForChainID(ctx, 123) require.NoError(t, err) @@ -289,7 +200,7 @@ func TestZetacore_GetChainParams(t *testing.T) { method := "/zetachain.zetacore.observer.Query/GetChainParams" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetChainParams(ctx) require.NoError(t, err) @@ -309,7 +220,7 @@ func TestZetacore_GetUpgradePlan(t *testing.T) { method := "/cosmos.upgrade.v1beta1.Query/CurrentPlan" setupMockServer(t, upgradetypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetUpgradePlan(ctx) require.NoError(t, err) @@ -331,7 +242,7 @@ func TestZetacore_GetAllCctx(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/CctxAll" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetAllCctx(ctx) require.NoError(t, err) @@ -350,7 +261,7 @@ func TestZetacore_GetCctxByHash(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/Cctx" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetCctxByHash(ctx, "9c8d02b6956b9c78ecb6090a8160faaa48e7aecfd0026fcdf533721d861436a3") require.NoError(t, err) @@ -370,7 +281,7 @@ func TestZetacore_GetCctxByNonce(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/CctxByNonce" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetCctxByNonce(ctx, 7000, 55) require.NoError(t, err) @@ -391,7 +302,7 @@ func TestZetacore_GetObserverList(t *testing.T) { method := "/zetachain.zetacore.observer.Query/ObserverSet" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetObserverList(ctx) require.NoError(t, err) @@ -414,7 +325,7 @@ func TestZetacore_GetRateLimiterInput(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/RateLimiterInput" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetRateLimiterInput(ctx, 10) require.NoError(t, err) @@ -436,7 +347,7 @@ func TestZetacore_ListPendingCctx(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/ListPendingCctx" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, totalPending, err := client.ListPendingCCTX(ctx, 7000) require.NoError(t, err) @@ -452,7 +363,7 @@ func TestZetacore_GetAbortedZetaAmount(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/ZetaAccounting" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetAbortedZetaAmount(ctx) require.NoError(t, err) @@ -475,7 +386,7 @@ func TestZetacore_GetZetaTokenSupplyOnNode(t *testing.T) { method := "/cosmos.bank.v1beta1.Query/SupplyOf" setupMockServer(t, banktypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetZetaTokenSupplyOnNode(ctx) require.NoError(t, err) @@ -491,9 +402,7 @@ func TestZetacore_GetBlockHeight(t *testing.T) { setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, output) - client := setupZetacoreClient(t, - withDefaultObserverKeys(), - ) + client := setupZetacoreClients(t) t.Run("last block height", func(t *testing.T) { height, err := client.GetBlockHeight(ctx) @@ -517,7 +426,7 @@ func TestZetacore_GetLatestZetaBlock(t *testing.T) { method := "/cosmos.base.tendermint.v1beta1.Service/GetLatestBlock" setupMockServer(t, tmservice.RegisterServiceServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetLatestZetaBlock(ctx) require.NoError(t, err) @@ -535,7 +444,7 @@ func TestZetacore_GetNodeInfo(t *testing.T) { method := "/cosmos.base.tendermint.v1beta1.Service/GetNodeInfo" setupMockServer(t, tmservice.RegisterServiceServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetNodeInfo(ctx) require.NoError(t, err) @@ -554,7 +463,7 @@ func TestZetacore_GetBaseGasPrice(t *testing.T) { method := "/ethermint.feemarket.v1.Query/Params" setupMockServer(t, feemarkettypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBaseGasPrice(ctx) require.NoError(t, err) @@ -578,7 +487,7 @@ func TestZetacore_GetNonceByChain(t *testing.T) { method := "/zetachain.zetacore.observer.Query/ChainNonces" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetNonceByChain(ctx, chain) require.NoError(t, err) @@ -602,7 +511,7 @@ func TestZetacore_GetAllNodeAccounts(t *testing.T) { method := "/zetachain.zetacore.observer.Query/NodeAccountAll" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetAllNodeAccounts(ctx) require.NoError(t, err) @@ -622,7 +531,7 @@ func TestZetacore_GetKeyGen(t *testing.T) { method := "/zetachain.zetacore.observer.Query/Keygen" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetKeyGen(ctx) require.NoError(t, err) @@ -639,7 +548,7 @@ func TestZetacore_GetBallotByID(t *testing.T) { method := "/zetachain.zetacore.observer.Query/BallotByIdentifier" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBallot(ctx, "ballot1235") require.NoError(t, err) @@ -663,7 +572,7 @@ func TestZetacore_GetInboundTrackersForChain(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/InboundTrackerAllByChain" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetInboundTrackersForChain(ctx, chainID) require.NoError(t, err) @@ -686,7 +595,7 @@ func TestZetacore_GetTss(t *testing.T) { method := "/zetachain.zetacore.observer.Query/TSS" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetTSS(ctx) require.NoError(t, err) @@ -704,7 +613,7 @@ func TestZetacore_GetEthTssAddress(t *testing.T) { method := "/zetachain.zetacore.observer.Query/GetTssAddress" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetEVMTSSAddress(ctx) require.NoError(t, err) @@ -722,7 +631,7 @@ func TestZetacore_GetBtcTssAddress(t *testing.T) { method := "/zetachain.zetacore.observer.Query/GetTssAddress" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBTCTSSAddress(ctx, 8332) require.NoError(t, err) @@ -747,7 +656,7 @@ func TestZetacore_GetTssHistory(t *testing.T) { method := "/zetachain.zetacore.observer.Query/TssHistory" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetTSSHistory(ctx) require.NoError(t, err) @@ -771,7 +680,7 @@ func TestZetacore_GetOutboundTracker(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/OutboundTracker" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) ctx := context.Background() resp, err := client.GetOutboundTracker(ctx, chain, 456) @@ -806,7 +715,7 @@ func TestZetacore_GetAllOutboundTrackerByChain(t *testing.T) { method := "/zetachain.zetacore.crosschain.Query/OutboundTrackerAllByChain" setupMockServer(t, crosschaintypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetAllOutboundTrackerByChain(ctx, chain.ChainId, interfaces.Ascending) require.NoError(t, err) @@ -832,7 +741,7 @@ func TestZetacore_GetPendingNoncesByChain(t *testing.T) { method := "/zetachain.zetacore.observer.Query/PendingNoncesByChain" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetPendingNoncesByChain(ctx, chains.Ethereum.ChainId) require.NoError(t, err) @@ -853,7 +762,7 @@ func TestZetacore_GetBlockHeaderChainState(t *testing.T) { method := "/zetachain.zetacore.lightclient.Query/ChainState" setupMockServer(t, lightclienttypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetBlockHeaderChainState(ctx, chainID) require.NoError(t, err) @@ -889,7 +798,7 @@ func TestZetacore_GetSupportedChains(t *testing.T) { method := "/zetachain.zetacore.observer.Query/SupportedChains" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetSupportedChains(ctx) require.NoError(t, err) @@ -912,11 +821,7 @@ func TestZetacore_GetAdditionalChains(t *testing.T) { setupMockServer(t, authoritytypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, - withDefaultObserverKeys(), - withAccountRetriever(t, 100, 100), - withTendermint(mocks.NewSDKClientWithErr(t, nil, 0).SetBroadcastTxHash(sampleHash)), - ) + client := setupZetacoreClients(t) resp, err := client.GetAdditionalChains(ctx) require.NoError(t, err) @@ -940,7 +845,7 @@ func TestZetacore_GetPendingNonces(t *testing.T) { method := "/zetachain.zetacore.observer.Query/PendingNoncesAll" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.GetPendingNonces(ctx) require.NoError(t, err) @@ -967,7 +872,7 @@ func TestZetacore_Prove(t *testing.T) { method := "/zetachain.zetacore.lightclient.Query/Prove" setupMockServer(t, lightclienttypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.Prove(ctx, blockHash, txHash, int64(txIndex), nil, chainId) require.NoError(t, err) @@ -985,40 +890,9 @@ func TestZetacore_HasVoted(t *testing.T) { method := "/zetachain.zetacore.observer.Query/HasVoted" setupMockServer(t, observertypes.RegisterQueryServer, method, input, expectedOutput) - client := setupZetacoreClient(t, withDefaultObserverKeys()) + client := setupZetacoreClients(t) resp, err := client.HasVoted(ctx, "123456asdf", "zeta1l40mm7meacx03r4lp87s9gkxfan32xnznp42u6") require.NoError(t, err) require.Equal(t, expectedOutput.HasVoted, resp) } - -func TestZetacore_GetZetaHotKeyBalance(t *testing.T) { - ctx := context.Background() - - expectedOutput := banktypes.QueryBalanceResponse{ - Balance: &types.Coin{ - Denom: config.BaseDenom, - Amount: types.NewInt(55646484), - }, - } - input := banktypes.QueryBalanceRequest{ - Address: types.AccAddress(mocks.TestKeyringPair.PubKey().Address().Bytes()).String(), - Denom: config.BaseDenom, - } - method := "/cosmos.bank.v1beta1.Query/Balance" - setupMockServer(t, banktypes.RegisterQueryServer, method, input, expectedOutput) - - client := setupZetacoreClient(t, withDefaultObserverKeys()) - - // should be able to get balance of signer - client.keys = keys.NewKeysWithKeybase(mocks.NewKeyring(), types.AccAddress{}, "bob", "") - resp, err := client.GetZetaHotKeyBalance(ctx) - require.NoError(t, err) - require.Equal(t, expectedOutput.Balance.Amount, resp) - - // should return error on empty signer - client.keys = keys.NewKeysWithKeybase(mocks.NewKeyring(), types.AccAddress{}, "", "") - resp, err = client.GetZetaHotKeyBalance(ctx) - require.Error(t, err) - require.Equal(t, types.ZeroInt(), resp) -} diff --git a/precompiles/precompiles.go b/precompiles/precompiles.go new file mode 100644 index 0000000000..e3901aa873 --- /dev/null +++ b/precompiles/precompiles.go @@ -0,0 +1,43 @@ +package precompiles + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + ethparams "github.com/ethereum/go-ethereum/params" + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + + "github.com/zeta-chain/zetacore/precompiles/prototype" + "github.com/zeta-chain/zetacore/x/fungible/keeper" +) + +// EnabledStatefulContracts contains the list of all enabled stateful precompiles. +// This is useful for listing and reading from other packages, such as BlockedAddrs() function. +// Setting to false a contract here will disable it, not being included in the blockchain. +var EnabledStatefulContracts = map[common.Address]bool{ + prototype.ContractAddress: true, +} + +// StatefulContracts returns all the registered precompiled contracts. +func StatefulContracts( + fungibleKeeper *keeper.Keeper, + cdc codec.Codec, + gasConfig storetypes.GasConfig, +) (precompiledContracts []evmkeeper.CustomContractFn) { + // Initialize at 0 the custom compiled contracts and the addresses. + precompiledContracts = make([]evmkeeper.CustomContractFn, 0) + + // Define the regular contract function. + if EnabledStatefulContracts[prototype.ContractAddress] { + prototypeContract := func(_ sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract { + return prototype.NewIPrototypeContract(fungibleKeeper, cdc, gasConfig) + } + + // Append the regular contract to the precompiledContracts slice. + precompiledContracts = append(precompiledContracts, prototypeContract) + } + + return precompiledContracts +} diff --git a/precompiles/precompiles_test.go b/precompiles/precompiles_test.go new file mode 100644 index 0000000000..06c8ccb0bb --- /dev/null +++ b/precompiles/precompiles_test.go @@ -0,0 +1,39 @@ +package precompiles + +import ( + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + ethparams "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/zetacore/testutil/keeper" +) + +func Test_StatefulContracts(t *testing.T) { + k, ctx, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + + var expectedContracts int + for _, enabled := range EnabledStatefulContracts { + if enabled { + expectedContracts++ + } + } + + // StatefulContracts() should return all the enabled contracts. + contracts := StatefulContracts(k, appCodec, gasConfig) + require.NotNil(t, contracts, "StatefulContracts() should not return a nil slice") + require.Len(t, contracts, expectedContracts, "StatefulContracts() should return all the enabled contracts") + + // Extract the contract function from the first contract. + customContractFn := contracts[0] + contract := customContractFn(ctx, ethparams.Rules{}) + + // Check the contract function returns a valid address. + contractAddr := contract.Address() + require.NotNil(t, contractAddr, "The called contract should have a valid address") +} diff --git a/precompiles/prototype/IPrototype.abi b/precompiles/prototype/IPrototype.abi new file mode 100644 index 0000000000..d510aa3ec5 --- /dev/null +++ b/precompiles/prototype/IPrototype.abi @@ -0,0 +1,64 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "name": "bech32ToHexAddr", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prefix", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "bech32ify", + "outputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int64", + "name": "chainID", + "type": "int64" + } + ], + "name": "getGasStabilityPoolBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/precompiles/prototype/IPrototype.go b/precompiles/prototype/IPrototype.go new file mode 100644 index 0000000000..ab97bd36fc --- /dev/null +++ b/precompiles/prototype/IPrototype.go @@ -0,0 +1,274 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package prototype + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IPrototypeMetaData contains all meta data concerning the IPrototype contract. +var IPrototypeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"name\":\"bech32ToHexAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"prefix\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"bech32ify\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"bech32\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int64\",\"name\":\"chainID\",\"type\":\"int64\"}],\"name\":\"getGasStabilityPoolBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// IPrototypeABI is the input ABI used to generate the binding from. +// Deprecated: Use IPrototypeMetaData.ABI instead. +var IPrototypeABI = IPrototypeMetaData.ABI + +// IPrototype is an auto generated Go binding around an Ethereum contract. +type IPrototype struct { + IPrototypeCaller // Read-only binding to the contract + IPrototypeTransactor // Write-only binding to the contract + IPrototypeFilterer // Log filterer for contract events +} + +// IPrototypeCaller is an auto generated read-only Go binding around an Ethereum contract. +type IPrototypeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IPrototypeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IPrototypeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPrototypeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IPrototypeSession struct { + Contract *IPrototype // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPrototypeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IPrototypeCallerSession struct { + Contract *IPrototypeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IPrototypeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IPrototypeTransactorSession struct { + Contract *IPrototypeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPrototypeRaw is an auto generated low-level Go binding around an Ethereum contract. +type IPrototypeRaw struct { + Contract *IPrototype // Generic contract binding to access the raw methods on +} + +// IPrototypeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IPrototypeCallerRaw struct { + Contract *IPrototypeCaller // Generic read-only contract binding to access the raw methods on +} + +// IPrototypeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IPrototypeTransactorRaw struct { + Contract *IPrototypeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIPrototype creates a new instance of IPrototype, bound to a specific deployed contract. +func NewIPrototype(address common.Address, backend bind.ContractBackend) (*IPrototype, error) { + contract, err := bindIPrototype(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IPrototype{IPrototypeCaller: IPrototypeCaller{contract: contract}, IPrototypeTransactor: IPrototypeTransactor{contract: contract}, IPrototypeFilterer: IPrototypeFilterer{contract: contract}}, nil +} + +// NewIPrototypeCaller creates a new read-only instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeCaller(address common.Address, caller bind.ContractCaller) (*IPrototypeCaller, error) { + contract, err := bindIPrototype(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IPrototypeCaller{contract: contract}, nil +} + +// NewIPrototypeTransactor creates a new write-only instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeTransactor(address common.Address, transactor bind.ContractTransactor) (*IPrototypeTransactor, error) { + contract, err := bindIPrototype(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IPrototypeTransactor{contract: contract}, nil +} + +// NewIPrototypeFilterer creates a new log filterer instance of IPrototype, bound to a specific deployed contract. +func NewIPrototypeFilterer(address common.Address, filterer bind.ContractFilterer) (*IPrototypeFilterer, error) { + contract, err := bindIPrototype(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IPrototypeFilterer{contract: contract}, nil +} + +// bindIPrototype binds a generic wrapper to an already deployed contract. +func bindIPrototype(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IPrototypeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPrototype *IPrototypeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPrototype.Contract.IPrototypeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPrototype *IPrototypeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPrototype.Contract.IPrototypeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPrototype *IPrototypeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPrototype.Contract.IPrototypeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPrototype *IPrototypeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPrototype.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPrototype *IPrototypeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPrototype.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPrototype *IPrototypeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPrototype.Contract.contract.Transact(opts, method, params...) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeCaller) Bech32ToHexAddr(opts *bind.CallOpts, bech32 string) (common.Address, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "bech32ToHexAddr", bech32) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _IPrototype.Contract.Bech32ToHexAddr(&_IPrototype.CallOpts, bech32) +} + +// Bech32ToHexAddr is a free data retrieval call binding the contract method 0xe4e2a4ec. +// +// Solidity: function bech32ToHexAddr(string bech32) view returns(address addr) +func (_IPrototype *IPrototypeCallerSession) Bech32ToHexAddr(bech32 string) (common.Address, error) { + return _IPrototype.Contract.Bech32ToHexAddr(&_IPrototype.CallOpts, bech32) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeCaller) Bech32ify(opts *bind.CallOpts, prefix string, addr common.Address) (string, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "bech32ify", prefix, addr) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _IPrototype.Contract.Bech32ify(&_IPrototype.CallOpts, prefix, addr) +} + +// Bech32ify is a free data retrieval call binding the contract method 0x0615b74e. +// +// Solidity: function bech32ify(string prefix, address addr) view returns(string bech32) +func (_IPrototype *IPrototypeCallerSession) Bech32ify(prefix string, addr common.Address) (string, error) { + return _IPrototype.Contract.Bech32ify(&_IPrototype.CallOpts, prefix, addr) +} + +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. +// +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeCaller) GetGasStabilityPoolBalance(opts *bind.CallOpts, chainID int64) (*big.Int, error) { + var out []interface{} + err := _IPrototype.contract.Call(opts, &out, "getGasStabilityPoolBalance", chainID) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. +// +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeSession) GetGasStabilityPoolBalance(chainID int64) (*big.Int, error) { + return _IPrototype.Contract.GetGasStabilityPoolBalance(&_IPrototype.CallOpts, chainID) +} + +// GetGasStabilityPoolBalance is a free data retrieval call binding the contract method 0x3ee8d1a4. +// +// Solidity: function getGasStabilityPoolBalance(int64 chainID) view returns(uint256 result) +func (_IPrototype *IPrototypeCallerSession) GetGasStabilityPoolBalance(chainID int64) (*big.Int, error) { + return _IPrototype.Contract.GetGasStabilityPoolBalance(&_IPrototype.CallOpts, chainID) +} diff --git a/precompiles/prototype/IPrototype.json b/precompiles/prototype/IPrototype.json new file mode 100644 index 0000000000..3b7c9ea8cb --- /dev/null +++ b/precompiles/prototype/IPrototype.json @@ -0,0 +1,66 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "name": "bech32ToHexAddr", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "prefix", + "type": "string" + }, + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "bech32ify", + "outputs": [ + { + "internalType": "string", + "name": "bech32", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int64", + "name": "chainID", + "type": "int64" + } + ], + "name": "getGasStabilityPoolBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/precompiles/prototype/IPrototype.sol b/precompiles/prototype/IPrototype.sol new file mode 100644 index 0000000000..eb8f34d770 --- /dev/null +++ b/precompiles/prototype/IPrototype.sol @@ -0,0 +1,34 @@ +pragma solidity ^0.8.26; + +/// @dev The IPrototype contract's address. +address constant IPROTOTYPE_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000065; // 101 + +/// @dev The IPrototype contract's instance. +IPrototype constant IPROTOTYPE_CONTRACT = IPrototype( + IPROTOTYPE_PRECOMPILE_ADDRESS +); + +interface IPrototype { + /// @dev converting a bech32 address to hexadecimal address. + /// @param bech32 The bech32 address. + /// @return addr The hexadecimal address. + function bech32ToHexAddr( + string memory bech32 + ) external view returns (address addr); + + /// @dev converting a hex address to bech32 address. + /// @param prefix of the bech32, e.g. zeta. + /// @param addr The hex address + /// @return bech32 The bech32 address. + function bech32ify( + string memory prefix, + address addr + ) external view returns (string memory bech32); + + /// @dev returns the balance of the gas stability pool + /// @param chainID to query gas. + /// @return result of the call. + function getGasStabilityPoolBalance( + int64 chainID + ) external view returns (uint256 result); +} diff --git a/precompiles/prototype/bindings.go b/precompiles/prototype/bindings.go new file mode 100644 index 0000000000..e4a31a5e56 --- /dev/null +++ b/precompiles/prototype/bindings.go @@ -0,0 +1,7 @@ +//go:generate sh -c "solc IPrototype.sol --combined-json abi | jq '.contracts.\"IPrototype.sol:IPrototype\"' > IPrototype.json" +//go:generate sh -c "cat IPrototype.json | jq .abi > IPrototype.abi" +//go:generate sh -c "abigen --abi IPrototype.abi --pkg prototype --type IPrototype --out IPrototype.go" + +package prototype + +var _ Contract diff --git a/precompiles/prototype/prototype.go b/precompiles/prototype/prototype.go new file mode 100644 index 0000000000..eeba2f9328 --- /dev/null +++ b/precompiles/prototype/prototype.go @@ -0,0 +1,258 @@ +package prototype + +import ( + "fmt" + "strings" + + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + + ptypes "github.com/zeta-chain/zetacore/precompiles/types" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" +) + +const ( + Bech32ToHexAddrMethodName = "bech32ToHexAddr" + Bech32ifyMethodName = "bech32ify" + GetGasStabilityPoolBalanceName = "getGasStabilityPoolBalance" +) + +var ( + ABI abi.ABI + ContractAddress = common.HexToAddress("0x0000000000000000000000000000000000000065") + GasRequiredByMethod = map[[4]byte]uint64{} +) + +func init() { + initABI() +} + +func initABI() { + if err := ABI.UnmarshalJSON([]byte(IPrototypeMetaData.ABI)); err != nil { + panic(err) + } + + GasRequiredByMethod = map[[4]byte]uint64{} + for methodName := range ABI.Methods { + var methodID [4]byte + copy(methodID[:], ABI.Methods[methodName].ID[:4]) + switch methodName { + case Bech32ToHexAddrMethodName: + GasRequiredByMethod[methodID] = 500 + case Bech32ifyMethodName: + GasRequiredByMethod[methodID] = 500 + case GetGasStabilityPoolBalanceName: + GasRequiredByMethod[methodID] = 10000 + default: + GasRequiredByMethod[methodID] = 0 + } + } +} + +type Contract struct { + ptypes.BaseContract + + fungibleKeeper fungiblekeeper.Keeper + cdc codec.Codec + kvGasConfig storetypes.GasConfig +} + +func NewIPrototypeContract( + fungibleKeeper *fungiblekeeper.Keeper, + cdc codec.Codec, + kvGasConfig storetypes.GasConfig, +) *Contract { + return &Contract{ + BaseContract: ptypes.NewBaseContract(ContractAddress), + fungibleKeeper: *fungibleKeeper, + cdc: cdc, + kvGasConfig: kvGasConfig, + } +} + +// Address() is required to implement the PrecompiledContract interface. +func (c *Contract) Address() common.Address { + return ContractAddress +} + +// Abi() is required to implement the PrecompiledContract interface. +func (c *Contract) Abi() abi.ABI { + return ABI +} + +// RequiredGas is required to implement the PrecompiledContract interface. +// The gas has to be calculated deterministically based on the input. +func (c *Contract) RequiredGas(input []byte) uint64 { + // base cost to prevent large input size + baseCost := uint64(len(input)) * c.kvGasConfig.WriteCostPerByte + + // get methodID (first 4 bytes) + var methodID [4]byte + copy(methodID[:], input[:4]) + + if requiredGas, ok := GasRequiredByMethod[methodID]; ok { + return requiredGas + baseCost + } + + // Can not happen, but return 0 if the method is not found. + return 0 +} + +// Bech32ToHexAddr converts a bech32 address to a hex address. +func (c *Contract) Bech32ToHexAddr(method *abi.Method, args []interface{}) ([]byte, error) { + if len(args) != 1 { + return nil, &ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 1, + } + } + + bech32String, ok := args[0].(string) + if !ok { + return nil, fmt.Errorf("invalid argument, wanted a string, got: %T", args[0]) + } + + bech32String = strings.TrimSpace(bech32String) + if bech32String == "" { + return nil, fmt.Errorf("invalid bech32 address: %s", bech32String) + } + + // 1 is always the separator between the bech32 prefix and the bech32 data part. + // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 + bech32Prefix, bech32Data, found := strings.Cut(bech32String, "1") + if !found || bech32Data == "" || bech32Prefix == "" || bech32Prefix == bech32String { + return nil, fmt.Errorf("invalid bech32 address: %s", bech32String) + } + + addressBz, err := sdk.GetFromBech32(bech32String, bech32Prefix) + if err != nil { + return nil, err + } + + if err := sdk.VerifyAddressFormat(addressBz); err != nil { + return nil, err + } + + return method.Outputs.Pack(common.BytesToAddress(addressBz)) +} + +// Bech32ify converts a hex address to a bech32 address. +func (c *Contract) Bech32ify(method *abi.Method, args []interface{}) ([]byte, error) { + if len(args) != 2 { + return nil, &ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 2, + } + } + + cfg := sdk.GetConfig() + prefix, ok := args[0].(string) + if !ok { + return nil, fmt.Errorf("invalid bech32 human readable prefix (HRP): %v", args[0]) + } + + if strings.TrimSpace(prefix) == "" { + return nil, fmt.Errorf( + "invalid bech32 human readable prefix (HRP). Please provide a either an account, validator or consensus address prefix (eg: %s, %s, %s)", + cfg.GetBech32AccountAddrPrefix(), + cfg.GetBech32ValidatorAddrPrefix(), + cfg.GetBech32ConsensusAddrPrefix(), + ) + } + + address, ok := args[1].(common.Address) + if !ok { + return nil, fmt.Errorf("invalid hex address") + } + + // NOTE: safety check, should not happen given that the address is 20 bytes. + if err := sdk.VerifyAddressFormat(address.Bytes()); err != nil { + return nil, err + } + + bech32Str, err := sdk.Bech32ifyAddressBytes(prefix, address.Bytes()) + if err != nil { + return nil, err + } + + addressBz, err := sdk.GetFromBech32(bech32Str, prefix) + if err != nil { + return nil, err + } + + if err := sdk.VerifyAddressFormat(addressBz); err != nil { + return nil, err + } + + return method.Outputs.Pack(bech32Str) +} + +func (c *Contract) GetGasStabilityPoolBalance( + ctx sdk.Context, + method *abi.Method, + args []interface{}, +) ([]byte, error) { + if len(args) != 1 { + return nil, &(ptypes.ErrInvalidNumberOfArgs{ + Got: len(args), + Expect: 1, + }) + } + + // Unwrap arguments. The chainID is the first and unique argument. + chainID, ok := args[0].(int64) + if !ok { + return nil, ptypes.ErrInvalidArgument{ + Got: chainID, + } + } + + balance, err := c.fungibleKeeper.GetGasStabilityPoolBalance(ctx, chainID) + if err != nil { + return nil, fmt.Errorf("error calling fungible keeper: %s", err.Error()) + } + + return method.Outputs.Pack(balance) +} + +// Run is the entrypoint of the precompiled contract, it switches over the input method, +// and execute them accordingly. +func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, error) { + method, err := ABI.MethodById(contract.Input[:4]) + if err != nil { + return nil, err + } + + args, err := method.Inputs.Unpack(contract.Input[4:]) + if err != nil { + return nil, err + } + + stateDB := evm.StateDB.(ptypes.ExtStateDB) + + switch method.Name { + case GetGasStabilityPoolBalanceName: + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.GetGasStabilityPoolBalance(ctx, method, args) + return err + }) + if execErr != nil { + return nil, err + } + return res, nil + + case Bech32ToHexAddrMethodName: + return c.Bech32ToHexAddr(method, args) + case Bech32ifyMethodName: + return c.Bech32ify(method, args) + default: + return nil, ptypes.ErrInvalidMethod{ + Method: method.Name, + } + } +} diff --git a/precompiles/prototype/prototype_test.go b/precompiles/prototype/prototype_test.go new file mode 100644 index 0000000000..8999fa14eb --- /dev/null +++ b/precompiles/prototype/prototype_test.go @@ -0,0 +1,347 @@ +package prototype + +import ( + "encoding/json" + "testing" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + "github.com/zeta-chain/zetacore/precompiles/types" + "github.com/zeta-chain/zetacore/testutil/keeper" +) + +func Test_IPrototypeContract(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + t.Run("should create contract and check address and ABI", func(t *testing.T) { + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + address := contract.Address() + require.Equal(t, ContractAddress, address, "contract address should match the precompiled address") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + }) + + t.Run("should check methods are present in ABI", func(t *testing.T) { + contract := NewIPrototypeContract(k, appCodec, gasConfig) + abi := contract.Abi() + + require.NotNil(t, abi.Methods[Bech32ToHexAddrMethodName], "bech32ToHexAddr method should be present in the ABI") + require.NotNil(t, abi.Methods[Bech32ifyMethodName], "bech32ify method should be present in the ABI") + require.NotNil( + t, + abi.Methods[GetGasStabilityPoolBalanceName], + "getGasStabilityPoolBalance method should be present in the ABI", + ) + }) + + t.Run("should check gas requirements for methods", func(t *testing.T) { + contract := NewIPrototypeContract(k, appCodec, gasConfig) + abi := contract.Abi() + var method [4]byte + + t.Run("bech32ToHexAddr", func(t *testing.T) { + gasBech32ToHex := contract.RequiredGas(abi.Methods[Bech32ToHexAddrMethodName].ID) + copy(method[:], abi.Methods[Bech32ToHexAddrMethodName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasBech32ToHex, + "bech32ToHexAddr method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasBech32ToHex, + ) + }) + + t.Run("bech32ify", func(t *testing.T) { + gasBech32ify := contract.RequiredGas(abi.Methods[Bech32ifyMethodName].ID) + copy(method[:], abi.Methods[Bech32ifyMethodName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasBech32ify, + "bech32ify method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasBech32ify, + ) + }) + + t.Run("getGasStabilityPoolBalance", func(t *testing.T) { + gasGetGasStabilityPoolBalance := contract.RequiredGas(abi.Methods[GetGasStabilityPoolBalanceName].ID) + copy(method[:], abi.Methods[GetGasStabilityPoolBalanceName].ID[:4]) + baseCost := uint64(len(method)) * gasConfig.WriteCostPerByte + require.Equal( + t, + GasRequiredByMethod[method]+baseCost, + gasGetGasStabilityPoolBalance, + "getGasStabilityPoolBalance method should require %d gas, got %d", + GasRequiredByMethod[method]+baseCost, + gasGetGasStabilityPoolBalance, + ) + }) + + t.Run("invalid method", func(t *testing.T) { + invalidMethodBytes := []byte("invalidMethod") + gasInvalidMethod := contract.RequiredGas(invalidMethodBytes) + require.Equal( + t, + uint64(0), + gasInvalidMethod, + "invalid method should require %d gas, got %d", + uint64(0), + gasInvalidMethod, + ) + }) + }) +} + +func Test_Bech32ToHexAddress(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + methodID := abi.Methods[Bech32ToHexAddrMethodName] + + t.Run("should succeed with valid bech32 address", func(t *testing.T) { + args := []interface{}{"zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u"} + + rawBytes, err := contract.Bech32ToHexAddr(&methodID, args) + require.NoError(t, err, "Bech32ToHexAddr should not return an error") + + addr := common.BytesToAddress(rawBytes[12:]) + require.Equal( + t, + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), + addr, + "Bech32ToHexAddr should return the correct address, got: %v", + addr, + ) + }) + + t.Run("should fail if invalid argument type", func(t *testing.T) { + args := []interface{}{1} + + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected invalid argument; wanted string; got: %T", args[0]) + }) + + t.Run("should fail if invalid bech32 address", func(t *testing.T) { + t.Run("invalid bech32 format", func(t *testing.T) { + args := []interface{}{"foobar"} + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; invalid bech32 address") + }) + + t.Run("invalid bech32 prefix", func(t *testing.T) { + args := []interface{}{"foobar1"} + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; invalid bech32 addresss") + }) + + t.Run("invalid bech32 decoding", func(t *testing.T) { + args := []interface{}{"foobar1foobar"} + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error; decoding bech32 failed") + }) + + t.Run("invalid number of arguments", func(t *testing.T) { + args := []interface{}{"zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", "second argument"} + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 1; got: 2") + require.IsType( + t, + &types.ErrInvalidNumberOfArgs{}, + err, + "expected error type: ErrInvalidNumberOfArgs, got: %T", + err, + ) + }) + }) + + t.Run("should fail if empty address argument", func(t *testing.T) { + args := []interface{}{""} + _, err := contract.Bech32ToHexAddr(&methodID, args) + require.Error(t, err, "expected error invalid bech32 address: %v", args[0]) + }) +} + +func Test_Bech32ify(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + methodID := abi.Methods[Bech32ifyMethodName] + + t.Run("should succeed with zeta HRP", func(t *testing.T) { + args := []interface{}{"zeta", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")} + + rawBytes, err := contract.Bech32ify(&methodID, args) + require.NoError(t, err, "Bech32ify prefix zeta should not return an error") + + zetaAddr := string(rawBytes[64:107]) + require.Equal( + t, + "zeta1h8duy2dltz9xz0qqhm5wvcnj02upy887fyn43u", + zetaAddr, + "Bech32ify prefix zeta should return the correct address, got: %v", + zetaAddr, + ) + }) + + t.Run("should succeed with cosmos HRP", func(t *testing.T) { + args := []interface{}{"cosmos", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")} + + rawBytes, err := contract.Bech32ify(&methodID, args) + require.NoError(t, err, "Bech32ify prefix cosmos should not return an error") + + zetaAddr := string(rawBytes[64:107]) + require.Equal( + t, + "cosmos1h8duy2dltz9xz0qqhm5wvcnj02upy887lqaq", + zetaAddr, + "Bech32ify prefix cosmos should return the correct address, got: %v", + zetaAddr, + ) + }) + + t.Run("should fail with invalid arguments", func(t *testing.T) { + t.Run("too many arguments", func(t *testing.T) { + args := []interface{}{ + "zeta", + common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE"), + "third argument", + } + _, err := contract.Bech32ify(&methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 2; got: 3") + require.IsType( + t, + &types.ErrInvalidNumberOfArgs{}, + err, + "expected error type: ErrInvalidNumberOfArgs, got: %T", + err, + ) + }) + + t.Run("invalid HRP", func(t *testing.T) { + args := []interface{}{1337, common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")} + _, err := contract.Bech32ify(&methodID, args) + require.Error(t, err, "expected error invalid bech32 human readable prefix (HRP)") + }) + + t.Run("invalid hex address", func(t *testing.T) { + args := []interface{}{"zeta", 1337} + _, err := contract.Bech32ify(&methodID, args) + require.Error(t, err, "expected error invalid hex address") + }) + + t.Run("empty HRP", func(t *testing.T) { + args := []interface{}{"", common.HexToAddress("0xB9Dbc229Bf588A613C00BEE8e662727AB8121cfE")} + _, err := contract.Bech32ify(&methodID, args) + require.Error( + t, + err, + "expected error invalid bech32 human readable prefix (HRP). Please provide either an account, validator, or consensus address prefix (eg: cosmos, cosmosvaloper, cosmosvalcons)", + ) + }) + }) +} + +func Test_GetGasStabilityPoolBalance(t *testing.T) { + // Only check the function is called correctly inside the contract, and it returns the expected error. + // Configuring a local environment for this contract would require deploying system contracts and gas pools. + // This method is tested thoroughly in the e2e tests. + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, ctx, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + methodID := abi.Methods[GetGasStabilityPoolBalanceName] + + args := []interface{}{int64(1337)} + + _, err := contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + require.Error( + t, + err, + "error calling fungible keeper: failed to get system contract variable: state variable not found", + ) + + t.Run("should fail with invalid arguments", func(t *testing.T) { + + t.Run("invalid number of arguments", func(t *testing.T) { + args := []interface{}{int64(1337), "second argument"} + _, err := contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + require.Error(t, err, "expected invalid number of arguments; expected 2; got: 3") + require.IsType( + t, + &types.ErrInvalidNumberOfArgs{}, + err, + "expected error type: ErrInvalidNumberOfArgs, got: %T", + err, + ) + }) + + t.Run("invalid chainID", func(t *testing.T) { + args := []interface{}{"foobar"} + _, err := contract.GetGasStabilityPoolBalance(ctx, &methodID, args) + require.Error(t, err, "expected int64, got: %T", args[0]) + require.IsType(t, types.ErrInvalidArgument{}, err, "expected error type: ErrInvalidArgument, got: %T", err) + }) + }) +} + +func Test_InvalidMethod(t *testing.T) { + var encoding ethermint.EncodingConfig + appCodec := encoding.Codec + k, _, _, _ := keeper.FungibleKeeper(t) + gasConfig := storetypes.TransientGasConfig() + + contract := NewIPrototypeContract(k, appCodec, gasConfig) + require.NotNil(t, contract, "NewIPrototypeContract() should not return a nil contract") + + abi := contract.Abi() + require.NotNil(t, abi, "contract ABI should not be nil") + + _, doNotExist := abi.Methods["invalidMethod"] + require.False(t, doNotExist, "invalidMethod should not be present in the ABI") +} + +func Test_InvalidABI(t *testing.T) { + IPrototypeMetaData.ABI = "invalid json" + defer func() { + if r := recover(); r != nil { + require.IsType(t, &json.SyntaxError{}, r, "expected error type: json.SyntaxError, got: %T", r) + } + }() + + initABI() +} diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go new file mode 100644 index 0000000000..0cc6928541 --- /dev/null +++ b/precompiles/types/errors.go @@ -0,0 +1,44 @@ +package types + +import "fmt" + +/* +Address related errors +*/ +type ErrInvalidAddr struct { + Got string +} + +func (e ErrInvalidAddr) Error() string { + return fmt.Sprintf("invalid address %s", e.Got) +} + +/* +Argument related errors +*/ +type ErrInvalidNumberOfArgs struct { + Got, Expect int +} + +func (e ErrInvalidNumberOfArgs) Error() string { + return fmt.Sprintf("invalid number of arguments; expected %d; got: %d", e.Expect, e.Got) +} + +type ErrInvalidArgument struct { + Got any +} + +func (e ErrInvalidArgument) Error() string { + return fmt.Sprintf("invalid argument: %s", e.Got.(string)) +} + +/* +Method related errors +*/ +type ErrInvalidMethod struct { + Method string +} + +func (e ErrInvalidMethod) Error() string { + return fmt.Sprintf("invalid method: %s", e.Method) +} diff --git a/precompiles/types/errors_test.go b/precompiles/types/errors_test.go new file mode 100644 index 0000000000..5693a450eb --- /dev/null +++ b/precompiles/types/errors_test.go @@ -0,0 +1,48 @@ +package types + +import "testing" + +func Test_ErrInvalidAddr(t *testing.T) { + e := ErrInvalidAddr{ + Got: "foo", + } + got := e.Error() + expect := "invalid address foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidNumberOfArgs(t *testing.T) { + e := ErrInvalidNumberOfArgs{ + Got: 1, + Expect: 2, + } + got := e.Error() + expect := "invalid number of arguments; expected 2; got: 1" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidArgument(t *testing.T) { + e := ErrInvalidArgument{ + Got: "foo", + } + got := e.Error() + expect := "invalid argument: foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} + +func Test_ErrInvalidMethod(t *testing.T) { + e := ErrInvalidMethod{ + Method: "foo", + } + got := e.Error() + expect := "invalid method: foo" + if got != expect { + t.Errorf("Expected %v, got %v", expect, got) + } +} diff --git a/precompiles/types/types.go b/precompiles/types/types.go new file mode 100644 index 0000000000..7bd4a57bfa --- /dev/null +++ b/precompiles/types/types.go @@ -0,0 +1,54 @@ +package types + +import ( + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/zeta-chain/ethermint/x/evm/statedb" +) + +// Interface compliance. +var _ ExtStateDB = (*statedb.StateDB)(nil) +var _ Registrable = (*baseContract)(nil) +var _ BaseContract = (*baseContract)(nil) + +// ExtStateDB defines extra methods of statedb to support stateful precompiled contracts. +// It's used to persist changes into the store. +type ExtStateDB interface { + vm.StateDB + ExecuteNativeAction( + contract common.Address, + converter statedb.EventConverter, + action func(ctx sdk.Context) error, + ) error + CacheContext() sdk.Context +} + +type Registrable interface { + RegistryKey() common.Address +} + +type BaseContract interface { + Registrable +} + +// A baseContract implements Registrable and BaseContract interfaces. +type baseContract struct { + address common.Address +} + +func NewBaseContract(address common.Address) BaseContract { + return &baseContract{ + address: address, + } +} + +func (c *baseContract) RegistryKey() common.Address { + return c.address +} + +func BytesToBigInt(data []byte) *big.Int { + return big.NewInt(0).SetBytes(data[:]) +} diff --git a/precompiles/types/types_test.go b/precompiles/types/types_test.go new file mode 100644 index 0000000000..1193b55426 --- /dev/null +++ b/precompiles/types/types_test.go @@ -0,0 +1,26 @@ +package types + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func Test_BaseContract(t *testing.T) { + addr := common.BytesToAddress([]byte{0x1}) + + contract := NewBaseContract(addr) + require.NotNil(t, contract) + + // By implementing RegistryKey() the baseContract struct implements Registrable. + // Registrable is the unique requisite to implement BaseContract as well. + require.Equal(t, addr, contract.RegistryKey()) +} + +func Test_BytesToBigInt(t *testing.T) { + data := []byte{0x1} + intData := BytesToBigInt(data) + require.NotNil(t, intData) + require.Equal(t, int64(1), intData.Int64()) +} diff --git a/readme.md b/readme.md index 3f00b4b7f5..61f04f632f 100644 --- a/readme.md +++ b/readme.md @@ -16,8 +16,8 @@ smart contracts and messaging between any blockchain. ZetaChain is built with [Cosmos SDK](https://github.com/cosmos/cosmos-sdk), a modular framework for building blockchain and -[Ethermint](https://github.com/evmos/ethermint), a module that implements -EVM-compatibility. +[Ethermint](https://github.com/zeta-chain/ethermint), a module that implements +EVM-compatibility (ZetaChain fork). - [zeta-node](https://github.com/zeta-chain/zeta-node) (this repository) contains the source code for the ZetaChain node (`zetacored`) and the @@ -29,15 +29,18 @@ EVM-compatibility. ## Building the `zetacored`/`zetaclientd` binaries Clone this repository, checkout the latest release tag, and type the following command to build the binaries: + ``` make install ``` -to build. + +to build. This command will install the `zetacored` and `zetaclientd` binaries in your `$GOPATH/bin` directory. -Verify that the version of the binaries match the release tag. +Verify that the version of the binaries match the release tag. + ``` zetacored version zetaclientd version @@ -67,14 +70,12 @@ documentation for all the messages in that module. Find below further documentation for development and running your own ZetaChain node: -* [Run the E2E tests and interact with the localnet](docs/development/LOCAL_TESTING.md) -* [Make a new ZetaChain release](docs/development/RELEASES.md) -* [Deploy your own ZetaChain or Bitcoin node](docs/development/DEPLOY_NODES.md) +- [Run the E2E tests and interact with the localnet](docs/development/LOCAL_TESTING.md) +- [Make a new ZetaChain release](docs/development/RELEASES.md) +- [Deploy your own ZetaChain or Bitcoin node](docs/development/DEPLOY_NODES.md) ## Community [Twitter](https://twitter.com/zetablockchain) | [Discord](https://discord.com/invite/zetachain) | [Telegram](https://t.me/zetachainofficial) | [Website](https://zetachain.com) - - diff --git a/rpc/apis.go b/rpc/apis.go index 2cc5c4b9a9..3f295b7136 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -22,7 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" + ethermint "github.com/zeta-chain/ethermint/types" "github.com/zeta-chain/zetacore/rpc/backend" "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/debug" diff --git a/rpc/backend/account_info.go b/rpc/backend/account_info.go index 59d6a57520..bb9cf39689 100644 --- a/rpc/backend/account_info.go +++ b/rpc/backend/account_info.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -27,8 +27,8 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/backend/account_info_test.go b/rpc/backend/account_info_test.go index 111b6bfb4f..c5937c1425 100644 --- a/rpc/backend/account_info_test.go +++ b/rpc/backend/account_info_test.go @@ -10,8 +10,8 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/backend.go b/rpc/backend/backend.go index 2890cae40b..3749e1d221 100644 --- a/rpc/backend/backend.go +++ b/rpc/backend/backend.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -32,8 +32,8 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/signer/core/apitypes" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" "github.com/zeta-chain/zetacore/server/config" diff --git a/rpc/backend/backend_suite_test.go b/rpc/backend/backend_suite_test.go index 21744e87e3..c6f5ff20da 100644 --- a/rpc/backend/backend_suite_test.go +++ b/rpc/backend/backend_suite_test.go @@ -16,14 +16,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/evmos/ethermint/app" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/crypto/hd" - "github.com/evmos/ethermint/encoding" - "github.com/evmos/ethermint/indexer" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/suite" + "github.com/zeta-chain/ethermint/app" + "github.com/zeta-chain/ethermint/crypto/ethsecp256k1" + "github.com/zeta-chain/ethermint/crypto/hd" + "github.com/zeta-chain/ethermint/encoding" + "github.com/zeta-chain/ethermint/indexer" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend/mocks" rpctypes "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/backend/blocks.go b/rpc/backend/blocks.go index a4a9d03063..a902c7b8cb 100644 --- a/rpc/backend/blocks.go +++ b/rpc/backend/blocks.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -32,8 +32,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc" "google.golang.org/grpc/metadata" diff --git a/rpc/backend/blocks_test.go b/rpc/backend/blocks_test.go index ef8023e448..83fba94cf3 100644 --- a/rpc/backend/blocks_test.go +++ b/rpc/backend/blocks_test.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index 95bedf5a42..781d8ce7c7 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -29,9 +29,9 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -89,7 +89,7 @@ func (b *Backend) Resend( } for _, tx := range pending { - // FIXME does Resend api possible at all? https://github.com/evmos/ethermint/issues/905 + // FIXME does Resend api possible at all? https://github.com/zeta-chain/ethermint/issues/905 p, err := evmtypes.UnwrapEthereumMsg(tx, common.Hash{}) if err != nil { // not valid ethereum tx diff --git a/rpc/backend/call_tx_test.go b/rpc/backend/call_tx_test.go index a30ef6a941..f1b28e0a97 100644 --- a/rpc/backend/call_tx_test.go +++ b/rpc/backend/call_tx_test.go @@ -10,8 +10,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/chain_info.go b/rpc/backend/chain_info.go index c5a06d354a..965f20dcee 100644 --- a/rpc/backend/chain_info.go +++ b/rpc/backend/chain_info.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -28,10 +28,10 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/pkg/errors" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/backend/chain_info_test.go b/rpc/backend/chain_info_test.go index c39215d1bf..7259defa4b 100644 --- a/rpc/backend/chain_info_test.go +++ b/rpc/backend/chain_info_test.go @@ -9,9 +9,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common/hexutil" ethrpc "github.com/ethereum/go-ethereum/rpc" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/client_test.go b/rpc/backend/client_test.go index 952bc215b7..6adf0ea5d0 100644 --- a/rpc/backend/client_test.go +++ b/rpc/backend/client_test.go @@ -17,9 +17,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" mock "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend/mocks" rpc "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/backend/evm_query_client_test.go b/rpc/backend/evm_query_client_test.go index de50ef7ca6..997b6076d6 100644 --- a/rpc/backend/evm_query_client_test.go +++ b/rpc/backend/evm_query_client_test.go @@ -12,10 +12,10 @@ import ( errortypes "github.com/cosmos/cosmos-sdk/types/errors" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/ethereum/go-ethereum/common" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" mock "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" diff --git a/rpc/backend/feemarket_query_client_test.go b/rpc/backend/feemarket_query_client_test.go index d24507eae4..e51bb7e7a5 100644 --- a/rpc/backend/feemarket_query_client_test.go +++ b/rpc/backend/feemarket_query_client_test.go @@ -2,7 +2,7 @@ package backend import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "github.com/zeta-chain/zetacore/rpc/backend/mocks" rpc "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/backend/filters.go b/rpc/backend/filters.go index b989d8099b..400828e307 100644 --- a/rpc/backend/filters.go +++ b/rpc/backend/filters.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( diff --git a/rpc/backend/filters_test.go b/rpc/backend/filters_test.go index 486e51ebf2..56bc32ad2d 100644 --- a/rpc/backend/filters_test.go +++ b/rpc/backend/filters_test.go @@ -6,7 +6,7 @@ import ( tmtypes "github.com/cometbft/cometbft/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend/mocks" ethrpc "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/backend/mocks/evm_query_client.go b/rpc/backend/mocks/evm_query_client.go index 231759d1b0..e5a7fa72dd 100644 --- a/rpc/backend/mocks/evm_query_client.go +++ b/rpc/backend/mocks/evm_query_client.go @@ -9,7 +9,7 @@ import ( mock "github.com/stretchr/testify/mock" - types "github.com/evmos/ethermint/x/evm/types" + types "github.com/zeta-chain/ethermint/x/evm/types" ) // EVMQueryClient is an autogenerated mock type for the EVMQueryClient type diff --git a/rpc/backend/mocks/feemarket_query_client.go b/rpc/backend/mocks/feemarket_query_client.go index 2536699fb0..cf6091a0f1 100644 --- a/rpc/backend/mocks/feemarket_query_client.go +++ b/rpc/backend/mocks/feemarket_query_client.go @@ -9,7 +9,7 @@ import ( mock "github.com/stretchr/testify/mock" - types "github.com/evmos/ethermint/x/feemarket/types" + types "github.com/zeta-chain/ethermint/x/feemarket/types" ) // FeeMarketQueryClient is an autogenerated mock type for the QueryClient type diff --git a/rpc/backend/node_info.go b/rpc/backend/node_info.go index 2b7a99a267..7c661c3fb1 100644 --- a/rpc/backend/node_info.go +++ b/rpc/backend/node_info.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -34,10 +34,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/server/config" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/crypto/ethsecp256k1" + "github.com/zeta-chain/ethermint/server/config" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/backend/node_info_test.go b/rpc/backend/node_info_test.go index 7931cf4230..ccfc3fe551 100644 --- a/rpc/backend/node_info_test.go +++ b/rpc/backend/node_info_test.go @@ -12,9 +12,9 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - ethermint "github.com/evmos/ethermint/types" "github.com/spf13/viper" + "github.com/zeta-chain/ethermint/crypto/ethsecp256k1" + ethermint "github.com/zeta-chain/ethermint/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index a5e004dc45..105f161976 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -29,7 +29,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // SendTransaction sends transaction based on received args using Node's key to sign it diff --git a/rpc/backend/sign_tx_test.go b/rpc/backend/sign_tx_test.go index d50f6fb6bd..791befec4c 100644 --- a/rpc/backend/sign_tx_test.go +++ b/rpc/backend/sign_tx_test.go @@ -12,10 +12,10 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" goethcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/ethereum/eip712" - "github.com/evmos/ethermint/tests" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/crypto/ethsecp256k1" + "github.com/zeta-chain/ethermint/ethereum/eip712" + "github.com/zeta-chain/ethermint/tests" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index 84a78dc6c7..df893bde9e 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -22,8 +22,8 @@ import ( tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/backend/tracing_test.go b/rpc/backend/tracing_test.go index 1abae1818b..d03c85ddb1 100644 --- a/rpc/backend/tracing_test.go +++ b/rpc/backend/tracing_test.go @@ -11,9 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/evmos/ethermint/crypto/ethsecp256k1" - "github.com/evmos/ethermint/indexer" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/crypto/ethsecp256k1" + "github.com/zeta-chain/ethermint/indexer" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend/mocks" ) diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index a65c86743f..e195efb49c 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -26,9 +26,9 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" rpctypes "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/backend/tx_info_test.go b/rpc/backend/tx_info_test.go index f564494f19..8aa336f57d 100644 --- a/rpc/backend/tx_info_test.go +++ b/rpc/backend/tx_info_test.go @@ -12,9 +12,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/evmos/ethermint/indexer" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/indexer" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/metadata" "github.com/zeta-chain/zetacore/rpc/backend/mocks" diff --git a/rpc/backend/utils.go b/rpc/backend/utils.go index 1be9e81b33..21fd67e2df 100644 --- a/rpc/backend/utils.go +++ b/rpc/backend/utils.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package backend import ( @@ -32,7 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc" ethtypes "github.com/ethereum/go-ethereum/core/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/rpc/ethereum/pubsub/pubsub.go b/rpc/ethereum/pubsub/pubsub.go index a8117a8fbb..9238c8a4db 100644 --- a/rpc/ethereum/pubsub/pubsub.go +++ b/rpc/ethereum/pubsub/pubsub.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package pubsub import ( diff --git a/rpc/namespaces/ethereum/debug/api.go b/rpc/namespaces/ethereum/debug/api.go index 1b07828b80..9608fa7d67 100644 --- a/rpc/namespaces/ethereum/debug/api.go +++ b/rpc/namespaces/ethereum/debug/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package debug import ( @@ -34,8 +34,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/rlp" - evmtypes "github.com/evmos/ethermint/x/evm/types" stderrors "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" zetaos "github.com/zeta-chain/zetacore/pkg/os" "github.com/zeta-chain/zetacore/rpc/backend" diff --git a/rpc/namespaces/ethereum/debug/utils.go b/rpc/namespaces/ethereum/debug/utils.go index ae3f0c5ba5..be318ddf2e 100644 --- a/rpc/namespaces/ethereum/debug/utils.go +++ b/rpc/namespaces/ethereum/debug/utils.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package debug import ( diff --git a/rpc/namespaces/ethereum/eth/api.go b/rpc/namespaces/ethereum/eth/api.go index 2a558109af..25b8c99137 100644 --- a/rpc/namespaces/ethereum/eth/api.go +++ b/rpc/namespaces/ethereum/eth/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package eth import ( @@ -23,8 +23,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend" rpctypes "github.com/zeta-chain/zetacore/rpc/types" diff --git a/rpc/namespaces/ethereum/eth/filters/api.go b/rpc/namespaces/ethereum/eth/filters/api.go index a18ba4402e..ffa0611fcf 100644 --- a/rpc/namespaces/ethereum/eth/filters/api.go +++ b/rpc/namespaces/ethereum/eth/filters/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package filters import ( @@ -30,7 +30,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rpc" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/types" ) diff --git a/rpc/namespaces/ethereum/eth/filters/filter_system.go b/rpc/namespaces/ethereum/eth/filters/filter_system.go index 35004b0138..1427916df9 100644 --- a/rpc/namespaces/ethereum/eth/filters/filter_system.go +++ b/rpc/namespaces/ethereum/eth/filters/filter_system.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package filters import ( @@ -32,8 +32,8 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rpc" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" ) diff --git a/rpc/namespaces/ethereum/eth/filters/filters.go b/rpc/namespaces/ethereum/eth/filters/filters.go index 59874611db..fe975dcc62 100644 --- a/rpc/namespaces/ethereum/eth/filters/filters.go +++ b/rpc/namespaces/ethereum/eth/filters/filters.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package filters import ( diff --git a/rpc/namespaces/ethereum/eth/filters/subscription.go b/rpc/namespaces/ethereum/eth/filters/subscription.go index 8566757bd8..7287c44cff 100644 --- a/rpc/namespaces/ethereum/eth/filters/subscription.go +++ b/rpc/namespaces/ethereum/eth/filters/subscription.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package filters import ( diff --git a/rpc/namespaces/ethereum/eth/filters/utils.go b/rpc/namespaces/ethereum/eth/filters/utils.go index 2d4557f568..c8e5013e50 100644 --- a/rpc/namespaces/ethereum/eth/filters/utils.go +++ b/rpc/namespaces/ethereum/eth/filters/utils.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package filters import ( diff --git a/rpc/namespaces/ethereum/miner/api.go b/rpc/namespaces/ethereum/miner/api.go index c1a21f5518..3e4abc9900 100644 --- a/rpc/namespaces/ethereum/miner/api.go +++ b/rpc/namespaces/ethereum/miner/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package miner import ( diff --git a/rpc/namespaces/ethereum/miner/unsupported.go b/rpc/namespaces/ethereum/miner/unsupported.go index d07ac006ac..22e5110555 100644 --- a/rpc/namespaces/ethereum/miner/unsupported.go +++ b/rpc/namespaces/ethereum/miner/unsupported.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package miner import ( diff --git a/rpc/namespaces/ethereum/net/api.go b/rpc/namespaces/ethereum/net/api.go index a04e8066f1..c44e1f42b2 100644 --- a/rpc/namespaces/ethereum/net/api.go +++ b/rpc/namespaces/ethereum/net/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package net import ( @@ -21,7 +21,7 @@ import ( rpcclient "github.com/cometbft/cometbft/rpc/client" "github.com/cosmos/cosmos-sdk/client" - ethermint "github.com/evmos/ethermint/types" + ethermint "github.com/zeta-chain/ethermint/types" ) // PublicAPI is the eth_ prefixed set of APIs in the Web3 JSON-RPC spec. diff --git a/rpc/namespaces/ethereum/personal/api.go b/rpc/namespaces/ethereum/personal/api.go index 71f1aa5271..4420857799 100644 --- a/rpc/namespaces/ethereum/personal/api.go +++ b/rpc/namespaces/ethereum/personal/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package personal import ( @@ -28,9 +28,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" - "github.com/evmos/ethermint/crypto/hd" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/crypto/hd" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/backend" ) diff --git a/rpc/namespaces/ethereum/txpool/api.go b/rpc/namespaces/ethereum/txpool/api.go index 521025cf6a..c42c50b725 100644 --- a/rpc/namespaces/ethereum/txpool/api.go +++ b/rpc/namespaces/ethereum/txpool/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package txpool import ( @@ -23,7 +23,7 @@ import ( ) // PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential. -// NOTE: For more info about the current status of this endpoints see https://github.com/evmos/ethermint/issues/124 +// NOTE: For more info about the current status of this endpoints see https://github.com/zeta-chain/ethermint/issues/124 type PublicAPI struct { logger log.Logger } diff --git a/rpc/namespaces/ethereum/web3/api.go b/rpc/namespaces/ethereum/web3/api.go index 6d3a8f970b..77f01d6bac 100644 --- a/rpc/namespaces/ethereum/web3/api.go +++ b/rpc/namespaces/ethereum/web3/api.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package web3 import ( diff --git a/rpc/types/addrlock.go b/rpc/types/addrlock.go index 0c81cf7af6..2f19e5b634 100644 --- a/rpc/types/addrlock.go +++ b/rpc/types/addrlock.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( diff --git a/rpc/types/block.go b/rpc/types/block.go index 4515e67d8c..cb2c873709 100644 --- a/rpc/types/block.go +++ b/rpc/types/block.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( @@ -27,8 +27,8 @@ import ( grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ethermint "github.com/evmos/ethermint/types" "github.com/spf13/cast" + ethermint "github.com/zeta-chain/ethermint/types" "google.golang.org/grpc/metadata" ) diff --git a/rpc/types/events.go b/rpc/types/events.go index 4650f460a6..886b0e6a87 100644 --- a/rpc/types/events.go +++ b/rpc/types/events.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( @@ -28,8 +28,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - ethermint "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // EventFormat is the format version of the events. @@ -324,7 +324,7 @@ func (p *ParsedTxs) newTx(attrs []abci.EventAttribute) error { // updateTx updates an exiting tx from events, called during parsing. // In event format 2, we update the tx with the attributes of the second `ethereum_tx` event, -// Due to bug https://github.com/evmos/ethermint/issues/1175, the first `ethereum_tx` event may emit incorrect tx hash, +// Due to bug https://github.com/zeta-chain/ethermint/issues/1175, the first `ethereum_tx` event may emit incorrect tx hash, // so we prefer the second event and override the first one. func (p *ParsedTxs) updateTx(eventIndex int, attrs []abci.EventAttribute) error { tx := NewParsedTx(eventIndex) diff --git a/rpc/types/events_test.go b/rpc/types/events_test.go index 79a6fc5f25..b01bd45850 100644 --- a/rpc/types/events_test.go +++ b/rpc/types/events_test.go @@ -6,8 +6,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) func TestParseTxResult(t *testing.T) { diff --git a/rpc/types/query_client.go b/rpc/types/query_client.go index cda2962f18..46ce2d1244 100644 --- a/rpc/types/query_client.go +++ b/rpc/types/query_client.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( @@ -22,8 +22,8 @@ import ( "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/types/tx" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" ) // QueryClient defines a gRPC Client used for: diff --git a/rpc/types/types.go b/rpc/types/types.go index 907eff4740..0d53851866 100644 --- a/rpc/types/types.go +++ b/rpc/types/types.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( diff --git a/rpc/types/utils.go b/rpc/types/utils.go index 5e93d97ae8..addce9521a 100644 --- a/rpc/types/utils.go +++ b/rpc/types/utils.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package types import ( @@ -32,8 +32,8 @@ import ( "github.com/ethereum/go-ethereum/common/math" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" - evmtypes "github.com/evmos/ethermint/x/evm/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" ) // ExceedBlockGasLimitError defines the error message when tx execution exceeds the block gas limit. diff --git a/rpc/websockets.go b/rpc/websockets.go index b2470e0203..48f357de26 100644 --- a/rpc/websockets.go +++ b/rpc/websockets.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package rpc import ( @@ -36,10 +36,10 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/gorilla/mux" "github.com/gorilla/websocket" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/rpc/ethereum/pubsub" rpcfilters "github.com/zeta-chain/zetacore/rpc/namespaces/ethereum/eth/filters" diff --git a/scripts/bindings-stateful-precompiles.sh b/scripts/bindings-stateful-precompiles.sh new file mode 100755 index 0000000000..3083f8bf43 --- /dev/null +++ b/scripts/bindings-stateful-precompiles.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# Check if abigen is installed +if ! command -v abigen &> /dev/null +then + echo "abigen could not be found, installing..." + go install github.com/ethereum/go-ethereum/cmd/abigen@latest +fi + +# Check if solc is installed and at version 0.8.26 +if command -v solc &> /dev/null +then + SOLC_VERSION=$(solc --version | grep -o "Version: 0.8.26") + if [ "$SOLC_VERSION" == "Version: 0.8.26" ]; then + echo "solc version 0.8.26 is already installed." + else + echo "solc is installed but not version 0.8.26. Checking for solc-select..." + if command -v solc-select &> /dev/null + then + echo "solc-select found, installing and using solc 0.8.26..." + solc-select install 0.8.26 + solc-select use 0.8.26 + else + echo "solc-select not found. Please install solc-select or ensure solc 0.8.26 is available." + exit 1 + fi + fi +else + echo "solc is not installed. Checking for solc-select..." + if command -v solc-select &> /dev/null + then + echo "solc-select found, installing and using solc 0.8.26..." + solc-select install 0.8.26 + solc-select use 0.8.26 + else + echo "solc or solc-select could not be found. Please install one of them to proceed." + exit 1 + fi +fi + +# Generic function to generate bindings +function bindings() { + cd $1 + go generate > /dev/null 2>&1 + echo "Generated bindings for $1" +} + +# List of bindings to generate +bindings ./precompiles/prototype + diff --git a/scripts/protoc-gen-openapi.sh b/scripts/protoc-gen-openapi.sh index 994f107b19..3a4a40e097 100755 --- a/scripts/protoc-gen-openapi.sh +++ b/scripts/protoc-gen-openapi.sh @@ -5,7 +5,7 @@ go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.16. go mod download COSMOS_SDK="github.com/cosmos/cosmos-sdk" -ETHERMINT="github.com/evmos/ethermint" +ETHERMINT="github.com/zeta-chain/ethermint" PROTO_TEMPLATE="proto/buf.openapi.yaml" OUTPUT_DIR="./docs/openapi" MERGED_SWAGGER_FILE="openapi.swagger.yaml" diff --git a/server/config/config.go b/server/config/config.go index e62bdfd74a..1f04a16b14 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package config import ( diff --git a/server/config/toml.go b/server/config/toml.go index a61f110dc7..4c296d1f95 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package config // DefaultConfigTemplate defines the configuration template for the EVM RPC configuration diff --git a/server/flags/flags.go b/server/flags/flags.go index abc3d6dc72..3749b62ef0 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package flags import ( diff --git a/server/indexer_cmd.go b/server/indexer_cmd.go index 65d4d2b9e3..b4c39f4934 100644 --- a/server/indexer_cmd.go +++ b/server/indexer_cmd.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package server import ( @@ -23,8 +23,8 @@ import ( tmstore "github.com/cometbft/cometbft/store" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" - "github.com/evmos/ethermint/indexer" "github.com/spf13/cobra" + "github.com/zeta-chain/ethermint/indexer" ) func NewIndexTxCmd() *cobra.Command { diff --git a/server/indexer_service.go b/server/indexer_service.go index d996eac6ba..79115317f5 100644 --- a/server/indexer_service.go +++ b/server/indexer_service.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package server import ( @@ -22,7 +22,7 @@ import ( "github.com/cometbft/cometbft/libs/service" rpcclient "github.com/cometbft/cometbft/rpc/client" "github.com/cometbft/cometbft/types" - ethermint "github.com/evmos/ethermint/types" + ethermint "github.com/zeta-chain/ethermint/types" ) const ( diff --git a/server/json_rpc.go b/server/json_rpc.go index 9abe6b9ecc..4b17ccf413 100644 --- a/server/json_rpc.go +++ b/server/json_rpc.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package server import ( @@ -24,9 +24,9 @@ import ( "github.com/cosmos/cosmos-sdk/server/types" ethlog "github.com/ethereum/go-ethereum/log" ethrpc "github.com/ethereum/go-ethereum/rpc" - ethermint "github.com/evmos/ethermint/types" "github.com/gorilla/mux" "github.com/rs/cors" + ethermint "github.com/zeta-chain/ethermint/types" "github.com/zeta-chain/zetacore/rpc" "github.com/zeta-chain/zetacore/server/config" diff --git a/server/start.go b/server/start.go index 79abab78bf..0301408f91 100644 --- a/server/start.go +++ b/server/start.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package server import ( @@ -52,9 +52,9 @@ import ( "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" ethmetricsexp "github.com/ethereum/go-ethereum/metrics/exp" - "github.com/evmos/ethermint/indexer" - ethermint "github.com/evmos/ethermint/types" "github.com/spf13/cobra" + "github.com/zeta-chain/ethermint/indexer" + ethermint "github.com/zeta-chain/ethermint/types" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/server/util.go b/server/util.go index 94b29cd769..b8a5d5ea63 100644 --- a/server/util.go +++ b/server/util.go @@ -12,7 +12,7 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE +// along with the Ethermint library. If not, see https://github.com/zeta-chain/ethermint/blob/main/LICENSE package server import ( diff --git a/testutil/keeper/authority.go b/testutil/keeper/authority.go index 169b6df526..34b917f2d4 100644 --- a/testutil/keeper/authority.go +++ b/testutil/keeper/authority.go @@ -4,8 +4,10 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/mock" @@ -23,13 +25,12 @@ var ( func initAuthorityKeeper( cdc codec.Codec, - db *tmdb.MemDB, ss store.CommitMultiStore, ) keeper.Keeper { storeKey := sdk.NewKVStoreKey(types.StoreKey) memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, nil) return keeper.NewKeeper( cdc, @@ -46,14 +47,14 @@ func AuthorityKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + stateStore := rootmulti.NewStore(db, log.NewNopLogger()) cdc := NewCodec() // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) // Create the observer keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) require.NoError(t, stateStore.LoadLatestVersion()) diff --git a/testutil/keeper/codec.go b/testutil/keeper/codec.go index 90d8ff6e7d..d9be189d04 100644 --- a/testutil/keeper/codec.go +++ b/testutil/keeper/codec.go @@ -13,8 +13,8 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - etherminttypes "github.com/evmos/ethermint/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + ethermint "github.com/zeta-chain/ethermint/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" emissionstypes "github.com/zeta-chain/zetacore/x/emissions/types" @@ -36,12 +36,11 @@ func NewCodec() *codec.ProtoCodec { evidencetypes.RegisterInterfaces(registry) crisistypes.RegisterInterfaces(registry) evmtypes.RegisterInterfaces(registry) - etherminttypes.RegisterInterfaces(registry) + ethermint.RegisterInterfaces(registry) crosschaintypes.RegisterInterfaces(registry) emissionstypes.RegisterInterfaces(registry) fungibletypes.RegisterInterfaces(registry) observertypes.RegisterInterfaces(registry) - cdc := codec.NewProtoCodec(registry) - return cdc + return codec.NewProtoCodec(registry) } diff --git a/testutil/keeper/config.go b/testutil/keeper/config.go index 9c2c63cf27..ec42304a64 100644 --- a/testutil/keeper/config.go +++ b/testutil/keeper/config.go @@ -1,6 +1,34 @@ package keeper -import sdk "github.com/cosmos/cosmos-sdk/types" +import ( + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/group" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" + + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + emissionstypes "github.com/zeta-chain/zetacore/x/emissions/types" + fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) const ( AccountAddressPrefix = "zeta" @@ -23,3 +51,52 @@ func SetConfig(seal bool) { config.Seal() } } + +func StoreKeys() ( + map[string]*storetypes.KVStoreKey, + map[string]*storetypes.MemoryStoreKey, + map[string]*storetypes.TransientStoreKey, + map[string]storetypes.StoreKey, +) { + keys := sdk.NewKVStoreKeys( + authtypes.StoreKey, + banktypes.StoreKey, + stakingtypes.StoreKey, + distrtypes.StoreKey, + slashingtypes.StoreKey, + govtypes.StoreKey, + paramstypes.StoreKey, + group.StoreKey, + upgradetypes.StoreKey, + evidencetypes.StoreKey, + ibcexported.StoreKey, + ibctransfertypes.StoreKey, + capabilitytypes.StoreKey, + authzkeeper.StoreKey, + evmtypes.StoreKey, + feemarkettypes.StoreKey, + authoritytypes.StoreKey, + lightclienttypes.StoreKey, + crosschaintypes.StoreKey, + observertypes.StoreKey, + fungibletypes.StoreKey, + emissionstypes.StoreKey, + consensusparamtypes.StoreKey, + crisistypes.StoreKey, + ) + tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey) + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + + allKeys := make(map[string]storetypes.StoreKey, len(keys)+len(tkeys)+len(memKeys)) + for k, v := range keys { + allKeys[k] = v + } + for k, v := range tkeys { + allKeys[k] = v + } + for k, v := range memKeys { + allKeys[k] = v + } + + return keys, memKeys, tkeys, allKeys +} diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index 886e3e5792..aae70a32f6 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -5,22 +5,32 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" crosschainmocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/crosschain" "github.com/zeta-chain/zetacore/testutil/sample" + authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" + 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" + fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" + lightclientkeeper "github.com/zeta-chain/zetacore/x/lightclient/keeper" + lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -85,40 +95,54 @@ func CrosschainKeeperWithMocks( t testing.TB, mockOptions CrosschainMockOptions, ) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { - SetConfig(false) - storeKey := sdk.NewKVStoreKey(types.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + keys, memKeys, tkeys, allKeys := StoreKeys() // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + logger := log.NewNopLogger() + stateStore := rootmulti.NewStore(db, logger) cdc := NewCodec() // Create regular keepers - sdkKeepers := NewSDKKeepers(cdc, db, stateStore) + sdkKeepers := NewSDKKeepersWithKeys(cdc, keys, memKeys, tkeys, allKeys) // Create zeta keepers - authorityKeeperTmp := initAuthorityKeeper(cdc, db, stateStore) - lightclientKeeperTmp := initLightclientKeeper(cdc, db, stateStore, authorityKeeperTmp) - observerKeeperTmp := initObserverKeeper( + authorityKeeperTmp := authoritykeeper.NewKeeper( cdc, - db, - stateStore, + keys[authoritytypes.StoreKey], + memKeys[authoritytypes.MemStoreKey], + AuthorityGovAddress, + ) + + lightclientKeeperTmp := lightclientkeeper.NewKeeper( + cdc, + keys[lightclienttypes.StoreKey], + memKeys[lightclienttypes.MemStoreKey], + authorityKeeperTmp, + ) + + observerKeeperTmp := observerkeeper.NewKeeper( + cdc, + keys[observertypes.StoreKey], + memKeys[observertypes.MemStoreKey], sdkKeepers.StakingKeeper, sdkKeepers.SlashingKeeper, authorityKeeperTmp, lightclientKeeperTmp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - fungibleKeeperTmp := initFungibleKeeper( + + fungibleKeeperTmp := fungiblekeeper.NewKeeper( cdc, - db, - stateStore, + keys[types.StoreKey], + memKeys[types.MemStoreKey], sdkKeepers.AuthKeeper, - sdkKeepers.BankKeeper, sdkKeepers.EvmKeeper, + sdkKeepers.BankKeeper, observerKeeperTmp, authorityKeeperTmp, ) + zetaKeepers := ZetaKeepers{ ObserverKeeper: observerKeeperTmp, FungibleKeeper: fungibleKeeperTmp, @@ -129,9 +153,15 @@ func CrosschainKeeperWithMocks( var observerKeeper types.ObserverKeeper = observerKeeperTmp var fungibleKeeper types.FungibleKeeper = fungibleKeeperTmp - // Create the crosschain keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) + for _, key := range keys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + } + for _, key := range tkeys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeTransient, nil) + } + for _, key := range memKeys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeMemory, nil) + } // Initialize mocks for mocked keepers var authKeeper types.AccountKeeper = sdkKeepers.AuthKeeper @@ -163,8 +193,8 @@ func CrosschainKeeperWithMocks( // create crosschain keeper k := keeper.NewKeeper( cdc, - storeKey, - memStoreKey, + keys[types.StoreKey], + memKeys[types.MemStoreKey], stakingKeeper, authKeeper, bankKeeper, @@ -190,7 +220,7 @@ func CrosschainKeeperWithMocks( k.SetIBCCrosschainKeeper(ibcCrosschainKeeperTmp) // seal the IBC router - sdkKeepers.IBCKeeper.SetRouter(sdkKeepers.IBCRouter) + // sdkKeepers.IBCKeeper.SetRouter(sdkKeepers.IBCRouter) // load the latest version of the state store require.NoError(t, stateStore.LoadLatestVersion()) @@ -387,10 +417,6 @@ func MockVoteOnOutboundFailedBallot( Once() } -func MockGetOutbound(m *crosschainmocks.CrosschainObserverKeeper, ctx sdk.Context) { - m.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() -} - func MockSaveOutbound( m *crosschainmocks.CrosschainObserverKeeper, ctx sdk.Context, @@ -401,7 +427,6 @@ func MockSaveOutbound( m.On("RemoveFromPendingNonces", ctx, tss.TssPubkey, cctx.GetCurrentOutboundParam().ReceiverChainId, mock.Anything). Return().Times(expectedNumberOfOutboundParams) - m.On("GetTSS", ctx).Return(observertypes.TSS{}, true) } func MockSaveOutboundNewRevertCreated( diff --git a/testutil/keeper/emissions.go b/testutil/keeper/emissions.go index 594f46aca0..903b7457c2 100644 --- a/testutil/keeper/emissions.go +++ b/testutil/keeper/emissions.go @@ -4,7 +4,8 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" - "github.com/cosmos/cosmos-sdk/store" + "github.com/cometbft/cometbft/libs/log" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -37,23 +38,22 @@ func EmissionKeeperWithMockOptions( // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + stateStore := rootmulti.NewStore(db, log.NewNopLogger()) cdc := NewCodec() // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) - authorityKeeper := initAuthorityKeeper(cdc, db, stateStore) + authorityKeeper := initAuthorityKeeper(cdc, stateStore) // Create zeta keepers observerKeeperTmp := initObserverKeeper( cdc, - db, stateStore, sdkKeepers.StakingKeeper, sdkKeepers.SlashingKeeper, authorityKeeper, - initLightclientKeeper(cdc, db, stateStore, authorityKeeper), + initLightclientKeeper(cdc, stateStore, authorityKeeper), ) zetaKeepers := ZetaKeepers{ @@ -62,7 +62,7 @@ func EmissionKeeperWithMockOptions( var observerKeeper types.ObserverKeeper = observerKeeperTmp // Create the fungible keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) require.NoError(t, stateStore.LoadLatestVersion()) diff --git a/testutil/keeper/fungible.go b/testutil/keeper/fungible.go index 29ddc25790..a4e4dc406e 100644 --- a/testutil/keeper/fungible.go +++ b/testutil/keeper/fungible.go @@ -5,20 +5,30 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/evmos/ethermint/x/evm/statedb" - evmtypes "github.com/evmos/ethermint/x/evm/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/x/evm/statedb" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" fungiblemocks "github.com/zeta-chain/zetacore/testutil/keeper/mocks/fungible" "github.com/zeta-chain/zetacore/testutil/sample" + authoritykeeper "github.com/zeta-chain/zetacore/x/authority/keeper" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" fungiblemodule "github.com/zeta-chain/zetacore/x/fungible" "github.com/zeta-chain/zetacore/x/fungible/keeper" "github.com/zeta-chain/zetacore/x/fungible/types" + lightclientkeeper "github.com/zeta-chain/zetacore/x/lightclient/keeper" + lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) type FungibleMockOptions struct { @@ -42,7 +52,6 @@ var ( func initFungibleKeeper( cdc codec.Codec, - db *tmdb.MemDB, ss store.CommitMultiStore, authKeeper types.AccountKeeper, bankKeepr types.BankKeeper, @@ -52,8 +61,8 @@ func initFungibleKeeper( ) *keeper.Keeper { storeKey := sdk.NewKVStoreKey(types.StoreKey) memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, nil) return keeper.NewKeeper( cdc, @@ -72,42 +81,44 @@ func FungibleKeeperWithMocks( t testing.TB, mockOptions FungibleMockOptions, ) (*keeper.Keeper, sdk.Context, SDKKeepers, ZetaKeepers) { - storeKey := sdk.NewKVStoreKey(types.StoreKey) - memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + keys, memKeys, tkeys, allKeys := StoreKeys() // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + stateStore := rootmulti.NewStore(db, log.NewNopLogger()) cdc := NewCodec() // Create regular keepers - sdkKeepers := NewSDKKeepers(cdc, db, stateStore) + sdkKeepers := NewSDKKeepersWithKeys(cdc, keys, memKeys, tkeys, allKeys) // Create authority keeper - authorityKeeperTmp := initAuthorityKeeper( + authorityKeeperTmp := authoritykeeper.NewKeeper( cdc, - db, - stateStore, + keys[authoritytypes.StoreKey], + memKeys[authoritytypes.MemStoreKey], + AuthorityGovAddress, ) // Create lightclient keeper - lightclientKeeperTmp := initLightclientKeeper( + lightclientKeeperTmp := lightclientkeeper.NewKeeper( cdc, - db, - stateStore, + keys[lightclienttypes.StoreKey], + memKeys[lightclienttypes.MemStoreKey], authorityKeeperTmp, ) // Create observer keeper - observerKeeperTmp := initObserverKeeper( + observerKeeperTmp := observerkeeper.NewKeeper( cdc, - db, - stateStore, + keys[observertypes.StoreKey], + memKeys[observertypes.MemStoreKey], sdkKeepers.StakingKeeper, sdkKeepers.SlashingKeeper, authorityKeeperTmp, lightclientKeeperTmp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + zetaKeepers := ZetaKeepers{ ObserverKeeper: observerKeeperTmp, AuthorityKeeper: &authorityKeeperTmp, @@ -117,13 +128,20 @@ func FungibleKeeperWithMocks( var authorityKeeper types.AuthorityKeeper = authorityKeeperTmp // Create the fungible keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) - require.NoError(t, stateStore.LoadLatestVersion()) + for _, key := range keys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + } + for _, key := range tkeys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeTransient, nil) + } + for _, key := range memKeys { + stateStore.MountStoreWithDB(key, storetypes.StoreTypeMemory, nil) + } - ctx := NewContext(stateStore) + require.NoError(t, stateStore.LoadLatestVersion()) // Initialize modules genesis + ctx := NewContext(stateStore) sdkKeepers.InitGenesis(ctx) zetaKeepers.InitGenesis(ctx) @@ -153,8 +171,8 @@ func FungibleKeeperWithMocks( k := keeper.NewKeeper( cdc, - storeKey, - memStoreKey, + keys[types.StoreKey], + memKeys[types.MemStoreKey], authKeeper, evmKeeper, bankKeeper, diff --git a/testutil/keeper/ibccrosschain.go b/testutil/keeper/ibccrosschain.go index a13ca4fe00..d90e485002 100644 --- a/testutil/keeper/ibccrosschain.go +++ b/testutil/keeper/ibccrosschain.go @@ -69,11 +69,10 @@ func IBCCrosschainKeeperWithMocks( sdkKeepers := NewSDKKeepers(cdc, db, stateStore) // Create zeta keepers - authorityKeeper := initAuthorityKeeper(cdc, db, stateStore) - lightclientKeeper := initLightclientKeeper(cdc, db, stateStore, authorityKeeper) + authorityKeeper := initAuthorityKeeper(cdc, stateStore) + lightclientKeeper := initLightclientKeeper(cdc, stateStore, authorityKeeper) observerKeeper := initObserverKeeper( cdc, - db, stateStore, sdkKeepers.StakingKeeper, sdkKeepers.SlashingKeeper, @@ -82,7 +81,6 @@ func IBCCrosschainKeeperWithMocks( ) fungibleKeeper := initFungibleKeeper( cdc, - db, stateStore, sdkKeepers.AuthKeeper, sdkKeepers.BankKeeper, diff --git a/testutil/keeper/keeper.go b/testutil/keeper/keeper.go index 8b3a9d0dfb..c33e0686f5 100644 --- a/testutil/keeper/keeper.go +++ b/testutil/keeper/keeper.go @@ -39,14 +39,13 @@ import ( porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - ethermint "github.com/evmos/ethermint/types" - evmmodule "github.com/evmos/ethermint/x/evm" - evmkeeper "github.com/evmos/ethermint/x/evm/keeper" - evmtypes "github.com/evmos/ethermint/x/evm/types" - "github.com/evmos/ethermint/x/evm/vm/geth" - feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/stretchr/testify/require" + ethermint "github.com/zeta-chain/ethermint/types" + evmmodule "github.com/zeta-chain/ethermint/x/evm" + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + feemarketkeeper "github.com/zeta-chain/ethermint/x/feemarket/keeper" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "github.com/zeta-chain/zetacore/testutil/sample" authoritymodule "github.com/zeta-chain/zetacore/x/authority" @@ -73,7 +72,7 @@ import ( ) // NewContext creates a new sdk.Context for testing purposes with initialized header -func NewContext(stateStore sdk.CommitMultiStore) sdk.Context { +func NewContext(stateStore sdk.MultiStore) sdk.Context { header := tmproto.Header{ Height: 1, ChainID: "test_7000-1", @@ -142,6 +141,17 @@ var moduleAccountPerms = map[string][]string{ ibccrosschaintypes.ModuleName: nil, } +var ( + testStoreKeys = sdk.NewKVStoreKeys( + authtypes.StoreKey, + banktypes.StoreKey, + evmtypes.StoreKey, + consensustypes.StoreKey, + ) + testTransientKeys = sdk.NewTransientStoreKeys(evmtypes.TransientKey) + testMemKeys = sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) +) + // ModuleAccountAddrs returns all the app's module account addresses. func ModuleAccountAddrs(maccPerms map[string][]string) map[string]bool { modAccAddrs := make(map[string]bool) @@ -353,6 +363,17 @@ func EVMKeeper( ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) ss.MountStoreWithDB(transientKey, storetypes.StoreTypeTransient, db) + allKeys := make(map[string]storetypes.StoreKey, len(testStoreKeys)+len(testTransientKeys)+len(testMemKeys)) + for k, v := range testStoreKeys { + allKeys[k] = v + } + for k, v := range testTransientKeys { + allKeys[k] = v + } + for k, v := range testMemKeys { + allKeys[k] = v + } + k := evmkeeper.NewKeeper( cdc, storeKey, @@ -362,16 +383,106 @@ func EVMKeeper( bankKeeper, stakingKeeper, feemarketKeeper, - nil, - geth.NewEVM, "", paramKeeper.Subspace(evmtypes.ModuleName), + nil, consensusKeeper, + allKeys, ) return k } +// NewSDKKeepers instantiates regular Cosmos SDK keeper such as staking with local storage for testing purposes +func NewSDKKeepersWithKeys( + cdc codec.Codec, + keys map[string]*storetypes.KVStoreKey, + memKeys map[string]*storetypes.MemoryStoreKey, + tKeys map[string]*storetypes.TransientStoreKey, + allKeys map[string]storetypes.StoreKey, +) SDKKeepers { + paramsKeeper := paramskeeper.NewKeeper( + cdc, + fungibletypes.Amino, + keys[paramstypes.StoreKey], + tKeys[paramstypes.TStoreKey], + ) + authKeeper := authkeeper.NewAccountKeeper( + cdc, + keys[authtypes.StoreKey], + ethermint.ProtoAccount, + moduleAccountPerms, + "zeta", + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + blockedAddrs := make(map[string]bool) + bankKeeper := bankkeeper.NewBaseKeeper( + cdc, + keys[banktypes.StoreKey], + authKeeper, + blockedAddrs, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + stakingKeeper := *stakingkeeper.NewKeeper( + cdc, + keys[stakingtypes.StoreKey], + authKeeper, + bankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + consensusKeeper := consensuskeeper.NewKeeper( + cdc, + keys[consensustypes.StoreKey], + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + feeMarketKeeper := feemarketkeeper.NewKeeper( + cdc, + authtypes.NewModuleAddress(govtypes.ModuleName), + keys[feemarkettypes.StoreKey], + tKeys[feemarkettypes.TransientKey], + paramsKeeper.Subspace(feemarkettypes.ModuleName), + consensusKeeper, + ) + evmKeeper := evmkeeper.NewKeeper( + cdc, + keys[evmtypes.StoreKey], + tKeys[evmtypes.TransientKey], + authtypes.NewModuleAddress(govtypes.ModuleName), + authKeeper, + bankKeeper, + stakingKeeper, + feeMarketKeeper, + "", + paramsKeeper.Subspace(evmtypes.ModuleName), + []evmkeeper.CustomContractFn{}, + consensusKeeper, + allKeys, + ) + slashingKeeper := slashingkeeper.NewKeeper( + cdc, + codec.NewLegacyAmino(), + keys[slashingtypes.StoreKey], + stakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + capabilityKeeper := capabilitykeeper.NewKeeper( + cdc, + keys[capabilitytypes.StoreKey], + memKeys[capabilitytypes.MemStoreKey], + ) + + return SDKKeepers{ + ParamsKeeper: paramsKeeper, + AuthKeeper: authKeeper, + BankKeeper: bankKeeper, + StakingKeeper: stakingKeeper, + FeeMarketKeeper: feeMarketKeeper, + EvmKeeper: evmKeeper, + SlashingKeeper: slashingKeeper, + CapabilityKeeper: capabilityKeeper, + } +} + // CapabilityKeeper instantiates a capability keeper for testing purposes func CapabilityKeeper( cdc codec.Codec, @@ -442,8 +553,7 @@ func TransferKeeper( ) // create IBC module from bottom to top of stack - var transferStack porttypes.IBCModule - transferStack = transfer.NewIBCModule(transferKeeper) + transferStack := transfer.NewIBCModule(transferKeeper) // Add transfer stack to IBC Router ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) @@ -510,11 +620,9 @@ func NewSDKKeepers( // InitGenesis initializes the test modules genesis state func (sdkk SDKKeepers) InitGenesis(ctx sdk.Context) { capabilitymodule.InitGenesis(ctx, *sdkk.CapabilityKeeper, *capabilitytypes.DefaultGenesis()) - sdkk.AuthKeeper.InitGenesis(ctx, *authtypes.DefaultGenesisState()) sdkk.BankKeeper.InitGenesis(ctx, banktypes.DefaultGenesisState()) sdkk.StakingKeeper.InitGenesis(ctx, stakingtypes.DefaultGenesisState()) - evmGenesis := *evmtypes.DefaultGenesisState() evmGenesis.Params.EvmDenom = "azeta" evmmodule.InitGenesis(ctx, sdkk.EvmKeeper, sdkk.AuthKeeper, evmGenesis) diff --git a/testutil/keeper/lightclient.go b/testutil/keeper/lightclient.go index c9d907ec3d..62aa09288e 100644 --- a/testutil/keeper/lightclient.go +++ b/testutil/keeper/lightclient.go @@ -4,8 +4,10 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -29,14 +31,13 @@ var ( func initLightclientKeeper( cdc codec.Codec, - db *tmdb.MemDB, ss store.CommitMultiStore, authorityKeeper types.AuthorityKeeper, ) keeper.Keeper { storeKey := sdk.NewKVStoreKey(types.StoreKey) memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, nil) return keeper.NewKeeper(cdc, storeKey, memKey, authorityKeeper) } @@ -51,16 +52,16 @@ func LightclientKeeperWithMocks( // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + stateStore := rootmulti.NewStore(db, log.NewNopLogger()) cdc := NewCodec() - authorityKeeperTmp := initAuthorityKeeper(cdc, db, stateStore) + authorityKeeperTmp := initAuthorityKeeper(cdc, stateStore) // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) // Create the observer keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) require.NoError(t, stateStore.LoadLatestVersion()) diff --git a/testutil/keeper/mocks/crosschain/fungible.go b/testutil/keeper/mocks/crosschain/fungible.go index ac48687449..f7445a0785 100644 --- a/testutil/keeper/mocks/crosschain/fungible.go +++ b/testutil/keeper/mocks/crosschain/fungible.go @@ -10,7 +10,7 @@ import ( crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" diff --git a/testutil/keeper/mocks/fungible/evm.go b/testutil/keeper/mocks/fungible/evm.go index 28fd46e25c..79b2cc1985 100644 --- a/testutil/keeper/mocks/fungible/evm.go +++ b/testutil/keeper/mocks/fungible/evm.go @@ -10,11 +10,11 @@ import ( core "github.com/ethereum/go-ethereum/core" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" mock "github.com/stretchr/testify/mock" - statedb "github.com/evmos/ethermint/x/evm/statedb" + statedb "github.com/zeta-chain/ethermint/x/evm/statedb" types "github.com/cosmos/cosmos-sdk/types" diff --git a/testutil/keeper/observer.go b/testutil/keeper/observer.go index f482fed0bc..c45d988045 100644 --- a/testutil/keeper/observer.go +++ b/testutil/keeper/observer.go @@ -4,8 +4,10 @@ import ( "testing" tmdb "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -41,7 +43,6 @@ var ( func initObserverKeeper( cdc codec.Codec, - db *tmdb.MemDB, ss store.CommitMultiStore, stakingKeeper stakingkeeper.Keeper, slashingKeeper slashingkeeper.Keeper, @@ -50,8 +51,8 @@ func initObserverKeeper( ) *keeper.Keeper { storeKey := sdk.NewKVStoreKey(types.StoreKey) memKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) - ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, db) + ss.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) + ss.MountStoreWithDB(memKey, storetypes.StoreTypeMemory, nil) return keeper.NewKeeper( cdc, @@ -75,17 +76,17 @@ func ObserverKeeperWithMocks( // Initialize local store db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + stateStore := rootmulti.NewStore(db, log.NewNopLogger()) cdc := NewCodec() - authorityKeeperTmp := initAuthorityKeeper(cdc, db, stateStore) - lightclientKeeperTmp := initLightclientKeeper(cdc, db, stateStore, authorityKeeperTmp) + authorityKeeperTmp := initAuthorityKeeper(cdc, stateStore) + lightclientKeeperTmp := initLightclientKeeper(cdc, stateStore, authorityKeeperTmp) // Create regular keepers sdkKeepers := NewSDKKeepers(cdc, db, stateStore) // Create the observer keeper - stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) require.NoError(t, stateStore.LoadLatestVersion()) diff --git a/testutil/network/genesis_state.go b/testutil/network/genesis_state.go index e391526328..73220ba9a5 100644 --- a/testutil/network/genesis_state.go +++ b/testutil/network/genesis_state.go @@ -9,8 +9,8 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" cmdcfg "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/pkg/chains" diff --git a/testutil/network/network_setup.go b/testutil/network/network_setup.go index 7fe4855de9..0a942aa83b 100644 --- a/testutil/network/network_setup.go +++ b/testutil/network/network_setup.go @@ -553,7 +553,7 @@ func (n *Network) LatestHeight() (int64, error) { for { select { case <-timeout.C: - return latestHeight, errors.New("timeout exceeded waiting for block") + return latestHeight, errors.New("LatestHeight: timeout exceeded waiting for block") case <-ticker.C: res, err := queryClient.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{}) if err == nil && res != nil { @@ -590,7 +590,7 @@ func (n *Network) WaitForHeightWithTimeout(h int64, t time.Duration) (int64, err for { select { case <-timeout.C: - return latestHeight, errors.New("timeout exceeded waiting for block") + return latestHeight, errors.New("WaitForHeightWithTimeout: timeout exceeded waiting for block") case <-ticker.C: res, err := queryClient.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{}) diff --git a/x/crosschain/genesis.go b/x/crosschain/genesis.go index 6a1fe1ed58..7d750bafa1 100644 --- a/x/crosschain/genesis.go +++ b/x/crosschain/genesis.go @@ -43,9 +43,12 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) } // Set all the cross-chain txs - for _, elem := range genState.CrossChainTxs { - if elem != nil { - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, *elem) + tss, found := k.GetObserverKeeper().GetTSS(ctx) + if found { + for _, elem := range genState.CrossChainTxs { + if elem != nil { + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, *elem, tss.TssPubkey) + } } } for _, elem := range genState.FinalizedInbounds { diff --git a/x/crosschain/keeper/cctx.go b/x/crosschain/keeper/cctx.go index f9cf7ee570..9a1e1781df 100644 --- a/x/crosschain/keeper/cctx.go +++ b/x/crosschain/keeper/cctx.go @@ -16,11 +16,11 @@ import ( // 2. set the mapping inboundHash -> cctxIndex , one inboundHash can be connected to multiple cctxindex // 3. set the mapping nonce => cctx // 4. update the zeta accounting -func (k Keeper) SetCctxAndNonceToCctxAndInboundHashToCctx(ctx sdk.Context, cctx types.CrossChainTx) { - tss, found := k.zetaObserverKeeper.GetTSS(ctx) - if !found { - return - } +func (k Keeper) SetCctxAndNonceToCctxAndInboundHashToCctx( + ctx sdk.Context, + cctx types.CrossChainTx, + tssPubkey string, +) { // set mapping nonce => cctxIndex if cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound || cctx.CctxStatus.Status == types.CctxStatus_PendingRevert { @@ -29,7 +29,7 @@ func (k Keeper) SetCctxAndNonceToCctxAndInboundHashToCctx(ctx sdk.Context, cctx // #nosec G115 always in range Nonce: int64(cctx.GetCurrentOutboundParam().TssNonce), CctxIndex: cctx.Index, - Tss: tss.TssPubkey, + Tss: tssPubkey, }) } @@ -37,7 +37,7 @@ func (k Keeper) SetCctxAndNonceToCctxAndInboundHashToCctx(ctx sdk.Context, cctx // set mapping inboundHash -> cctxIndex in, _ := k.GetInboundHashToCctx(ctx, cctx.InboundParams.ObservedHash) in.InboundHash = cctx.InboundParams.ObservedHash - found = false + found := false for _, cctxIndex := range in.CctxIndex { if cctxIndex == cctx.Index { found = true diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 4cda69a5c3..f2f10e23b6 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -51,7 +51,7 @@ func (k Keeper) ValidateInbound( if ok { cctx.InboundParams.ObservedHash = inCctxIndex } - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx, tss.TssPubkey) return &cctx, nil } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index bbd4530484..fd798998c0 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -214,80 +214,6 @@ func TestKeeper_ValidateInbound(t *testing.T) { require.ErrorIs(t, err, types.ErrCannotFindReceiverNonce) }) - t.Run("does not set cctx if SetCctxAndNonceToCctxAndInboundHashToCctx fails", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, - keepertest.CrosschainMockOptions{ - UseObserverMock: true, - UseFungibleMock: true, - UseAuthorityMock: true, - }) - - // Setup mock data - observerMock := keepertest.GetCrosschainObserverMock(t, k) - authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) - receiver := sample.EthAddress() - creator := sample.AccAddress() - amount := sdkmath.NewUint(42) - message := "test" - inboundBlockHeight := uint64(420) - inboundHash := sample.Hash() - gasLimit := uint64(100) - asset := "test-asset" - eventIndex := uint64(1) - cointType := coin.CoinType_ERC20 - tss := sample.Tss() - receiverChain := chains.Goerli - senderChain := chains.Goerli - sender := sample.EthAddress() - tssList := sample.TssList(3) - - // Set up mocks for CheckIfTSSMigrationTransfer - observerMock.On("GetAllTSS", ctx).Return(tssList) - observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) - authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) - // setup Mocks for GetTSS - observerMock.On("GetTSS", mock.Anything).Return(tss, true).Twice() - // setup Mocks for IsInboundEnabled - observerMock.On("IsInboundEnabled", ctx).Return(true) - // setup mocks for Initiate Outbound - observerMock.On("GetChainNonces", mock.Anything, mock.Anything). - Return(observerTypes.ChainNonces{Nonce: 1}, true) - observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything). - Return(observerTypes.PendingNonces{NonceHigh: 1}, true) - observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Return(nil) - observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Return(nil) - // setup Mocks for SetCctxAndNonceToCctxAndInboundHashToCctx - observerMock.On("GetTSS", mock.Anything).Return(tss, false).Once() - - k.SetGasPrice(ctx, types.GasPrice{ - ChainId: senderChain.ChainId, - MedianIndex: 0, - Prices: []uint64{100}, - }) - - // call InitiateOutbound - msg := types.MsgVoteInbound{ - Creator: creator, - Sender: sender.String(), - SenderChainId: senderChain.ChainId, - Receiver: receiver.String(), - ReceiverChain: receiverChain.ChainId, - Amount: amount, - Message: message, - InboundHash: inboundHash.String(), - InboundBlockHeight: inboundBlockHeight, - GasLimit: gasLimit, - CoinType: cointType, - TxOrigin: sender.String(), - Asset: asset, - EventIndex: eventIndex, - } - - _, err := k.ValidateInbound(ctx, &msg, false) - require.NoError(t, err) - require.Len(t, k.GetAllCrossChainTx(ctx), 0) - }) - t.Run("fail if inbound is disabled", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go index f39f0d3af8..1fca5bcc51 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound_test.go @@ -7,9 +7,9 @@ import ( "cosmossdk.io/errors" ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/evmos/ethermint/x/evm/statedb" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/x/evm/statedb" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/crosschain/keeper/cctx_test.go b/x/crosschain/keeper/cctx_test.go index c523814c69..0c99f979c9 100644 --- a/x/crosschain/keeper/cctx_test.go +++ b/x/crosschain/keeper/cctx_test.go @@ -24,6 +24,7 @@ func createNCctxWithStatus( ctx sdk.Context, n int, status types.CctxStatus, + tssPubkey string, ) []types.CrossChainTx { items := make([]types.CrossChainTx, n) for i := range items { @@ -39,13 +40,13 @@ func createNCctxWithStatus( items[i].OutboundParams = []*types.OutboundParams{{Amount: math.ZeroUint()}} items[i].RevertOptions = types.NewEmptyRevertOptions() - keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, items[i]) + keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, items[i], tssPubkey) } return items } // Keeper Tests -func createNCctx(keeper *keeper.Keeper, ctx sdk.Context, n int) []types.CrossChainTx { +func createNCctx(keeper *keeper.Keeper, ctx sdk.Context, n int, tssPubkey string) []types.CrossChainTx { items := make([]types.CrossChainTx, n) for i := range items { items[i].Creator = "any" @@ -79,10 +80,9 @@ func createNCctx(keeper *keeper.Keeper, ctx sdk.Context, n int) []types.CrossCha items[i].ZetaFees = math.OneUint() items[i].Index = fmt.Sprintf("%d", i) - items[i].RevertOptions = types.NewEmptyRevertOptions() - keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, items[i]) + keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, items[i], tssPubkey) } return items } @@ -125,24 +125,39 @@ func TestCCTXs(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) keeper.SetZetaAccounting(ctx, types.ZetaAccounting{AbortedZetaAmount: math.ZeroUint()}) var sends []types.CrossChainTx - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + sends = append( + sends, + createNCctxWithStatus( + keeper, + ctx, + tt.PendingInbound, + types.CctxStatus_PendingInbound, + tss.TssPubkey, + )...) + sends = append( + sends, + createNCctxWithStatus( + keeper, + ctx, + tt.PendingOutbound, + types.CctxStatus_PendingOutbound, + tss.TssPubkey, + )...) sends = append( sends, - createNCctxWithStatus(keeper, ctx, tt.PendingInbound, types.CctxStatus_PendingInbound)...) + createNCctxWithStatus(keeper, ctx, tt.PendingRevert, types.CctxStatus_PendingRevert, tss.TssPubkey)...) sends = append( sends, - createNCctxWithStatus(keeper, ctx, tt.PendingOutbound, types.CctxStatus_PendingOutbound)...) + createNCctxWithStatus(keeper, ctx, tt.Aborted, types.CctxStatus_Aborted, tss.TssPubkey)...) sends = append( sends, - createNCctxWithStatus(keeper, ctx, tt.PendingRevert, types.CctxStatus_PendingRevert)...) - sends = append(sends, createNCctxWithStatus(keeper, ctx, tt.Aborted, types.CctxStatus_Aborted)...) + createNCctxWithStatus(keeper, ctx, tt.OutboundMined, types.CctxStatus_OutboundMined, tss.TssPubkey)...) sends = append( sends, - createNCctxWithStatus(keeper, ctx, tt.OutboundMined, types.CctxStatus_OutboundMined)...) - sends = append(sends, createNCctxWithStatus(keeper, ctx, tt.Reverted, types.CctxStatus_Reverted)...) - //require.Equal(t, tt.PendingOutbound, len(keeper.GetAllCctxByStatuses(ctx, []types.CctxStatus{types.CctxStatus_PendingOutbound}))) - //require.Equal(t, tt.PendingInbound, len(keeper.GetAllCctxByStatuses(ctx, []types.CctxStatus{types.CctxStatus_PendingInbound}))) - //require.Equal(t, tt.PendingOutbound+tt.PendingRevert, len(keeper.GetAllCctxByStatuses(ctx, []types.CctxStatus{types.CctxStatus_PendingOutbound, types.CctxStatus_PendingRevert}))) + createNCctxWithStatus(keeper, ctx, tt.Reverted, types.CctxStatus_Reverted, tss.TssPubkey)...) + require.Equal(t, len(sends), len(keeper.GetAllCrossChainTx(ctx))) for _, s := range sends { send, found := keeper.GetCrossChainTx(ctx, s.Index) @@ -156,8 +171,9 @@ func TestCCTXs(t *testing.T) { func TestCCTXGetAll(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) - items := createNCctx(keeper, ctx, 10) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + items := createNCctx(keeper, ctx, 10, tss.TssPubkey) cctx := keeper.GetAllCrossChainTx(ctx) c := make([]types.CrossChainTx, len(cctx)) for i, val := range cctx { @@ -170,9 +186,10 @@ func TestCCTXGetAll(t *testing.T) { func TestCCTXQuerySingle(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) wctx := sdk.WrapSDKContext(ctx) - msgs := createNCctx(keeper, ctx, 2) + msgs := createNCctx(keeper, ctx, 2, tss.TssPubkey) for _, tc := range []struct { desc string request *types.QueryGetCctxRequest @@ -213,9 +230,10 @@ func TestCCTXQuerySingle(t *testing.T) { func TestCCTXQueryPaginated(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) + tss := sample.Tss() zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) wctx := sdk.WrapSDKContext(ctx) - msgs := createNCctx(keeper, ctx, 5) + msgs := createNCctx(keeper, ctx, 5, tss.TssPubkey) request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllCctxRequest { return &types.QueryAllCctxRequest{ @@ -262,8 +280,9 @@ func TestCCTXQueryPaginated(t *testing.T) { func TestKeeper_RemoveCrossChainTx(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) - txs := createNCctx(keeper, ctx, 5) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) + txs := createNCctx(keeper, ctx, 5, tss.TssPubkey) keeper.RemoveCrossChainTx(ctx, txs[0].Index) txs = keeper.GetAllCrossChainTx(ctx) diff --git a/x/crosschain/keeper/evm_deposit.go b/x/crosschain/keeper/evm_deposit.go index a85b98ed86..2b46cedcb6 100644 --- a/x/crosschain/keeper/evm_deposit.go +++ b/x/crosschain/keeper/evm_deposit.go @@ -9,8 +9,8 @@ import ( tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/crosschain/keeper/evm_deposit_test.go b/x/crosschain/keeper/evm_deposit_test.go index 45e8a5547e..18bc103bc3 100644 --- a/x/crosschain/keeper/evm_deposit_test.go +++ b/x/crosschain/keeper/evm_deposit_test.go @@ -8,9 +8,9 @@ import ( "cosmossdk.io/math" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/pkg/coin" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index e19d664310..03333e4f1e 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -13,8 +13,8 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" connectorzevm "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/zetaconnectorzevm.sol" "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" diff --git a/x/crosschain/keeper/grpc_query_inbound_hash_to_cctx_test.go b/x/crosschain/keeper/grpc_query_inbound_hash_to_cctx_test.go index c99bd9d9fc..da91836fe4 100644 --- a/x/crosschain/keeper/grpc_query_inbound_hash_to_cctx_test.go +++ b/x/crosschain/keeper/grpc_query_inbound_hash_to_cctx_test.go @@ -126,7 +126,11 @@ func TestInTxHashToCctxQueryPaginated(t *testing.T) { }) } -func createInTxHashToCctxWithCctxs(keeper *crosschainkeeper.Keeper, ctx sdk.Context) ([]types.CrossChainTx, +func createInTxHashToCctxWithCctxs( + ctx sdk.Context, + keeper *crosschainkeeper.Keeper, + tssPubkey string, +) ([]types.CrossChainTx, types.InboundHashToCctx) { cctxs := make([]types.CrossChainTx, 5) for i := range cctxs { @@ -136,7 +140,7 @@ func createInTxHashToCctxWithCctxs(keeper *crosschainkeeper.Keeper, ctx sdk.Cont cctxs[i].InboundParams = &types.InboundParams{ObservedHash: fmt.Sprintf("%d", i), Amount: math.OneUint()} cctxs[i].CctxStatus = &types.Status{Status: types.CctxStatus_PendingInbound} cctxs[i].RevertOptions = types.NewEmptyRevertOptions() - keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctxs[i]) + keeper.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctxs[i], tssPubkey) } var inboundHashToCctx types.InboundHashToCctx @@ -152,9 +156,10 @@ func createInTxHashToCctxWithCctxs(keeper *crosschainkeeper.Keeper, ctx sdk.Cont func TestKeeper_InTxHashToCctxDataQuery(t *testing.T) { keeper, ctx, _, zk := keepertest.CrosschainKeeper(t) wctx := sdk.WrapSDKContext(ctx) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) + tss := sample.Tss() + zk.ObserverKeeper.SetTSS(ctx, tss) t.Run("can query all cctxs data with in tx hash", func(t *testing.T) { - cctxs, inboundHashToCctx := createInTxHashToCctxWithCctxs(keeper, ctx) + cctxs, inboundHashToCctx := createInTxHashToCctxWithCctxs(ctx, keeper, tss.TssPubkey) req := &types.QueryInboundHashToCctxDataRequest{ InboundHash: inboundHashToCctx.InboundHash, } diff --git a/x/crosschain/keeper/msg_server_migrate_erc20_custody_funds.go b/x/crosschain/keeper/msg_server_migrate_erc20_custody_funds.go index 56bc0a5ea1..da1cd23618 100644 --- a/x/crosschain/keeper/msg_server_migrate_erc20_custody_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_erc20_custody_funds.go @@ -83,7 +83,7 @@ func (k msgServer) MigrateERC20CustodyFunds( if err != nil { return nil, err } - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx, tss.TssPubkey) err = ctx.EventManager().EmitTypedEvent( &types.EventERC20CustodyFundsMigration{ diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 7d48b48cdb..7921686ab5 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -106,6 +106,12 @@ func (k Keeper) initiateMigrateTSSFundsCCTX( return err } + // Set the CCTX and the nonce for the outbound migration + err = k.SetObserverOutboundInfo(ctx, chainID, &cctx) + if err != nil { + return errorsmod.Wrap(types.ErrUnableToSetOutboundInfo, err.Error()) + } + // The migrate funds can be run again to update the migration cctx index if the migration fails // This should be used after carefully calculating the amount again existingMigrationInfo, found := k.zetaObserverKeeper.GetFundMigrator(ctx, chainID) @@ -128,7 +134,7 @@ func (k Keeper) initiateMigrateTSSFundsCCTX( } } - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx, currentTss.TssPubkey) k.zetaObserverKeeper.SetFundMigrator(ctx, observertypes.TssFundMigratorInfo{ ChainId: chainID, MigrationCctxIndex: cctx.Index, 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 a715fcf4e6..93e9a8fb98 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -26,6 +26,7 @@ func setupTssMigrationParams( amount sdkmath.Uint, setNewTss bool, setCurrentTSS bool, + setChainNonces bool, ) (string, string) { zk.ObserverKeeper.SetCrosschainFlags(ctx, observertypes.CrosschainFlags{ IsInboundEnabled: false, @@ -70,10 +71,12 @@ func setupTssMigrationParams( PriorityFees: []uint64{100, 300, 200}, MedianIndex: 1, }) - k.GetObserverKeeper().SetChainNonces(ctx, observertypes.ChainNonces{ - ChainId: chain.ChainId, - Nonce: 1, - }) + if setChainNonces { + k.GetObserverKeeper().SetChainNonces(ctx, observertypes.ChainNonces{ + ChainId: chain.ChainId, + Nonce: 1, + }) + } indexString := crosschaintypes.GetTssMigrationCCTXIndexString( currentTss.TssPubkey, newTss.TssPubkey, @@ -98,7 +101,7 @@ func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) gp, priorityFee, found := k.GetMedianGasValues(ctx, chain.ChainId) require.True(t, found) msg := crosschaintypes.MsgMigrateTssFunds{ @@ -134,7 +137,7 @@ func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) gp, priorityFee, found := k.GetMedianGasValues(ctx, chain.ChainId) require.True(t, found) @@ -373,7 +376,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -405,7 +408,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -433,7 +436,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -460,7 +463,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, NonceHigh: 10, @@ -483,7 +486,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { require.False(t, found) }) - t.Run("unable to migrate funds when a pending cctx is presnt in migration info", func(t *testing.T) { + t.Run("unable to migrate funds when a pending cctx is present in migration info", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) @@ -494,7 +497,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, NonceHigh: 1, @@ -541,7 +544,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, false) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, false, true) currentTss, found := k.GetObserverKeeper().GetTSS(ctx) require.True(t, found) newTss := sample.Tss() @@ -565,4 +568,29 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { require.False(t, found) }, ) + + t.Run("unable to process migration if SetObserverOutboundInfo fails", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + chain := getValidEthChain() + amount := sdkmath.NewUintFromString("10000000000000000000") + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, _ = setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, false) + msg := crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + } + keepertest.MockCheckAuthorization(&authorityMock.Mock, &msg, nil) + keepertest.MockGetChainListEmpty(&authorityMock.Mock) + + _, err := msgServer.MigrateTssFunds(ctx, &msg) + require.ErrorContains(t, err, crosschaintypes.ErrUnableToSetOutboundInfo.Error()) + }) } diff --git a/x/crosschain/keeper/msg_server_update_erc20_custody_pause_status.go b/x/crosschain/keeper/msg_server_update_erc20_custody_pause_status.go index 4cda11f633..98e73566ed 100644 --- a/x/crosschain/keeper/msg_server_update_erc20_custody_pause_status.go +++ b/x/crosschain/keeper/msg_server_update_erc20_custody_pause_status.go @@ -81,7 +81,7 @@ func (k msgServer) UpdateERC20CustodyPauseStatus( if err != nil { return nil, err } - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx, tss.TssPubkey) err = ctx.EventManager().EmitTypedEvent( &types.EventERC20CustodyPausing{ 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 be03a407e5..98eb488d41 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go @@ -11,9 +11,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/evmos/ethermint/x/evm/statedb" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/x/evm/statedb" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 3da780ccc1..d4505dd2f3 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -63,6 +63,16 @@ func (k msgServer) VoteOutbound( ) (*types.MsgVoteOutboundResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + // Check if TSS exists + // It is almost impossible to reach this point without a TSS, + // as the check for TSS was already done when creating the inbound, but we check anyway. + // We also expect the tss.Pubkey to be the same as the one in the outbound params, + // As we would have processed all CCTXs before migrating + tss, found := k.zetaObserverKeeper.GetTSS(ctx) + if !found { + return nil, cosmoserrors.Wrap(types.ErrCannotFindTSSKeys, voteOutboundID) + } + // Validate the message params to verify it against an existing CCTX. cctx, err := k.ValidateOutboundMessage(ctx, *msg) if err != nil { @@ -92,6 +102,7 @@ func (k msgServer) VoteOutbound( // Set the finalized ballot to the current outbound params. cctx.SetOutboundBallotIndex(ballotIndex) + // If ballot is successful, the value received should be the out tx amount. err = cctx.AddOutbound(ctx, *msg, ballot.BallotStatus) if err != nil { @@ -101,13 +112,13 @@ func (k msgServer) VoteOutbound( // Fund the gas stability pool with the remaining funds. k.FundStabilityPool(ctx, &cctx) + // We use the current TSS pubkey to finalize the outbound. err = k.ValidateOutboundObservers(ctx, &cctx, ballot.BallotStatus, msg.ValueReceived.String()) if err != nil { - k.SaveFailedOutbound(ctx, &cctx, err.Error()) + k.SaveFailedOutbound(ctx, &cctx, err.Error(), tss.TssPubkey) return &types.MsgVoteOutboundResponse{}, nil } - - k.SaveSuccessfulOutbound(ctx, &cctx) + k.SaveSuccessfulOutbound(ctx, &cctx, tss.TssPubkey) return &types.MsgVoteOutboundResponse{}, nil } @@ -173,17 +184,17 @@ SaveFailedOutbound saves a failed outbound transaction.It does the following thi 2. Save the outbound */ -func (k Keeper) SaveFailedOutbound(ctx sdk.Context, cctx *types.CrossChainTx, errMessage string) { +func (k Keeper) SaveFailedOutbound(ctx sdk.Context, cctx *types.CrossChainTx, errMessage string, tssPubkey string) { cctx.SetAbort(errMessage) ctx.Logger().Error(errMessage) - k.SaveOutbound(ctx, cctx) + k.SaveOutbound(ctx, cctx, tssPubkey) } // SaveSuccessfulOutbound saves a successful outbound transaction. // This function does not set the CCTX status, therefore all successful outbound transactions need // to have their status set during processing -func (k Keeper) SaveSuccessfulOutbound(ctx sdk.Context, cctx *types.CrossChainTx) { - k.SaveOutbound(ctx, cctx) +func (k Keeper) SaveSuccessfulOutbound(ctx sdk.Context, cctx *types.CrossChainTx, tssPubkey string) { + k.SaveOutbound(ctx, cctx, tssPubkey) } /* @@ -197,16 +208,15 @@ SaveOutbound saves the outbound transaction.It does the following things in one 4. Set the cctx and nonce to cctx and inboundHash to cctx */ -func (k Keeper) SaveOutbound(ctx sdk.Context, cctx *types.CrossChainTx) { +func (k Keeper) SaveOutbound(ctx sdk.Context, cctx *types.CrossChainTx, tssPubkey string) { // #nosec G115 always in range for _, outboundParams := range cctx.OutboundParams { k.GetObserverKeeper(). RemoveFromPendingNonces(ctx, outboundParams.TssPubkey, outboundParams.ReceiverChainId, int64(outboundParams.TssNonce)) k.RemoveOutboundTrackerFromStore(ctx, outboundParams.ReceiverChainId, outboundParams.TssNonce) } - // This should set nonce to cctx only if a new revert is created. - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, *cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, *cctx, tssPubkey) } func (k Keeper) ValidateOutboundMessage(ctx sdk.Context, msg types.MsgVoteOutbound) (types.CrossChainTx, error) { @@ -228,12 +238,6 @@ func (k Keeper) ValidateOutboundMessage(ctx sdk.Context, msg types.MsgVoteOutbou ) } - // Do not process an outbound vote if TSS is not found. - _, found = k.zetaObserverKeeper.GetTSS(ctx) - if !found { - return types.CrossChainTx{}, cosmoserrors.Wrap(types.ErrCannotFindTSSKeys, voteOutboundID) - } - if cctx.GetCurrentOutboundParam().ReceiverChainId != msg.OutboundChain { return types.CrossChainTx{}, cosmoserrors.Wrapf( sdkerrors.ErrInvalidRequest, 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 0ac0d817ba..13ecdc672e 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go @@ -146,9 +146,6 @@ func TestKeeper_VoteOutbound(t *testing.T) { // Successfully mock VoteOnOutboundBallot keepertest.MockVoteOnOutboundSuccessBallot(observerMock, ctx, cctx, senderChain, observer) - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - // Successfully mock SaveSuccessfulOutbound expectedNumberOfOutboundParams := 1 keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss, expectedNumberOfOutboundParams) @@ -176,6 +173,44 @@ func TestKeeper_VoteOutbound(t *testing.T) { require.Len(t, c.OutboundParams, expectedNumberOfOutboundParams) }) + t.Run("vote on outbound tx fails if tss is not found", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseObserverMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + receiver := sample.EthAddress() + amount := big.NewInt(42) + senderChain := getValidEthChain() + asset := "" + observer := sample.AccAddress() + tss := sample.Tss() + zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) + cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) + cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey + cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound + k.SetCrossChainTx(ctx, *cctx) + observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, false).Once() + + msgServer := keeper.NewMsgServerImpl(*k) + msg := types.MsgVoteOutbound{ + CctxHash: cctx.Index, + OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, + OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, + Status: chains.ReceiveStatus_success, + Creator: observer, + ObservedOutboundHash: sample.Hash().String(), + ValueReceived: cctx.GetCurrentOutboundParam().Amount, + ObservedOutboundBlockHeight: 10, + ObservedOutboundEffectiveGasPrice: math.NewInt(21), + ObservedOutboundGasUsed: 21, + CoinType: cctx.InboundParams.CoinType, + } + _, err := msgServer.VoteOutbound(ctx, &msg) + require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) + }) + t.Run("successfully vote on outbound tx, vote-type failed", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseObserverMock: true, @@ -201,9 +236,6 @@ func TestKeeper_VoteOutbound(t *testing.T) { // Successfully mock VoteOnOutboundBallot keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - // Successfully mock ProcessOutbound keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) @@ -264,9 +296,6 @@ func TestKeeper_VoteOutbound(t *testing.T) { // Successfully mock VoteOnOutboundBallot keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - // Mock Failed ProcessOutbound keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) @@ -334,9 +363,6 @@ func TestKeeper_VoteOutbound(t *testing.T) { // Successfully mock VoteOnOutboundBallot keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - // Fail ProcessOutbound so that changes are not committed to the state fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, mock.Anything, mock.Anything). Return(fungibletypes.ForeignCoins{}, false) @@ -472,6 +498,7 @@ func TestKeeper_VoteOutbound(t *testing.T) { func TestKeeper_SaveFailedOutbound(t *testing.T) { t.Run("successfully save failed outbound", func(t *testing.T) { + //ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") k.SetOutboundTracker(ctx, types.OutboundTracker{ @@ -481,7 +508,11 @@ func TestKeeper_SaveFailedOutbound(t *testing.T) { HashList: nil, }) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveFailedOutbound(ctx, cctx, sample.String()) + + //ACT + k.SaveFailedOutbound(ctx, cctx, sample.String(), sample.Tss().TssPubkey) + + //ASSERT require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) _, found := k.GetOutboundTracker( ctx, @@ -492,6 +523,7 @@ func TestKeeper_SaveFailedOutbound(t *testing.T) { }) t.Run("successfully save failed outbound with multiple trackers", func(t *testing.T) { + //ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") for _, outboundParams := range cctx.OutboundParams { @@ -503,9 +535,12 @@ func TestKeeper_SaveFailedOutbound(t *testing.T) { }) } cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveFailedOutbound(ctx, cctx, sample.String()) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) + //ACT + k.SaveFailedOutbound(ctx, cctx, sample.String(), sample.Tss().TssPubkey) + + //ASSERT + require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) for _, outboundParams := range cctx.OutboundParams { _, found := k.GetOutboundTracker( ctx, @@ -514,12 +549,12 @@ func TestKeeper_SaveFailedOutbound(t *testing.T) { ) require.False(t, found) } - }) } func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { t.Run("successfully save successful outbound", func(t *testing.T) { + //ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") k.SetOutboundTracker(ctx, types.OutboundTracker{ @@ -529,8 +564,11 @@ func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { HashList: nil, }) cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveSuccessfulOutbound(ctx, cctx) + //ACT + k.SaveSuccessfulOutbound(ctx, cctx, sample.Tss().TssPubkey) + + //ASSERT _, found := k.GetOutboundTracker( ctx, cctx.GetCurrentOutboundParam().ReceiverChainId, @@ -540,6 +578,7 @@ func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { }) t.Run("successfully save successful outbound with multiple trackers", func(t *testing.T) { + //ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") for _, outboundParams := range cctx.OutboundParams { @@ -551,8 +590,11 @@ func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { }) } cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveSuccessfulOutbound(ctx, cctx) + //ACT + k.SaveSuccessfulOutbound(ctx, cctx, sample.Tss().TssPubkey) + + //ASSERT for _, outboundParams := range cctx.OutboundParams { _, found := k.GetOutboundTracker( ctx, @@ -566,8 +608,8 @@ func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { func TestKeeper_SaveOutbound(t *testing.T) { t.Run("successfully save outbound", func(t *testing.T) { + //ARRANGE k, ctx, _, zk := keepertest.CrosschainKeeper(t) - // setup state for crosschain and observer modules cctx := sample.CrossChainTx(t, "test") cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound @@ -577,7 +619,6 @@ func TestKeeper_SaveOutbound(t *testing.T) { Nonce: cctx.GetCurrentOutboundParam().TssNonce, HashList: nil, }) - zk.ObserverKeeper.SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: int64(cctx.GetCurrentOutboundParam().TssNonce) - 1, NonceHigh: int64(cctx.GetCurrentOutboundParam().TssNonce) + 1, @@ -588,8 +629,11 @@ func TestKeeper_SaveOutbound(t *testing.T) { TssPubkey: cctx.GetCurrentOutboundParam().TssPubkey, }) + //ACT // Save outbound and assert all values are successfully saved - k.SaveOutbound(ctx, cctx) + k.SaveOutbound(ctx, cctx, cctx.GetCurrentOutboundParam().TssPubkey) + + //ASSERT _, found := k.GetOutboundTracker( ctx, cctx.GetCurrentOutboundParam().ReceiverChainId, @@ -616,8 +660,8 @@ func TestKeeper_SaveOutbound(t *testing.T) { }) t.Run("successfully save outbound with multiple trackers", func(t *testing.T) { + //ARRANGE k, ctx, _, zk := keepertest.CrosschainKeeper(t) - // setup state for crosschain and observer modules cctx := sample.CrossChainTx(t, "test") for _, outboundParams := range cctx.OutboundParams { @@ -635,15 +679,16 @@ func TestKeeper_SaveOutbound(t *testing.T) { }) } cctx.CctxStatus.Status = types.CctxStatus_PendingRevert - tssPubkey := cctx.GetCurrentOutboundParam().TssPubkey zk.ObserverKeeper.SetTSS(ctx, observertypes.TSS{ TssPubkey: tssPubkey, }) + //ACT // Save outbound and assert all values are successfully saved - k.SaveOutbound(ctx, cctx) + k.SaveOutbound(ctx, cctx, cctx.GetCurrentOutboundParam().TssPubkey) + //ASSERT for _, outboundParams := range cctx.OutboundParams { _, found := k.GetOutboundTracker( ctx, @@ -717,17 +762,6 @@ func TestKeeper_ValidateOutboundMessage(t *testing.T) { ) }) - t.Run("failed to validate outbound message if tss not found", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetCrossChainTx(ctx, *cctx) - _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - }) - require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) - }) - t.Run("failed to validate outbound message if chain does not match", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) cctx := sample.CrossChainTx(t, "test") diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20.go b/x/crosschain/keeper/msg_server_whitelist_erc20.go index 45cf836061..62ce836643 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20.go @@ -154,7 +154,7 @@ func (k msgServer) WhitelistERC20( GasLimit: uint64(msg.GasLimit), } k.fungibleKeeper.SetForeignCoins(ctx, foreignCoin) - k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx) + k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx, tss.TssPubkey) commit() diff --git a/x/crosschain/keeper/utils_test.go b/x/crosschain/keeper/utils_test.go index 2c4126b635..fb59b7afb9 100644 --- a/x/crosschain/keeper/utils_test.go +++ b/x/crosschain/keeper/utils_test.go @@ -2,17 +2,19 @@ package keeper_test import ( + "math/big" + "testing" + "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" "github.com/zeta-chain/zetacore/pkg/contracts/erc1967proxy" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - "math/big" - "testing" sdk "github.com/cosmos/cosmos-sdk/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" "github.com/ethereum/go-ethereum/common" - evmkeeper "github.com/evmos/ethermint/x/evm/keeper" "github.com/stretchr/testify/require" + + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" "github.com/zeta-chain/protocol-contracts/v1/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" "github.com/zeta-chain/zetacore/cmd/zetacored/config" diff --git a/x/crosschain/types/cmd_cctxs.go b/x/crosschain/types/cmd_cctxs.go index 3f416c6d7d..5ba7495d22 100644 --- a/x/crosschain/types/cmd_cctxs.go +++ b/x/crosschain/types/cmd_cctxs.go @@ -250,7 +250,7 @@ func MigrateFundCmdCCTX( gasLimit, gasPrice, priorityFee.MulUint64(2).String(), - newTSSPubKey, + currentTSSPubKey, ), nil } diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 279442d2c7..40182fe313 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -55,6 +55,7 @@ var ( 1156, "migration tx from an old tss address detected", ) - ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") - ErrInvalidGasLimit = errorsmod.Register(ModuleName, 1158, "invalid gas limit") + ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") + ErrInvalidGasLimit = errorsmod.Register(ModuleName, 1158, "invalid gas limit") + ErrUnableToSetOutboundInfo = errorsmod.Register(ModuleName, 1159, "unable to set outbound info") ) diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index 1305c31b7c..9d053f9b05 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/emissions/keeper/msg_server_withdraw_emissions.go b/x/emissions/keeper/msg_server_withdraw_emissions.go index 3b570ea81b..cb7231fc33 100644 --- a/x/emissions/keeper/msg_server_withdraw_emissions.go +++ b/x/emissions/keeper/msg_server_withdraw_emissions.go @@ -50,7 +50,7 @@ func (k msgServer) WithdrawEmission( SendCoinsFromModuleToAccount(ctx, types.UndistributedObserverRewardsPool, address, sdk.NewCoins(sdk.NewCoin(config.BaseDenom, msg.Amount))) if err != nil { ctx.Logger(). - Error(fmt.Sprintf("Error while processing withdraw of emission to adresss %s for amount %s : err %s", address, msg.Amount, err)) + Error(fmt.Sprintf("Error while processing withdraw of emission to address %s for amount %s : err %s", address, msg.Amount, err)) return nil, errorsmod.Wrap(types.ErrUnableToWithdrawEmissions, err.Error()) } diff --git a/x/fungible/keeper/deposits.go b/x/fungible/keeper/deposits.go index e77a8ba16b..4a05d1dcd3 100644 --- a/x/fungible/keeper/deposits.go +++ b/x/fungible/keeper/deposits.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" eth "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 5f4c61bebf..07354b6bff 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -19,7 +19,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/wzeta.sol" zevmconnectorcontract "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/zetaconnectorzevm.sol" diff --git a/x/fungible/keeper/evm_hooks.go b/x/fungible/keeper/evm_hooks.go index a171adb3e4..3c03c8974a 100644 --- a/x/fungible/keeper/evm_hooks.go +++ b/x/fungible/keeper/evm_hooks.go @@ -6,7 +6,7 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/x/fungible/types" ) diff --git a/x/fungible/keeper/evm_test.go b/x/fungible/keeper/evm_test.go index cd45aa8cc1..f80893d193 100644 --- a/x/fungible/keeper/evm_test.go +++ b/x/fungible/keeper/evm_test.go @@ -10,9 +10,11 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" + "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/wzeta.sol" "github.com/zeta-chain/protocol-contracts/v2/pkg/erc1967proxy.sol" diff --git a/x/fungible/keeper/gas_coin_and_pool_test.go b/x/fungible/keeper/gas_coin_and_pool_test.go index b703b212f4..2fc1929202 100644 --- a/x/fungible/keeper/gas_coin_and_pool_test.go +++ b/x/fungible/keeper/gas_coin_and_pool_test.go @@ -8,10 +8,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" "github.com/ethereum/go-ethereum/common" - evmkeeper "github.com/evmos/ethermint/x/evm/keeper" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + evmkeeper "github.com/zeta-chain/ethermint/x/evm/keeper" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/systemcontract.sol" uniswapv2router02 "github.com/zeta-chain/protocol-contracts/v1/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" diff --git a/x/fungible/keeper/msg_server_deploy_system_contract_test.go b/x/fungible/keeper/msg_server_deploy_system_contract_test.go index 882b8fecf1..4a92926ec0 100644 --- a/x/fungible/keeper/msg_server_deploy_system_contract_test.go +++ b/x/fungible/keeper/msg_server_deploy_system_contract_test.go @@ -6,9 +6,9 @@ import ( "testing" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" diff --git a/x/fungible/keeper/msg_server_update_contract_bytecode_test.go b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go index dadb62d145..a1f9cc4ddd 100644 --- a/x/fungible/keeper/msg_server_update_contract_bytecode_test.go +++ b/x/fungible/keeper/msg_server_update_contract_bytecode_test.go @@ -8,9 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/evmos/ethermint/x/evm/statedb" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/x/evm/statedb" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/fungible/keeper/msg_server_update_system_contract_test.go b/x/fungible/keeper/msg_server_update_system_contract_test.go index 1d3e6b7ce6..3e43c307db 100644 --- a/x/fungible/keeper/msg_server_update_system_contract_test.go +++ b/x/fungible/keeper/msg_server_update_system_contract_test.go @@ -6,8 +6,9 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/require" + + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v1/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" diff --git a/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go index 9794be84d2..7b7dc14b4e 100644 --- a/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go +++ b/x/fungible/keeper/msg_server_update_zrc20_withdraw_fee_test.go @@ -6,9 +6,10 @@ import ( "cosmossdk.io/math" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v2/pkg/zrc20.sol" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" diff --git a/x/fungible/keeper/v2_deposits.go b/x/fungible/keeper/v2_deposits.go index 66df27d86e..1f431e8a70 100644 --- a/x/fungible/keeper/v2_deposits.go +++ b/x/fungible/keeper/v2_deposits.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/pkg/errors" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v2/pkg/systemcontract.sol" "github.com/zeta-chain/zetacore/pkg/coin" diff --git a/x/fungible/keeper/v2_evm.go b/x/fungible/keeper/v2_evm.go index e77c04b580..3015471f1c 100644 --- a/x/fungible/keeper/v2_evm.go +++ b/x/fungible/keeper/v2_evm.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol" "github.com/zeta-chain/protocol-contracts/v2/pkg/revert.sol" "github.com/zeta-chain/protocol-contracts/v2/pkg/systemcontract.sol" diff --git a/x/fungible/keeper/zevm_message_passing_test.go b/x/fungible/keeper/zevm_message_passing_test.go index 5a450968be..96a4762583 100644 --- a/x/fungible/keeper/zevm_message_passing_test.go +++ b/x/fungible/keeper/zevm_message_passing_test.go @@ -7,9 +7,9 @@ import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/evmos/ethermint/x/evm/statedb" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/zeta-chain/ethermint/x/evm/statedb" "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/testutil/contracts" diff --git a/x/fungible/keeper/zevm_msg_passing.go b/x/fungible/keeper/zevm_msg_passing.go index 258df47209..675118dec5 100644 --- a/x/fungible/keeper/zevm_msg_passing.go +++ b/x/fungible/keeper/zevm_msg_passing.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ethcommon "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // ZETADepositAndCallContract deposits native ZETA to the to address if its an account or if the account does not exist yet diff --git a/x/fungible/types/evm.go b/x/fungible/types/evm.go index cf466f137c..d7aa882ce6 100644 --- a/x/fungible/types/evm.go +++ b/x/fungible/types/evm.go @@ -4,7 +4,7 @@ import ( "strings" "github.com/ethereum/go-ethereum/core/vm" - evmtypes "github.com/evmos/ethermint/x/evm/types" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" ) // IsRevertError checks if an error is a evm revert error diff --git a/x/fungible/types/evm_test.go b/x/fungible/types/evm_test.go index aa4a402900..b375d0c5ef 100644 --- a/x/fungible/types/evm_test.go +++ b/x/fungible/types/evm_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/ethereum/go-ethereum/core/vm" - evmtypes "github.com/evmos/ethermint/x/evm/types" "github.com/stretchr/testify/require" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/x/fungible/types" ) diff --git a/x/fungible/types/expected_keepers.go b/x/fungible/types/expected_keepers.go index ad0521ab81..a719bef123 100644 --- a/x/fungible/types/expected_keepers.go +++ b/x/fungible/types/expected_keepers.go @@ -9,8 +9,8 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/ethermint/x/evm/statedb" - evmtypes "github.com/evmos/ethermint/x/evm/types" + "github.com/zeta-chain/ethermint/x/evm/statedb" + evmtypes "github.com/zeta-chain/ethermint/x/evm/types" "github.com/zeta-chain/zetacore/pkg/chains" ) diff --git a/x/observer/keeper/msg_server_vote_tss.go b/x/observer/keeper/msg_server_vote_tss.go index 617411d575..9455dfa25b 100644 --- a/x/observer/keeper/msg_server_vote_tss.go +++ b/x/observer/keeper/msg_server_vote_tss.go @@ -42,11 +42,6 @@ func (k msgServer) VoteTSS(goCtx context.Context, msg *types.MsgVoteTSS) (*types return &types.MsgVoteTSSResponse{}, errorsmod.Wrap(types.ErrKeygenNotFound, voteTSSid) } - // Use a separate transaction to update keygen status to pending when trying to change the TSS address. - if keygen.Status == types.KeygenStatus_KeyGenSuccess { - return &types.MsgVoteTSSResponse{}, errorsmod.Wrap(types.ErrKeygenCompleted, voteTSSid) - } - // GetBallot checks against the supported chains list before querying for Ballot. ballotCreated := false index := msg.Digest() @@ -94,6 +89,30 @@ func (k msgServer) VoteTSS(goCtx context.Context, msg *types.MsgVoteTSS) (*types }, nil } + // The ballot is finalized, we check if this is the correct ballot for updating the TSS + // The requirements are + // 1. The keygen is still pending + // 2. The keygen block number matches the ballot block number ,which makes sure this the correct ballot for the current keygen + + // Return without an error so the vote is added to the ballot + if keygen.Status != types.KeygenStatus_PendingKeygen { + // The response is used for testing only.Setting false for keygen success as the keygen has already been finalized and it doesnt matter what the final status is.We are just asserting that the keygen was previously finalized and is not in pending status. + return &types.MsgVoteTSSResponse{ + VoteFinalized: isFinalized, + BallotCreated: ballotCreated, + KeygenSuccess: false, + }, nil + } + + // For cases when an observer tries to vote for an older pending ballot, associated with a keygen that was discarded , we would return at this check while still adding the vote to the ballot + if msg.KeygenZetaHeight != keygen.BlockNumber { + return &types.MsgVoteTSSResponse{ + VoteFinalized: isFinalized, + BallotCreated: ballotCreated, + KeygenSuccess: false, + }, nil + } + // Set TSS only on success, set keygen either way. // Keygen block can be updated using a policy transaction if keygen fails. keygenSuccess := false diff --git a/x/observer/keeper/msg_server_vote_tss_test.go b/x/observer/keeper/msg_server_vote_tss_test.go index f44ceaa07d..2d9466e89c 100644 --- a/x/observer/keeper/msg_server_vote_tss_test.go +++ b/x/observer/keeper/msg_server_vote_tss_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" "math" "testing" @@ -16,19 +17,24 @@ import ( func TestMsgServer_VoteTSS(t *testing.T) { t.Run("fail if node account not found", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) srv := keeper.NewMsgServerImpl(*k) + // ACT _, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: sample.AccAddress(), TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) + + // ASSERT require.ErrorIs(t, err, sdkerrors.ErrorInvalidSigner) }) t.Run("fail if keygen is not found", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) srv := keeper.NewMsgServerImpl(*k) @@ -36,16 +42,20 @@ func TestMsgServer_VoteTSS(t *testing.T) { nodeAcc := sample.NodeAccount() k.SetNodeAccount(ctx, *nodeAcc) + // ACT _, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) + + // ASSERT require.ErrorIs(t, err, types.ErrKeygenNotFound) }) t.Run("fail if keygen already completed ", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) srv := keeper.NewMsgServerImpl(*k) @@ -53,30 +63,43 @@ func TestMsgServer_VoteTSS(t *testing.T) { nodeAcc := sample.NodeAccount() keygen := sample.Keygen(t) keygen.Status = types.KeygenStatus_KeyGenSuccess + keygen.BlockNumber = 42 k.SetNodeAccount(ctx, *nodeAcc) k.SetKeygen(ctx, *keygen) + // ACT _, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, TssPubkey: sample.Tss().TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) - require.ErrorIs(t, err, types.ErrKeygenCompleted) + + // ASSERT + // keygen is already completed, but the vote can still be added if the operator has not voted yet + require.NoError(t, err) + ballot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + require.True(t, found) + require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, ballot.BallotStatus) + require.True(t, ballot.HasVoted(nodeAcc.Operator)) }) t.Run("can create a new ballot, vote success and finalize", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) - ctx = ctx.WithBlockHeight(42) + finalizingHeight := int64(55) + ctx = ctx.WithBlockHeight(finalizingHeight) srv := keeper.NewMsgServerImpl(*k) // setup state nodeAcc := sample.NodeAccount() keygen := sample.Keygen(t) keygen.Status = types.KeygenStatus_PendingKeygen + keygen.BlockNumber = 42 k.SetNodeAccount(ctx, *nodeAcc) k.SetKeygen(ctx, *keygen) + // ACT // there is a single node account, so the ballot will be created and finalized in a single vote res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, @@ -84,8 +107,9 @@ func TestMsgServer_VoteTSS(t *testing.T) { KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) - require.NoError(t, err) + // ASSERT + require.NoError(t, err) // check response require.True(t, res.BallotCreated) require.True(t, res.VoteFinalized) @@ -95,10 +119,17 @@ func TestMsgServer_VoteTSS(t *testing.T) { newKeygen, found := k.GetKeygen(ctx) require.True(t, found) require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) - require.EqualValues(t, ctx.BlockHeight(), newKeygen.BlockNumber) + require.EqualValues(t, finalizingHeight, newKeygen.BlockNumber) + + // check tss updated + tss, found := k.GetTSS(ctx) + require.True(t, found) + require.Equal(t, tss.KeyGenZetaHeight, int64(42)) + require.Equal(t, tss.FinalizedZetaHeight, finalizingHeight) }) t.Run("can create a new ballot, vote failure and finalize", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) ctx = ctx.WithBlockHeight(42) srv := keeper.NewMsgServerImpl(*k) @@ -106,10 +137,12 @@ func TestMsgServer_VoteTSS(t *testing.T) { // setup state nodeAcc := sample.NodeAccount() keygen := sample.Keygen(t) + keygen.BlockNumber = 42 keygen.Status = types.KeygenStatus_PendingKeygen k.SetNodeAccount(ctx, *nodeAcc) k.SetKeygen(ctx, *keygen) + // ACT // there is a single node account, so the ballot will be created and finalized in a single vote res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, @@ -117,8 +150,9 @@ func TestMsgServer_VoteTSS(t *testing.T) { KeygenZetaHeight: 42, Status: chains.ReceiveStatus_failed, }) - require.NoError(t, err) + // ASSERT + require.NoError(t, err) // check response require.True(t, res.BallotCreated) require.True(t, res.VoteFinalized) @@ -131,7 +165,135 @@ func TestMsgServer_VoteTSS(t *testing.T) { require.EqualValues(t, math.MaxInt64, newKeygen.BlockNumber) }) - t.Run("can create a new ballot, vote without finalizing, then add vote and finalizing", func(t *testing.T) { + t.Run( + "can create a new ballot, vote without finalizing, then add final vote to update keygen and set tss", + func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.ObserverKeeper(t) + finalizingHeight := int64(55) + ctx = ctx.WithBlockHeight(finalizingHeight) + srv := keeper.NewMsgServerImpl(*k) + + // setup state with 3 node accounts + nodeAcc1 := sample.NodeAccount() + nodeAcc2 := sample.NodeAccount() + nodeAcc3 := sample.NodeAccount() + keygen := sample.Keygen(t) + keygen.BlockNumber = 42 + keygen.Status = types.KeygenStatus_PendingKeygen + tss := sample.Tss() + k.SetNodeAccount(ctx, *nodeAcc1) + k.SetNodeAccount(ctx, *nodeAcc2) + k.SetNodeAccount(ctx, *nodeAcc3) + k.SetKeygen(ctx, *keygen) + + // ACT + // 1st vote: created ballot, but not finalized + res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // 2nd vote: already created ballot, and not finalized + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // 3rd vote: finalize the ballot + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc3.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // ASSERT + // check response + require.False(t, res.BallotCreated) + require.True(t, res.VoteFinalized) + require.True(t, res.KeygenSuccess) + + // check keygen updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) + require.EqualValues(t, ctx.BlockHeight(), newKeygen.BlockNumber) + + // check tss updated + tss, found = k.GetTSS(ctx) + require.True(t, found) + require.Equal(t, tss.KeyGenZetaHeight, int64(42)) + require.Equal(t, tss.FinalizedZetaHeight, finalizingHeight) + }, + ) + + t.Run("fail if voting fails", func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.ObserverKeeper(t) + ctx = ctx.WithBlockHeight(42) + srv := keeper.NewMsgServerImpl(*k) + + // setup state with two node accounts to not finalize the ballot + nodeAcc := sample.NodeAccount() + keygen := sample.Keygen(t) + keygen.Status = types.KeygenStatus_PendingKeygen + k.SetNodeAccount(ctx, *nodeAcc) + k.SetNodeAccount(ctx, *sample.NodeAccount()) + k.SetKeygen(ctx, *keygen) + + // add a first vote + res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc.Operator, + TssPubkey: sample.Tss().TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + require.False(t, res.VoteFinalized) + + // ACT + // vote again: voting should fail + _, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc.Operator, + TssPubkey: sample.Tss().TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + + // ASSERT + require.ErrorIs(t, err, types.ErrUnableToAddVote) + }) + + t.Run("can create a new ballot, without finalizing the older and then finalize older ballot", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) ctx = ctx.WithBlockHeight(42) srv := keeper.NewMsgServerImpl(*k) @@ -148,6 +310,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { k.SetNodeAccount(ctx, *nodeAcc3) k.SetKeygen(ctx, *keygen) + // ACT // 1st vote: created ballot, but not finalized res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc1.Operator, @@ -186,7 +349,51 @@ func TestMsgServer_VoteTSS(t *testing.T) { require.True(t, found) require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) - // 3rd vote: finalize the ballot + keygen.Status = types.KeygenStatus_PendingKeygen + keygen.BlockNumber = 52 + k.SetKeygen(ctx, *keygen) + + // Start voting on a new ballot + tss2 := sample.Tss() + // 1st Vote on new ballot (acc1) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss2.TssPubkey, + KeygenZetaHeight: 52, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // 2nd vote on new ballot: already created ballot, and not finalized (acc3) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc3.Operator, + TssPubkey: tss2.TssPubkey, + KeygenZetaHeight: 52, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen status + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // At this point, we have two ballots + // 1. Ballot for keygen 42 Voted : (acc1, acc2) + // 2. Ballot for keygen 52 Voted : (acc1, acc3) + + // 3rd vote on ballot 1: finalize the older ballot + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc3.Operator, TssPubkey: tss.TssPubkey, @@ -195,48 +402,317 @@ func TestMsgServer_VoteTSS(t *testing.T) { }) require.NoError(t, err) - // check response + // ASSERT + // Check response require.False(t, res.BallotCreated) require.True(t, res.VoteFinalized) - require.True(t, res.KeygenSuccess) + require.False(t, res.KeygenSuccess) + // Older ballot should be finalized which still keep keygen in pending state. + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + _, found = k.GetTSS(ctx) + require.False(t, found) + + oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + require.True(t, found) + require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, oldBallot.BallotStatus) + + newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 52, "tss-keygen")) + require.True(t, found) + require.EqualValues(t, types.BallotStatus_BallotInProgress, newBallot.BallotStatus) + }) + + t.Run("can create a new ballot, vote without finalizing,then finalize newer ballot", func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.ObserverKeeper(t) + ctx = ctx.WithBlockHeight(42) + srv := keeper.NewMsgServerImpl(*k) + + // setup state with 3 node accounts + nodeAcc1 := sample.NodeAccount() + nodeAcc2 := sample.NodeAccount() + nodeAcc3 := sample.NodeAccount() + keygen := sample.Keygen(t) + keygen.Status = types.KeygenStatus_PendingKeygen + keygen.BlockNumber = 42 + tss := sample.Tss() + k.SetNodeAccount(ctx, *nodeAcc1) + k.SetNodeAccount(ctx, *nodeAcc2) + k.SetNodeAccount(ctx, *nodeAcc3) + k.SetKeygen(ctx, *keygen) + + // ACT + // 1st vote: created ballot, but not finalized + res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // 2nd vote: already created ballot, and not finalized + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) // check keygen not updated newKeygen, found = k.GetKeygen(ctx) require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // Update keygen to 52 and start voting on new ballot + keygen.Status = types.KeygenStatus_PendingKeygen + keygen.BlockNumber = 52 + k.SetKeygen(ctx, *keygen) + + // Start voting on a new ballot + tss2 := sample.Tss() + // 1st Vote on new ballot (acc1) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss2.TssPubkey, + KeygenZetaHeight: 52, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // 2nd vote on new ballot: already created ballot, and not finalized (acc3) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc3.Operator, + TssPubkey: tss2.TssPubkey, + KeygenZetaHeight: 52, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen status + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_PendingKeygen, newKeygen.Status) + + // At this point, we have two ballots + // 1. Ballot for keygen 42 Voted : (acc1, acc2) + // 2. Ballot for keygen 52 Voted : (acc1, acc3) + + // 3rd vote on ballot 2: finalize the newer ballot + + finalizingHeight := int64(55) + ctx = ctx.WithBlockHeight(finalizingHeight) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss2.TssPubkey, + KeygenZetaHeight: 52, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // ASSERT + require.False(t, res.BallotCreated) + require.True(t, res.VoteFinalized) + require.True(t, res.KeygenSuccess) + // Newer ballot should be finalized which make keygen success + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, finalizingHeight, newKeygen.BlockNumber) require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) - require.EqualValues(t, ctx.BlockHeight(), newKeygen.BlockNumber) + + tss, found = k.GetTSS(ctx) + require.True(t, found) + require.Equal(t, tss.KeyGenZetaHeight, int64(52)) + require.Equal(t, tss.FinalizedZetaHeight, finalizingHeight) + + oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + require.True(t, found) + require.EqualValues(t, types.BallotStatus_BallotInProgress, oldBallot.BallotStatus) + + newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 52, "tss-keygen")) + require.True(t, found) + require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, newBallot.BallotStatus) }) - t.Run("fail if voting fails", func(t *testing.T) { + t.Run("add vote to a successful keygen", func(t *testing.T) { + // ARRANGE k, ctx, _, _ := keepertest.ObserverKeeper(t) ctx = ctx.WithBlockHeight(42) srv := keeper.NewMsgServerImpl(*k) - // setup state with two node accounts to not finalize the ballot - nodeAcc := sample.NodeAccount() + // setup state with 3 node accounts + nodeAcc1 := sample.NodeAccount() + nodeAcc2 := sample.NodeAccount() + nodeAcc3 := sample.NodeAccount() keygen := sample.Keygen(t) - keygen.Status = types.KeygenStatus_PendingKeygen - k.SetNodeAccount(ctx, *nodeAcc) - k.SetNodeAccount(ctx, *sample.NodeAccount()) + keygen.Status = types.KeygenStatus_KeyGenSuccess + tss := sample.Tss() + k.SetNodeAccount(ctx, *nodeAcc1) + k.SetNodeAccount(ctx, *nodeAcc2) + k.SetNodeAccount(ctx, *nodeAcc3) k.SetKeygen(ctx, *keygen) - // add a first vote + // ACT + // 1st vote: created ballot, but not finalized res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ - Creator: nodeAcc.Operator, - TssPubkey: sample.Tss().TssPubkey, + Creator: nodeAcc1.Operator, + TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) - // vote again: voting should fail - _, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ - Creator: nodeAcc.Operator, - TssPubkey: sample.Tss().TssPubkey, + // check keygen not updated + newKeygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) + + // 2nd vote: already created ballot, and not finalized + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) - require.ErrorIs(t, err, types.ErrUnableToAddVote) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) + + // 3nd vote: already created ballot, and not finalized (acc3) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc3.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.True(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) + }) + + t.Run("add vote to a failed keygen ", func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.ObserverKeeper(t) + ctx = ctx.WithBlockHeight(42) + srv := keeper.NewMsgServerImpl(*k) + + // setup state with 3 node accounts + nodeAcc1 := sample.NodeAccount() + nodeAcc2 := sample.NodeAccount() + nodeAcc3 := sample.NodeAccount() + keygen := sample.Keygen(t) + keygen.Status = types.KeygenStatus_KeyGenFailed + tss := sample.Tss() + k.SetNodeAccount(ctx, *nodeAcc1) + k.SetNodeAccount(ctx, *nodeAcc2) + k.SetNodeAccount(ctx, *nodeAcc3) + k.SetKeygen(ctx, *keygen) + + // ACT + // 1st vote: created ballot, but not finalized + res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_failed, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found := k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenFailed, newKeygen.Status) + + // 2nd vote: already created ballot, and not finalized + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_failed, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenFailed, newKeygen.Status) + + // 3nd vote: already created ballot, and not finalized (acc3) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc3.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_failed, + }) + require.NoError(t, err) + + // check response + require.False(t, res.BallotCreated) + require.True(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // check keygen not updated + newKeygen, found = k.GetKeygen(ctx) + require.True(t, found) + require.EqualValues(t, types.KeygenStatus_KeyGenFailed, newKeygen.Status) }) } diff --git a/zetaclient/chains/bitcoin/fee.go b/zetaclient/chains/bitcoin/fee.go index aec41407d9..3293727b47 100644 --- a/zetaclient/chains/bitcoin/fee.go +++ b/zetaclient/chains/bitcoin/fee.go @@ -15,27 +15,42 @@ import ( "github.com/rs/zerolog" "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/rpc" + "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" clientcommon "github.com/zeta-chain/zetacore/zetaclient/common" ) const ( - bytesPerKB = 1000 - bytesPerInput = 41 // each input is 41 bytes - bytesPerOutputP2TR = 43 // each P2TR output is 43 bytes - bytesPerOutputP2WSH = 43 // each P2WSH output is 43 bytes - bytesPerOutputP2WPKH = 31 // each P2WPKH output is 31 bytes - bytesPerOutputP2SH = 32 // each P2SH output is 32 bytes - bytesPerOutputP2PKH = 34 // each P2PKH output is 34 bytes - bytesPerOutputAvg = 37 // average size of all above types of outputs (36.6 bytes) - bytes1stWitness = 110 // the 1st witness incurs about 110 bytes and it may vary - bytesPerWitness = 108 // each additional witness incurs about 108 bytes and it may vary - defaultDepositorFeeRate = 20 // 20 sat/byte is the default depositor fee rate - - OutboundBytesMin = uint64(239) // 239vB == EstimateSegWitTxSize(2, 2, toP2WPKH) - OutboundBytesMax = uint64(1543) // 1543v == EstimateSegWitTxSize(21, 2, toP2TR) - OutboundBytesAvg = uint64(245) // 245vB is a suggested gas limit for zetacore - - DynamicDepositorFeeHeight = 834500 // DynamicDepositorFeeHeight contains the starting height (Bitcoin mainnet) from which dynamic depositor fee will take effect + // constants related to transaction size calculations + bytesPerKB = 1000 + bytesPerInput = 41 // each input is 41 bytes + bytesPerOutputP2TR = 43 // each P2TR output is 43 bytes + bytesPerOutputP2WSH = 43 // each P2WSH output is 43 bytes + bytesPerOutputP2WPKH = 31 // each P2WPKH output is 31 bytes + bytesPerOutputP2SH = 32 // each P2SH output is 32 bytes + bytesPerOutputP2PKH = 34 // each P2PKH output is 34 bytes + bytesPerOutputAvg = 37 // average size of all above types of outputs (36.6 bytes) + bytes1stWitness = 110 // the 1st witness incurs about 110 bytes and it may vary + bytesPerWitness = 108 // each additional witness incurs about 108 bytes and it may vary + OutboundBytesMin = uint64(239) // 239vB == EstimateSegWitTxSize(2, 2, toP2WPKH) + OutboundBytesMax = uint64(1543) // 1543v == EstimateSegWitTxSize(21, 2, toP2TR) + OutboundBytesAvg = uint64(245) // 245vB is a suggested gas limit for zetacore + + // defaultDepositorFeeRate is the default fee rate for depositor fee, 20 sat/vB + defaultDepositorFeeRate = 20 + + // defaultTestnetFeeRate is the default fee rate for testnet, 10 sat/vB + defaultTestnetFeeRate = 10 + + // feeRateCountBackBlocks is the default number of blocks to look back for fee rate estimation + feeRateCountBackBlocks = 2 + + // DynamicDepositorFeeHeight is the mainnet height from which dynamic depositor fee V1 is applied + DynamicDepositorFeeHeight = 834500 + + // DynamicDepositorFeeHeightV2 is the mainnet height from which dynamic depositor fee V2 is applied + // Height 863400 is approximately a month away (2024-09-28) from the time of writing, allowing enough time for the upgrade + DynamicDepositorFeeHeightV2 = 863400 ) var ( @@ -239,3 +254,73 @@ func CalcDepositorFee( return DepositorFee(feeRate) } + +// CalcDepositorFeeV2 calculates the depositor fee for a given tx result +func CalcDepositorFeeV2( + rpcClient interfaces.BTCRPCClient, + rawResult *btcjson.TxRawResult, + netParams *chaincfg.Params, +) (float64, error) { + // use default fee for regnet + if netParams.Name == chaincfg.RegressionNetParams.Name { + return DefaultDepositorFee, nil + } + + // get fee rate of the transaction + _, feeRate, err := rpc.GetTransactionFeeAndRate(rpcClient, rawResult) + if err != nil { + return 0, errors.Wrapf(err, "error getting fee rate for tx %s", rawResult.Txid) + } + + // apply gas price multiplier + // #nosec G115 always in range + feeRate = int64(float64(feeRate) * clientcommon.BTCOutboundGasPriceMultiplier) + + return DepositorFee(feeRate), nil +} + +// GetRecentFeeRate gets the highest fee rate from recent blocks +// Note: this method should be used for testnet ONLY +func GetRecentFeeRate(rpcClient interfaces.BTCRPCClient, netParams *chaincfg.Params) (uint64, error) { + // should avoid using this method for mainnet + if netParams.Name == chaincfg.MainNetParams.Name { + return 0, errors.New("GetRecentFeeRate should not be used for mainnet") + } + + // get the current block number + blockNumber, err := rpcClient.GetBlockCount() + if err != nil { + return 0, err + } + + // get the highest fee rate among recent 'countBack' blocks to avoid underestimation + highestRate := int64(0) + for i := int64(0); i < feeRateCountBackBlocks; i++ { + // get the block + hash, err := rpcClient.GetBlockHash(blockNumber - i) + if err != nil { + return 0, err + } + block, err := rpcClient.GetBlockVerboseTx(hash) + if err != nil { + return 0, err + } + + // computes the average fee rate of the block and take the higher rate + avgFeeRate, err := CalcBlockAvgFeeRate(block, netParams) + if err != nil { + return 0, err + } + if avgFeeRate > highestRate { + highestRate = avgFeeRate + } + } + + // use 10 sat/byte as default estimation if recent fee rate drops to 0 + if highestRate == 0 { + highestRate = defaultTestnetFeeRate + } + + // #nosec G115 always in range + return uint64(highestRate), nil +} diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index a7dc5afe3d..2035340e73 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -421,6 +421,19 @@ func GetBtcEvent( return nil, nil } + // switch to depositor fee V2 if + // 1. it is bitcoin testnet, or + // 2. it is bitcoin mainnet and upgrade height is reached + // TODO: remove CalcDepositorFeeV1 and below conditions after the upgrade height + // https://github.com/zeta-chain/node/issues/2766 + if netParams.Name == chaincfg.TestNet3Params.Name || + (netParams.Name == chaincfg.MainNetParams.Name && blockNumber >= bitcoin.DynamicDepositorFeeHeightV2) { + depositorFee, err = bitcoin.CalcDepositorFeeV2(rpcClient, &tx, netParams) + if err != nil { + return nil, errors.Wrapf(err, "error calculating depositor fee V2 for inbound: %s", tx.Txid) + } + } + // deposit amount has to be no less than the minimum depositor fee if vout0.Value < depositorFee { logger.Info(). diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 6feeffbbe0..86cf639a7f 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -23,7 +23,6 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/base" "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin" - "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/rpc" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/db" "github.com/zeta-chain/zetacore/zetaclient/metrics" @@ -566,7 +565,7 @@ func (ob *Observer) specialHandleFeeRate() (uint64, error) { // hardcode gas price for regnet return 1, nil case chains.NetworkType_testnet: - feeRateEstimated, err := rpc.GetRecentFeeRate(ob.btcClient, ob.netParams) + feeRateEstimated, err := bitcoin.GetRecentFeeRate(ob.btcClient, ob.netParams) if err != nil { return 0, errors.Wrapf(err, "error GetRecentFeeRate") } diff --git a/zetaclient/chains/bitcoin/rpc/rpc.go b/zetaclient/chains/bitcoin/rpc/rpc.go index 472e8b0e0f..1f67e492d6 100644 --- a/zetaclient/chains/bitcoin/rpc/rpc.go +++ b/zetaclient/chains/bitcoin/rpc/rpc.go @@ -5,24 +5,16 @@ import ( "time" "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcutil" "github.com/pkg/errors" - "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/config" ) const ( - // feeRateCountBackBlocks is the default number of blocks to look back for fee rate estimation - feeRateCountBackBlocks = 2 - - // defaultTestnetFeeRate is the default fee rate for testnet, 10 sat/byte - defaultTestnetFeeRate = 10 - // RPCAlertLatency is the default threshold for RPC latency to be considered unhealthy and trigger an alert. // Bitcoin block time is 10 minutes, 1200s (20 minutes) is a reasonable threshold for Bitcoin RPCAlertLatency = time.Duration(1200) * time.Second @@ -69,6 +61,20 @@ func GetTxResultByHash( return hash, txResult, nil } +// GetTXRawResultByHash gets the raw transaction by hash +func GetRawTxByHash(rpcClient interfaces.BTCRPCClient, txID string) (*btcutil.Tx, error) { + hash, err := chainhash.NewHashFromStr(txID) + if err != nil { + return nil, errors.Wrapf(err, "GetRawTxByHash: error NewHashFromStr: %s", txID) + } + + tx, err := rpcClient.GetRawTransaction(hash) + if err != nil { + return nil, errors.Wrapf(err, "GetRawTxByHash: error GetRawTransaction %s", txID) + } + return tx, nil +} + // GetBlockHeightByHash gets the block height by block hash func GetBlockHeightByHash( rpcClient interfaces.BTCRPCClient, @@ -124,44 +130,55 @@ func GetRawTxResult( return btcjson.TxRawResult{}, fmt.Errorf("GetRawTxResult: tx %s not included yet", hash) } -// GetRecentFeeRate gets the highest fee rate from recent blocks -// Note: this method is only used for testnet -func GetRecentFeeRate(rpcClient interfaces.BTCRPCClient, netParams *chaincfg.Params) (uint64, error) { - blockNumber, err := rpcClient.GetBlockCount() - if err != nil { - return 0, err +// GetTransactionFeeAndRate gets the transaction fee and rate for a given tx result +func GetTransactionFeeAndRate(rpcClient interfaces.BTCRPCClient, rawResult *btcjson.TxRawResult) (int64, int64, error) { + var ( + totalInputValue int64 + totalOutputValue int64 + ) + + // make sure the tx Vsize is not zero (should not happen) + if rawResult.Vsize <= 0 { + return 0, 0, fmt.Errorf("tx %s has non-positive Vsize: %d", rawResult.Txid, rawResult.Vsize) } - // get the highest fee rate among recent 'countBack' blocks to avoid underestimation - highestRate := int64(0) - for i := int64(0); i < feeRateCountBackBlocks; i++ { - // get the block - hash, err := rpcClient.GetBlockHash(blockNumber - i) - if err != nil { - return 0, err - } - block, err := rpcClient.GetBlockVerboseTx(hash) + // sum up total input value + for _, vin := range rawResult.Vin { + prevTx, err := GetRawTxByHash(rpcClient, vin.Txid) if err != nil { - return 0, err + return 0, 0, errors.Wrapf(err, "failed to get previous tx: %s", vin.Txid) } + totalInputValue += prevTx.MsgTx().TxOut[vin.Vout].Value + } - // computes the average fee rate of the block and take the higher rate - avgFeeRate, err := bitcoin.CalcBlockAvgFeeRate(block, netParams) - if err != nil { - return 0, err - } - if avgFeeRate > highestRate { - highestRate = avgFeeRate - } + // query the raw tx + tx, err := GetRawTxByHash(rpcClient, rawResult.Txid) + if err != nil { + return 0, 0, errors.Wrapf(err, "failed to get tx: %s", rawResult.Txid) } - // use 10 sat/byte as default estimation if recent fee rate drops to 0 - if highestRate == 0 { - highestRate = defaultTestnetFeeRate + // sum up total output value + for _, vout := range tx.MsgTx().TxOut { + totalOutputValue += vout.Value } + // calculate the transaction fee in satoshis + fee := totalInputValue - totalOutputValue + if fee < 0 { // never happens + return 0, 0, fmt.Errorf("got negative fee: %d", fee) + } + + // Note: the calculation uses 'Vsize' returned by RPC to simplify dev experience: + // - 1. the devs could use the same value returned by their RPC endpoints to estimate deposit fee. + // - 2. the devs don't have to bother 'Vsize' calculation, even though there is more accurate formula. + // Moreoever, the accurate 'Vsize' is usually an adjusted size (float value) by Bitcoin Core. + // - 3. the 'Vsize' calculation could depend on program language and the library used. + // + // calculate the fee rate in satoshis/vByte // #nosec G115 always in range - return uint64(highestRate), nil + feeRate := fee / int64(rawResult.Vsize) + + return fee, feeRate, nil } // CheckRPCStatus checks the RPC status of the bitcoin chain diff --git a/zetaclient/chains/bitcoin/rpc/rpc_live_test.go b/zetaclient/chains/bitcoin/rpc/rpc_live_test.go index 4e12f33507..92a5dd42fb 100644 --- a/zetaclient/chains/bitcoin/rpc/rpc_live_test.go +++ b/zetaclient/chains/bitcoin/rpc/rpc_live_test.go @@ -10,92 +10,24 @@ import ( "testing" "time" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" - "github.com/ethereum/go-ethereum/crypto" "github.com/pkg/errors" "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "github.com/zeta-chain/zetacore/zetaclient/db" "github.com/zeta-chain/zetacore/pkg/chains" - "github.com/zeta-chain/zetacore/zetaclient/chains/base" "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin" "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/observer" "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/rpc" "github.com/zeta-chain/zetacore/zetaclient/common" "github.com/zeta-chain/zetacore/zetaclient/config" "github.com/zeta-chain/zetacore/zetaclient/testutils" - "github.com/zeta-chain/zetacore/zetaclient/testutils/mocks" ) -type BitcoinObserverTestSuite struct { - suite.Suite - rpcClient *rpcclient.Client -} - -func (suite *BitcoinObserverTestSuite) SetupTest() { - // test private key with EVM address - //// EVM: 0x236C7f53a90493Bb423411fe4117Cb4c2De71DfB - // BTC testnet3: muGe9prUBjQwEnX19zG26fVRHNi8z7kSPo - skHex := "7b8507ba117e069f4a3f456f505276084f8c92aee86ac78ae37b4d1801d35fa8" - privateKey, err := crypto.HexToECDSA(skHex) - suite.Require().NoError(err) - pkBytes := crypto.FromECDSAPub(&privateKey.PublicKey) - suite.T().Logf("pubkey: %d", len(pkBytes)) - - tss := &mocks.TSS{ - PrivKey: privateKey, - } - - // create mock arguments for constructor - chain := chains.BitcoinMainnet - params := mocks.MockChainParams(chain.ChainId, 10) - btcClient := mocks.NewMockBTCRPCClient() - - database, err := db.NewFromSqliteInMemory(true) - suite.Require().NoError(err) - - // create observer - ob, err := observer.NewObserver(chain, btcClient, params, nil, tss, 60, database, base.DefaultLogger(), nil) - - suite.Require().NoError(err) - suite.Require().NotNil(ob) - suite.rpcClient, err = createRPCClient(18332) - suite.Require().NoError(err) - skBytes, err := hex.DecodeString(skHex) - suite.Require().NoError(err) - suite.T().Logf("skBytes: %d", len(skBytes)) - - _, err = btcClient.CreateWallet("e2e") - suite.Require().NoError(err) - addr, err := btcClient.GetNewAddress("test") - suite.Require().NoError(err) - suite.T().Logf("deployer address: %s", addr) - //err = btc.ImportPrivKey(privkeyWIF) - //suite.Require().NoError(err) - - btcClient.GenerateToAddress(101, addr, nil) - suite.Require().NoError(err) - - bal, err := btcClient.GetBalance("*") - suite.Require().NoError(err) - suite.T().Logf("balance: %f", bal.ToBTC()) - - utxo, err := btcClient.ListUnspent() - suite.Require().NoError(err) - suite.T().Logf("utxo: %d", len(utxo)) - for _, u := range utxo { - suite.T().Logf("utxo: %s %f", u.Address, u.Amount) - } -} - -func (suite *BitcoinObserverTestSuite) TearDownSuite() { -} - // createRPCClient creates a new Bitcoin RPC client for given chainID func createRPCClient(chainID int64) (*rpcclient.Client, error) { var connCfg *rpcclient.ConnConfig @@ -127,6 +59,7 @@ func createRPCClient(chainID int64) (*rpcclient.Client, error) { return rpcclient.New(connCfg, nil) } +// getFeeRate is a helper function to get fee rate for a given confirmation target func getFeeRate( client *rpcclient.Client, confTarget int64, @@ -145,28 +78,60 @@ func getFeeRate( return new(big.Int).SetInt64(int64(*feeResult.FeeRate * 1e8)), nil } -// All methods that begin with "Test" are run as tests within a -// suite. -func (suite *BitcoinObserverTestSuite) Test1() { - feeResult, err := suite.rpcClient.EstimateSmartFee(1, nil) - suite.Require().NoError(err) - suite.T().Logf("fee result: %f", *feeResult.FeeRate) - bn, err := suite.rpcClient.GetBlockCount() - suite.Require().NoError(err) - suite.T().Logf("block %d", bn) +// getMempoolSpaceTxsByBlock gets mempool.space txs for a given block +func getMempoolSpaceTxsByBlock( + t *testing.T, + client *rpcclient.Client, + blkNumber int64, + testnet bool, +) (*chainhash.Hash, []testutils.MempoolTx, error) { + blkHash, err := client.GetBlockHash(blkNumber) + if err != nil { + t.Logf("error GetBlockHash for block %d: %s\n", blkNumber, err) + return nil, nil, err + } + // get mempool.space txs for the block + mempoolTxs, err := testutils.GetBlockTxs(context.Background(), blkHash.String(), testnet) + if err != nil { + t.Logf("error GetBlockTxs %d: %s\n", blkNumber, err) + return nil, nil, err + } + + return blkHash, mempoolTxs, nil +} + +// Test_BitcoinLive is a phony test to run each live test individually +func Test_BitcoinLive(t *testing.T) { + // LiveTest_FilterAndParseIncomingTx(t) + // LiveTest_FilterAndParseIncomingTx_Nop(t) + // LiveTest_NewRPCClient(t) + // LiveTest_GetBlockHeightByHash(t) + // LiveTest_BitcoinFeeRate(t) + // LiveTest_AvgFeeRateMainnetMempoolSpace(t) + // LiveTest_AvgFeeRateTestnetMempoolSpace(t) + // LiveTest_GetRecentFeeRate(t) + // LiveTest_GetSenderByVin(t) + // LiveTest_GetTransactionFeeAndRate(t) + // LiveTest_CalcDepositorFeeV2(t) +} + +func LiveTest_FilterAndParseIncomingTx(t *testing.T) { + // setup Bitcoin client + client, err := createRPCClient(chains.BitcoinTestnet.ChainId) + require.NoError(t, err) + + // get the block that contains the incoming tx hashStr := "0000000000000032cb372f5d5d99c1ebf4430a3059b67c47a54dd626550fb50d" - var hash chainhash.Hash - err = chainhash.Decode(&hash, hashStr) - suite.Require().NoError(err) + hash, err := chainhash.NewHashFromStr(hashStr) + require.NoError(t, err) - block, err := suite.rpcClient.GetBlockVerboseTx(&hash) - suite.Require().NoError(err) - suite.T().Logf("block confirmation %d", block.Confirmations) - suite.T().Logf("block txs len %d", len(block.Tx)) + block, err := client.GetBlockVerboseTx(hash) + require.NoError(t, err) + // filter incoming tx inbounds, err := observer.FilterAndParseIncomingTx( - suite.rpcClient, + client, block.Tx, uint64(block.Height), "tb1qsa222mn2rhdq9cruxkz8p2teutvxuextx3ees2", @@ -174,36 +139,37 @@ func (suite *BitcoinObserverTestSuite) Test1() { &chaincfg.TestNet3Params, 0.0, ) - suite.Require().NoError(err) - suite.Require().Equal(1, len(inbounds)) - suite.Require().Equal(inbounds[0].Value, 0.0001) - suite.Require().Equal(inbounds[0].ToAddress, "tb1qsa222mn2rhdq9cruxkz8p2teutvxuextx3ees2") + require.NoError(t, err) + require.Len(t, inbounds, 1) + require.Equal(t, inbounds[0].Value, 0.0001) + require.Equal(t, inbounds[0].ToAddress, "tb1qsa222mn2rhdq9cruxkz8p2teutvxuextx3ees2") + // the text memo is base64 std encoded string:DSRR1RmDCwWmxqY201/TMtsJdmA= // see https://blockstream.info/testnet/tx/889bfa69eaff80a826286d42ec3f725fd97c3338357ddc3a1f543c2d6266f797 - memo, err := hex.DecodeString("0d2451D519830B05a6C6a636d35fd332dB097660") - suite.Require().NoError(err) - suite.Require().Equal((inbounds[0].MemoBytes), memo) - suite.Require().Equal(inbounds[0].FromAddress, "tb1qyslx2s8evalx67n88wf42yv7236303ezj3tm2l") - suite.T().Logf("from: %s", inbounds[0].FromAddress) - suite.Require().Equal(inbounds[0].BlockNumber, uint64(2406185)) - suite.Require().Equal(inbounds[0].TxHash, "889bfa69eaff80a826286d42ec3f725fd97c3338357ddc3a1f543c2d6266f797") + memo, err := hex.DecodeString("4453525231526d444377576d7871593230312f544d74734a646d413d") + require.NoError(t, err) + require.Equal(t, inbounds[0].MemoBytes, memo) + require.Equal(t, inbounds[0].FromAddress, "tb1qyslx2s8evalx67n88wf42yv7236303ezj3tm2l") + require.Equal(t, inbounds[0].BlockNumber, uint64(2406185)) + require.Equal(t, inbounds[0].TxHash, "889bfa69eaff80a826286d42ec3f725fd97c3338357ddc3a1f543c2d6266f797") } -// a tx with memo around 81B (is this allowed1?) -func (suite *BitcoinObserverTestSuite) Test2() { +func LiveTest_FilterAndParseIncomingTx_Nop(t *testing.T) { + // setup Bitcoin client + client, err := createRPCClient(chains.BitcoinTestnet.ChainId) + require.NoError(t, err) + + // get a block that contains no incoming tx hashStr := "000000000000002fd8136dbf91708898da9d6ae61d7c354065a052568e2f2888" - var hash chainhash.Hash - err := chainhash.Decode(&hash, hashStr) - suite.Require().NoError(err) + hash, err := chainhash.NewHashFromStr(hashStr) + require.NoError(t, err) - block, err := suite.rpcClient.GetBlockVerboseTx(&hash) - suite.Require().NoError(err) - suite.T().Logf("block confirmation %d", block.Confirmations) - suite.T().Logf("block height %d", block.Height) - suite.T().Logf("block txs len %d", len(block.Tx)) + block, err := client.GetBlockVerboseTx(hash) + require.NoError(t, err) + // filter incoming tx inbounds, err := observer.FilterAndParseIncomingTx( - suite.rpcClient, + client, block.Tx, uint64(block.Height), "tb1qsa222mn2rhdq9cruxkz8p2teutvxuextx3ees2", @@ -211,8 +177,9 @@ func (suite *BitcoinObserverTestSuite) Test2() { &chaincfg.TestNet3Params, 0.0, ) - suite.Require().NoError(err) - suite.Require().Equal(0, len(inbounds)) + + require.NoError(t, err) + require.Empty(t, inbounds) } // TestBitcoinObserverLive is a phony test to run each live test individually @@ -221,21 +188,18 @@ func TestBitcoinObserverLive(t *testing.T) { return } - // disable legacy live tests - // suite.Run(t, new(BitcoinClientTestSuite)) - - LiveTestNewRPCClient(t) - LiveTestCheckRPCStatus(t) - LiveTestGetBlockHeightByHash(t) - LiveTestBitcoinFeeRate(t) - LiveTestAvgFeeRateMainnetMempoolSpace(t) - LiveTestAvgFeeRateTestnetMempoolSpace(t) - LiveTestGetRecentFeeRate(t) - LiveTestGetSenderByVin(t) + LiveTest_NewRPCClient(t) + LiveTest_CheckRPCStatus(t) + LiveTest_GetBlockHeightByHash(t) + LiveTest_BitcoinFeeRate(t) + LiveTest_AvgFeeRateMainnetMempoolSpace(t) + LiveTest_AvgFeeRateTestnetMempoolSpace(t) + LiveTest_GetRecentFeeRate(t) + LiveTest_GetSenderByVin(t) } // LiveTestNewRPCClient creates a new Bitcoin RPC client -func LiveTestNewRPCClient(t *testing.T) { +func LiveTest_NewRPCClient(t *testing.T) { btcConfig := config.BTCConfig{ RPCUsername: "user", RPCPassword: "pass", @@ -253,8 +217,8 @@ func LiveTestNewRPCClient(t *testing.T) { require.Greater(t, bn, int64(0)) } -// LiveTestCheckRPCStatus checks the RPC status of the Bitcoin chain -func LiveTestCheckRPCStatus(t *testing.T) { +// Live_TestCheckRPCStatus checks the RPC status of the Bitcoin chain +func LiveTest_CheckRPCStatus(t *testing.T) { // setup Bitcoin client chainID := chains.BitcoinMainnet.ChainId client, err := createRPCClient(chainID) @@ -270,7 +234,7 @@ func LiveTestCheckRPCStatus(t *testing.T) { } // LiveTestGetBlockHeightByHash queries Bitcoin block height by hash -func LiveTestGetBlockHeightByHash(t *testing.T) { +func LiveTest_GetBlockHeightByHash(t *testing.T) { // setup Bitcoin client client, err := createRPCClient(chains.BitcoinMainnet.ChainId) require.NoError(t, err) @@ -292,7 +256,7 @@ func LiveTestGetBlockHeightByHash(t *testing.T) { // LiveTestBitcoinFeeRate query Bitcoin mainnet fee rate every 5 minutes // and compares Conservative and Economical fee rates for different block targets (1 and 2) -func LiveTestBitcoinFeeRate(t *testing.T) { +func LiveTest_BitcoinFeeRate(t *testing.T) { // setup Bitcoin client client, err := createRPCClient(chains.BitcoinMainnet.ChainId) require.NoError(t, err) @@ -419,7 +383,7 @@ func compareAvgFeeRate(t *testing.T, client *rpcclient.Client, startBlock int, e } // LiveTestAvgFeeRateMainnetMempoolSpace compares calculated fee rate with mempool.space fee rate for mainnet -func LiveTestAvgFeeRateMainnetMempoolSpace(t *testing.T) { +func LiveTest_AvgFeeRateMainnetMempoolSpace(t *testing.T) { // setup Bitcoin client client, err := createRPCClient(chains.BitcoinMainnet.ChainId) require.NoError(t, err) @@ -433,7 +397,7 @@ func LiveTestAvgFeeRateMainnetMempoolSpace(t *testing.T) { } // LiveTestAvgFeeRateTestnetMempoolSpace compares calculated fee rate with mempool.space fee rate for testnet -func LiveTestAvgFeeRateTestnetMempoolSpace(t *testing.T) { +func LiveTest_AvgFeeRateTestnetMempoolSpace(t *testing.T) { // setup Bitcoin client client, err := createRPCClient(chains.BitcoinTestnet.ChainId) require.NoError(t, err) @@ -447,19 +411,19 @@ func LiveTestAvgFeeRateTestnetMempoolSpace(t *testing.T) { } // LiveTestGetRecentFeeRate gets the highest fee rate from recent blocks -func LiveTestGetRecentFeeRate(t *testing.T) { +func LiveTest_GetRecentFeeRate(t *testing.T) { // setup Bitcoin testnet client client, err := createRPCClient(chains.BitcoinTestnet.ChainId) require.NoError(t, err) // get fee rate from recent blocks - feeRate, err := rpc.GetRecentFeeRate(client, &chaincfg.TestNet3Params) + feeRate, err := bitcoin.GetRecentFeeRate(client, &chaincfg.TestNet3Params) require.NoError(t, err) require.Greater(t, feeRate, uint64(0)) } -// LiveTestGetSenderByVin gets sender address for each vin and compares with mempool.space sender address -func LiveTestGetSenderByVin(t *testing.T) { +// LiveTest_GetSenderByVin gets sender address for each vin and compares with mempool.space sender address +func LiveTest_GetSenderByVin(t *testing.T) { // setup Bitcoin client chainID := chains.BitcoinMainnet.ChainId client, err := createRPCClient(chainID) @@ -478,22 +442,13 @@ func LiveTestGetSenderByVin(t *testing.T) { require.NoError(t, err) endBlock := startBlock - 1 // go back to whatever block as needed - // loop through mempool.space blocks in descending order + // loop through mempool.space blocks backwards BLOCKLOOP: for bn := startBlock; bn >= endBlock; { - // get block hash - blkHash, err := client.GetBlockHash(int64(bn)) - if err != nil { - fmt.Printf("error GetBlockHash for block %d: %s\n", bn, err) - time.Sleep(3 * time.Second) - continue - } - // get mempool.space txs for the block - mempoolTxs, err := testutils.GetBlockTxs(context.Background(), blkHash.String(), testnet) + _, mempoolTxs, err := getMempoolSpaceTxsByBlock(t, client, bn, testnet) if err != nil { - fmt.Printf("error GetBlockTxs %d: %s\n", bn, err) - time.Sleep(10 * time.Second) + time.Sleep(3 * time.Second) continue } @@ -527,6 +482,135 @@ BLOCKLOOP: } } bn-- - time.Sleep(500 * time.Millisecond) + time.Sleep(100 * time.Millisecond) + } +} + +// LiveTestGetTransactionFeeAndRate gets the transaction fee and rate for each tx and compares with mempool.space fee rate +func LiveTest_GetTransactionFeeAndRate(t *testing.T) { + // setup Bitcoin client + chainID := chains.BitcoinTestnet.ChainId + client, err := createRPCClient(chainID) + require.NoError(t, err) + + // testnet or mainnet + testnet := false + if chainID == chains.BitcoinTestnet.ChainId { + testnet = true + } + + // calculates block range to test + startBlock, err := client.GetBlockCount() + require.NoError(t, err) + endBlock := startBlock - 100 // go back whatever blocks as needed + + // loop through mempool.space blocks backwards + for bn := startBlock; bn >= endBlock; { + // get mempool.space txs for the block + blkHash, mempoolTxs, err := getMempoolSpaceTxsByBlock(t, client, bn, testnet) + if err != nil { + time.Sleep(3 * time.Second) + continue + } + + // get the block from rpc client + block, err := client.GetBlockVerboseTx(blkHash) + if err != nil { + time.Sleep(3 * time.Second) + continue + } + + // loop through each tx in the block (skip coinbase tx) + for i := 1; i < len(block.Tx); { + // sample 20 txs per block + if i >= 20 { + break + } + + // the two txs from two different sources + tx := block.Tx[i] + mpTx := mempoolTxs[i] + require.Equal(t, tx.Txid, mpTx.TxID) + + // get transaction fee rate for the raw result + fee, feeRate, err := rpc.GetTransactionFeeAndRate(client, &tx) + if err != nil { + t.Logf("error GetTransactionFeeRate %s: %s\n", mpTx.TxID, err) + continue + } + require.EqualValues(t, mpTx.Fee, fee) + require.EqualValues(t, mpTx.Weight, tx.Weight) + + // calculate mempool.space fee rate + vBytes := mpTx.Weight / blockchain.WitnessScaleFactor + mpFeeRate := int64(mpTx.Fee / vBytes) + + // compare our fee rate with mempool.space fee rate + var diff int64 + var diffPercent float64 + if feeRate == mpFeeRate { + fmt.Printf("tx %s: [our rate] %5d == %5d [mempool.space]", mpTx.TxID, feeRate, mpFeeRate) + } else if feeRate > mpFeeRate { + diff = feeRate - mpFeeRate + fmt.Printf("tx %s: [our rate] %5d > %5d [mempool.space]", mpTx.TxID, feeRate, mpFeeRate) + } else { + diff = mpFeeRate - feeRate + fmt.Printf("tx %s: [our rate] %5d < %5d [mempool.space]", mpTx.TxID, feeRate, mpFeeRate) + } + + // print the diff percentage + diffPercent = float64(diff) / float64(mpFeeRate) * 100 + if diff > 0 { + fmt.Printf(", diff: %f%%\n", diffPercent) + } else { + fmt.Printf("\n") + } + + // the expected diff percentage should be within 5% + if mpFeeRate >= 20 { + require.LessOrEqual(t, diffPercent, 5.0) + } else { + // for small fee rate, the absolute diff should be within 1 satoshi/vByte + require.LessOrEqual(t, diff, int64(1)) + } + + // next tx + i++ + } + + bn-- + time.Sleep(100 * time.Millisecond) } } + +func LiveTest_CalcDepositorFeeV2(t *testing.T) { + // setup Bitcoin client + client, err := createRPCClient(chains.BitcoinMainnet.ChainId) + require.NoError(t, err) + + // test tx hash + // https://mempool.space/tx/8dc0d51f83810cec7fcb5b194caebfc5fc64b10f9fe21845dfecc621d2a28538 + hash, err := chainhash.NewHashFromStr("8dc0d51f83810cec7fcb5b194caebfc5fc64b10f9fe21845dfecc621d2a28538") + require.NoError(t, err) + + // get the raw transaction result + rawResult, err := client.GetRawTransactionVerbose(hash) + require.NoError(t, err) + + t.Run("should return default depositor fee", func(t *testing.T) { + depositorFee, err := bitcoin.CalcDepositorFeeV2(client, rawResult, &chaincfg.RegressionNetParams) + require.NoError(t, err) + require.Equal(t, bitcoin.DefaultDepositorFee, depositorFee) + }) + + t.Run("should return correct depositor fee for a given tx", func(t *testing.T) { + depositorFee, err := bitcoin.CalcDepositorFeeV2(client, rawResult, &chaincfg.MainNetParams) + require.NoError(t, err) + + // the actual fee rate is 860 sat/vByte + // #nosec G115 always in range + expectedRate := int64(float64(860) * common.BTCOutboundGasPriceMultiplier) + expectedFee := bitcoin.DepositorFee(expectedRate) + require.Equal(t, expectedFee, depositorFee) + }) +} diff --git a/zetaclient/chains/interfaces/interfaces.go b/zetaclient/chains/interfaces/interfaces.go index 15e9c395bd..75ac50b2ce 100644 --- a/zetaclient/chains/interfaces/interfaces.go +++ b/zetaclient/chains/interfaces/interfaces.go @@ -201,7 +201,7 @@ type SolanaRPCClient interface { account solana.PublicKey, commitment solrpc.CommitmentType, ) (*solrpc.GetBalanceResult, error) - GetRecentBlockhash(ctx context.Context, commitment solrpc.CommitmentType) (*solrpc.GetRecentBlockhashResult, error) + GetLatestBlockhash(ctx context.Context, commitment solrpc.CommitmentType) (*solrpc.GetLatestBlockhashResult, error) GetRecentPrioritizationFees( ctx context.Context, accounts solana.PublicKeySlice, diff --git a/zetaclient/chains/solana/observer/inbound.go b/zetaclient/chains/solana/observer/inbound.go index cf05f94cf9..ef459cbd7a 100644 --- a/zetaclient/chains/solana/observer/inbound.go +++ b/zetaclient/chains/solana/observer/inbound.go @@ -68,7 +68,7 @@ func (ob *Observer) WatchInbound(ctx context.Context) error { } } -// ObserveInbound observes the Bitcoin chain for inbounds and post votes to zetacore. +// ObserveInbound observes the Solana chain for inbounds and post votes to zetacore. func (ob *Observer) ObserveInbound(ctx context.Context) error { chainID := ob.Chain().ChainId pageLimit := solanarpc.DefaultPageLimit diff --git a/zetaclient/chains/solana/signer/signer.go b/zetaclient/chains/solana/signer/signer.go index 41c4c3efdd..2b766a49f5 100644 --- a/zetaclient/chains/solana/signer/signer.go +++ b/zetaclient/chains/solana/signer/signer.go @@ -23,7 +23,7 @@ import ( var _ interfaces.ChainSigner = (*Signer)(nil) -// Signer deals with signing BTC transactions and implements the ChainSigner interface +// Signer deals with signing Solana transactions and implements the ChainSigner interface type Signer struct { *base.Signer @@ -41,7 +41,7 @@ type Signer struct { pda solana.PublicKey } -// NewSigner creates a new Bitcoin signer +// NewSigner creates a new Solana signer func NewSigner( chain chains.Chain, chainParams observertypes.ChainParams, diff --git a/zetaclient/chains/solana/signer/withdraw.go b/zetaclient/chains/solana/signer/withdraw.go index f44dc3fc30..8b91dc8f23 100644 --- a/zetaclient/chains/solana/signer/withdraw.go +++ b/zetaclient/chains/solana/signer/withdraw.go @@ -69,9 +69,9 @@ func (signer *Signer) SignWithdrawTx(ctx context.Context, msg contracts.MsgWithd attachWithdrawAccounts(&inst, privkey.PublicKey(), signer.pda, msg.To(), signer.gatewayID) // get a recent blockhash - recent, err := signer.client.GetRecentBlockhash(ctx, rpc.CommitmentFinalized) + recent, err := signer.client.GetLatestBlockhash(ctx, rpc.CommitmentFinalized) if err != nil { - return nil, errors.Wrap(err, "GetRecentBlockhash error") + return nil, errors.Wrap(err, "GetLatestBlockhash error") } // create a transaction that wraps the instruction diff --git a/zetaclient/testutils/mocks/solana_rpc.go b/zetaclient/testutils/mocks/solana_rpc.go index 6c4d2829e3..b6333ff744 100644 --- a/zetaclient/testutils/mocks/solana_rpc.go +++ b/zetaclient/testutils/mocks/solana_rpc.go @@ -165,24 +165,24 @@ func (_m *SolanaRPCClient) GetHealth(ctx context.Context) (string, error) { return r0, r1 } -// GetRecentBlockhash provides a mock function with given fields: ctx, commitment -func (_m *SolanaRPCClient) GetRecentBlockhash(ctx context.Context, commitment rpc.CommitmentType) (*rpc.GetRecentBlockhashResult, error) { +// GetLatestBlockhash provides a mock function with given fields: ctx, commitment +func (_m *SolanaRPCClient) GetLatestBlockhash(ctx context.Context, commitment rpc.CommitmentType) (*rpc.GetLatestBlockhashResult, error) { ret := _m.Called(ctx, commitment) if len(ret) == 0 { - panic("no return value specified for GetRecentBlockhash") + panic("no return value specified for GetLatestBlockhash") } - var r0 *rpc.GetRecentBlockhashResult + var r0 *rpc.GetLatestBlockhashResult var r1 error - if rf, ok := ret.Get(0).(func(context.Context, rpc.CommitmentType) (*rpc.GetRecentBlockhashResult, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, rpc.CommitmentType) (*rpc.GetLatestBlockhashResult, error)); ok { return rf(ctx, commitment) } - if rf, ok := ret.Get(0).(func(context.Context, rpc.CommitmentType) *rpc.GetRecentBlockhashResult); ok { + if rf, ok := ret.Get(0).(func(context.Context, rpc.CommitmentType) *rpc.GetLatestBlockhashResult); ok { r0 = rf(ctx, commitment) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*rpc.GetRecentBlockhashResult) + r0 = ret.Get(0).(*rpc.GetLatestBlockhashResult) } } diff --git a/zetaclient/zetacore/broadcast_test.go b/zetaclient/zetacore/broadcast_test.go index 6acd5c535f..80299c7ba5 100644 --- a/zetaclient/zetacore/broadcast_test.go +++ b/zetaclient/zetacore/broadcast_test.go @@ -9,8 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/stretchr/testify/require" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" "go.nhat.io/grpcmock" "go.nhat.io/grpcmock/planner" diff --git a/zetaclient/zetacore/client.go b/zetaclient/zetacore/client.go index c7149dd95f..dc5a888678 100644 --- a/zetaclient/zetacore/client.go +++ b/zetaclient/zetacore/client.go @@ -8,25 +8,19 @@ import ( "sync" "time" - "cosmossdk.io/simapp/params" rpchttp "github.com/cometbft/cometbft/rpc/client/http" cosmosclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/pkg/errors" "github.com/rs/zerolog" + etherminttypes "github.com/zeta-chain/ethermint/types" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/zeta-chain/zetacore/app" "github.com/zeta-chain/zetacore/pkg/authz" "github.com/zeta-chain/zetacore/pkg/chains" - authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" - crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" - lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + zetacore_rpc "github.com/zeta-chain/zetacore/pkg/rpc" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/config" @@ -38,17 +32,18 @@ var _ interfaces.ZetacoreClient = &Client{} // Client is the client to send tx to zetacore type Client struct { + zetacore_rpc.Clients + logger zerolog.Logger config config.ClientConfiguration - client clients cosmosClientContext cosmosclient.Context blockHeight int64 accountNumber map[authz.KeyType]uint64 seqNumber map[authz.KeyType]uint64 - encodingCfg params.EncodingConfig + encodingCfg etherminttypes.EncodingConfig keys keyinterfaces.ObserverKeys chainID string chain chains.Chain @@ -58,17 +53,6 @@ type Client struct { mu sync.RWMutex } -type clients struct { - observer observertypes.QueryClient - light lightclienttypes.QueryClient - crosschain crosschaintypes.QueryClient - bank banktypes.QueryClient - upgrade upgradetypes.QueryClient - fees feemarkettypes.QueryClient - authority authoritytypes.QueryClient - tendermint tmservice.ServiceClient -} - var unsecureGRPC = grpc.WithTransportCredentials(insecure.NewCredentials()) type constructOpts struct { @@ -129,7 +113,7 @@ func NewClient( encodingCfg := app.MakeEncodingConfig() - grpcConn, err := grpc.Dial(cosmosGRPC(chainIP), unsecureGRPC) + zetacoreClients, err := zetacore_rpc.NewGRPCClients(cosmosGRPC(chainIP), unsecureGRPC) if err != nil { return nil, errors.Wrap(err, "grpc dial fail") } @@ -147,20 +131,11 @@ func NewClient( } return &Client{ - logger: log, - config: cfg, + Clients: zetacoreClients, + logger: log, + config: cfg, cosmosClientContext: cosmosContext, - client: clients{ - observer: observertypes.NewQueryClient(grpcConn), - light: lightclienttypes.NewQueryClient(grpcConn), - crosschain: crosschaintypes.NewQueryClient(grpcConn), - bank: banktypes.NewQueryClient(grpcConn), - upgrade: upgradetypes.NewQueryClient(grpcConn), - fees: feemarkettypes.NewQueryClient(grpcConn), - authority: authoritytypes.NewQueryClient(grpcConn), - tendermint: tmservice.NewServiceClient(grpcConn), - }, accountNumber: accountsMap, seqNumber: seqMap, @@ -178,7 +153,7 @@ func buildCosmosClientContext( chainID string, keys keyinterfaces.ObserverKeys, config config.ClientConfiguration, - encodingConfig params.EncodingConfig, + encodingConfig etherminttypes.EncodingConfig, opts constructOpts, ) (cosmosclient.Context, error) { if keys == nil { diff --git a/zetaclient/zetacore/client_query_cosmos.go b/zetaclient/zetacore/client_cosmos.go similarity index 64% rename from zetaclient/zetacore/client_query_cosmos.go rename to zetaclient/zetacore/client_cosmos.go index 61d690d54a..815615c3bd 100644 --- a/zetaclient/zetacore/client_query_cosmos.go +++ b/zetaclient/zetacore/client_cosmos.go @@ -8,7 +8,6 @@ import ( tmhttp "github.com/cometbft/cometbft/rpc/client/http" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/pkg/errors" "github.com/zeta-chain/zetacore/cmd/zetacored/config" @@ -42,31 +41,6 @@ func (c *Client) GetGenesisSupply(ctx context.Context) (sdkmath.Int, error) { return bankstate.Supply.AmountOf(config.BaseDenom), nil } -// GetUpgradePlan returns the current upgrade plan. -// if there is no active upgrade plan, plan will be nil, err will be nil as well. -func (c *Client) GetUpgradePlan(ctx context.Context) (*upgradetypes.Plan, error) { - in := &upgradetypes.QueryCurrentPlanRequest{} - - resp, err := c.client.upgrade.CurrentPlan(ctx, in) - if err != nil { - return nil, errors.Wrap(err, "failed to get current upgrade plan") - } - - return resp.Plan, nil -} - -// GetZetaTokenSupplyOnNode returns the zeta token supply on the node -func (c *Client) GetZetaTokenSupplyOnNode(ctx context.Context) (sdkmath.Int, error) { - in := &banktypes.QuerySupplyOfRequest{Denom: config.BaseDenom} - - resp, err := c.client.bank.SupplyOf(ctx, in) - if err != nil { - return sdkmath.ZeroInt(), errors.Wrap(err, "failed to get zeta token supply") - } - - return resp.GetAmount().Amount, nil -} - // GetZetaHotKeyBalance returns the zeta hot key balance func (c *Client) GetZetaHotKeyBalance(ctx context.Context) (sdkmath.Int, error) { address, err := c.keys.GetAddress() @@ -79,7 +53,7 @@ func (c *Client) GetZetaHotKeyBalance(ctx context.Context) (sdkmath.Int, error) Denom: config.BaseDenom, } - resp, err := c.client.bank.Balance(ctx, in) + resp, err := c.Clients.Bank.Balance(ctx, in) if err != nil { return sdkmath.ZeroInt(), errors.Wrap(err, "failed to get zeta hot key balance") } diff --git a/zetaclient/zetacore/client_test.go b/zetaclient/zetacore/client_test.go new file mode 100644 index 0000000000..723f29084d --- /dev/null +++ b/zetaclient/zetacore/client_test.go @@ -0,0 +1,191 @@ +package zetacore + +import ( + "context" + "net" + "testing" + + abci "github.com/cometbft/cometbft/abci/types" + cosmosclient "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/testutil/mock" + "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/golang/mock/gomock" + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + feemarkettypes "github.com/zeta-chain/ethermint/x/feemarket/types" + keyinterfaces "github.com/zeta-chain/zetacore/zetaclient/keys/interfaces" + "go.nhat.io/grpcmock" + "go.nhat.io/grpcmock/planner" + + "github.com/zeta-chain/zetacore/cmd/zetacored/config" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + "github.com/zeta-chain/zetacore/zetaclient/keys" + "github.com/zeta-chain/zetacore/zetaclient/testutils/mocks" +) + +const skipMethod = "skip" + +// setupMockServer setup mock zetacore GRPC server +func setupMockServer( + t *testing.T, + serviceFunc any, method string, input any, expectedOutput any, + extra ...grpcmock.ServerOption, +) *grpcmock.Server { + listener, err := net.Listen("tcp", "127.0.0.1:9090") + require.NoError(t, err) + + opts := []grpcmock.ServerOption{ + grpcmock.RegisterService(serviceFunc), + grpcmock.WithPlanner(planner.FirstMatch()), + grpcmock.WithListener(listener), + } + + opts = append(opts, extra...) + + if method != skipMethod { + opts = append(opts, func(s *grpcmock.Server) { + s.ExpectUnary(method). + UnlimitedTimes(). + WithPayload(input). + Return(expectedOutput) + }) + } + + server := grpcmock.MockUnstartedServer(opts...)(t) + + server.Serve() + + t.Cleanup(func() { + require.NoError(t, server.Close()) + }) + + return server +} + +func withDummyServer(zetaBlockHeight int64) []grpcmock.ServerOption { + return []grpcmock.ServerOption{ + grpcmock.RegisterService(crosschaintypes.RegisterQueryServer), + grpcmock.RegisterService(crosschaintypes.RegisterMsgServer), + grpcmock.RegisterService(feemarkettypes.RegisterQueryServer), + grpcmock.RegisterService(authtypes.RegisterQueryServer), + grpcmock.RegisterService(abci.RegisterABCIApplicationServer), + func(s *grpcmock.Server) { + // Block Height + s.ExpectUnary("/zetachain.zetacore.crosschain.Query/LastZetaHeight"). + UnlimitedTimes(). + Return(crosschaintypes.QueryLastZetaHeightResponse{Height: zetaBlockHeight}) + + // London Base Fee + s.ExpectUnary("/ethermint.feemarket.v1.Query/Params"). + UnlimitedTimes(). + Return(feemarkettypes.QueryParamsResponse{ + Params: feemarkettypes.Params{BaseFee: types.NewInt(100)}, + }) + }, + } +} + +type clientTestConfig struct { + keys keyinterfaces.ObserverKeys + opts []Opt +} + +type clientTestOpt func(*clientTestConfig) + +func withObserverKeys(keys keyinterfaces.ObserverKeys) clientTestOpt { + return func(cfg *clientTestConfig) { cfg.keys = keys } +} + +func withDefaultObserverKeys() clientTestOpt { + var ( + key = mocks.TestKeyringPair + address = types.AccAddress(key.PubKey().Address().Bytes()) + keyRing = mocks.NewKeyring() + ) + + return withObserverKeys(keys.NewKeysWithKeybase(keyRing, address, testSigner, "")) +} + +func withTendermint(client cosmosclient.TendermintRPC) clientTestOpt { + return func(cfg *clientTestConfig) { cfg.opts = append(cfg.opts, WithTendermintClient(client)) } +} + +func withAccountRetriever(t *testing.T, accNum uint64, accSeq uint64) clientTestOpt { + ctrl := gomock.NewController(t) + ac := mock.NewMockAccountRetriever(ctrl) + ac.EXPECT(). + GetAccountNumberSequence(gomock.Any(), gomock.Any()). + AnyTimes(). + Return(accNum, accSeq, nil) + + return func(cfg *clientTestConfig) { + cfg.opts = append(cfg.opts, WithCustomAccountRetriever(ac)) + } +} + +func setupZetacoreClient(t *testing.T, opts ...clientTestOpt) *Client { + const ( + chainIP = "127.0.0.1" + signer = testSigner + chainID = "zetachain_7000-1" + ) + + var cfg clientTestConfig + for _, opt := range opts { + opt(&cfg) + } + + if cfg.keys == nil { + cfg.keys = &keys.Keys{} + } + + c, err := NewClient( + cfg.keys, + chainIP, signer, + chainID, + false, + zerolog.Nop(), + cfg.opts..., + ) + + require.NoError(t, err) + + return c +} + +// Need to test after refactor +func TestZetacore_GetGenesisSupply(t *testing.T) { +} + +func TestZetacore_GetZetaHotKeyBalance(t *testing.T) { + ctx := context.Background() + + expectedOutput := banktypes.QueryBalanceResponse{ + Balance: &types.Coin{ + Denom: config.BaseDenom, + Amount: types.NewInt(55646484), + }, + } + input := banktypes.QueryBalanceRequest{ + Address: types.AccAddress(mocks.TestKeyringPair.PubKey().Address().Bytes()).String(), + Denom: config.BaseDenom, + } + method := "/cosmos.bank.v1beta1.Query/Balance" + setupMockServer(t, banktypes.RegisterQueryServer, method, input, expectedOutput) + + client := setupZetacoreClient(t, withDefaultObserverKeys()) + + // should be able to get balance of signer + client.keys = keys.NewKeysWithKeybase(mocks.NewKeyring(), types.AccAddress{}, "bob", "") + resp, err := client.GetZetaHotKeyBalance(ctx) + require.NoError(t, err) + require.Equal(t, expectedOutput.Balance.Amount, resp) + + // should return error on empty signer + client.keys = keys.NewKeysWithKeybase(mocks.NewKeyring(), types.AccAddress{}, "", "") + resp, err = client.GetZetaHotKeyBalance(ctx) + require.Error(t, err) + require.Equal(t, types.ZeroInt(), resp) +}