diff --git a/AGENTS.md b/AGENTS.md index fc39927..a01acae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ VAAS (Validator-as-a-Service) is a simplified Interchain Security (ICS) implementation for Cosmos blockchains, derived from [interchain-security](https://github.com/cosmos/interchain-security). It lets a provider chain lease its proof-of-stake security to consumer chains via automatic validator synchronization. All active validators validate all consumers — no opt-in/opt-out. -Supports both IBC v1 (channel-based, ordered) and IBC v2/Eureka (client-based, out-of-order). IBC v2 uses application IDs `vaas/provider` and `vaas/consumer` instead of port IDs. +Supports both IBC v1 (channel-based, ordered) and IBC v2 (client-based, out-of-order). IBC v2 uses application IDs `vaas/provider` and `vaas/consumer` instead of port IDs. ## Build & Test Commands @@ -48,6 +48,7 @@ The core protocol lives in `x/vaas/` with two symmetric modules: Each module has: `keeper/` (business logic + state), `types/` (data structures + params), `client/cli/` (CLI commands), `module.go`, `ibc_module.go` (v1 callbacks), `ibc_module_v2.go` (v2 callbacks). Two helper modules replace standard Cosmos modules to prevent automatic validator set updates on consumer chains: + - `x/vaas/no_valupdates_staking/` — staking without EndBlock valset exports - `x/vaas/no_valupdates_genutil/` — genutil without gentx-based valset init @@ -89,6 +90,7 @@ Under `proto/vaas/`: `v1/` (shared wire types like `ValidatorSetChangePacketData ## Lint / Import Ordering Import groups (enforced by gci in `.golangci.yml`): + 1. Standard library 2. Third-party 3. `github.com/cometbft/cometbft` diff --git a/Makefile b/Makefile index 6f3ed16..46922ea 100644 --- a/Makefile +++ b/Makefile @@ -78,9 +78,9 @@ provider-start: build-apps $(providerd) config set client chain-id provider-localnet $(providerd) config set client keyring-backend test $(providerd) keys add val - $(providerd) genesis add-genesis-account val 1000000000000uatone + $(providerd) genesis add-genesis-account val 1000000000000uatone $(providerd) keys add user - $(providerd) genesis add-genesis-account user 1000000000uatone + $(providerd) genesis add-genesis-account user 1000000000uatone $(providerd) genesis gentx val 1000000000uatone $(providerd) genesis collect-gentxs @@ -170,63 +170,45 @@ consumer-start: consumer-init consumer-create .PHONY: consumer-init consumer-create consumer-genesis consumer-run consumer-start ############################################################################### -### Relayer ### +### TS Relayer ### ############################################################################### -HERMES ?= ./hermes -HERMES_CONFIG ?= $(HOME)/.vaas-hermes/config.toml +TS_RELAYER ?= ghcr.io/allinbits/ibc-v2-ts-relayer:latest -HERMES_CMD = $(HERMES) --config $(HERMES_CONFIG) - -# Create Hermes configuration -relayer-config: - @chmod +x ./scripts/hermes-config.sh - @./scripts/hermes-config.sh - -# Create relayer keys and fund them (requires both chains running) -RELAYER_MNEMONIC_FILE = /tmp/vaas-test/relayer_mnemonic.txt - -relayer-keys: - @echo "Creating relayer mnemonic file..." - @mkdir -p /tmp/vaas-test - @echo "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" > $(RELAYER_MNEMONIC_FILE) - @echo "Setting up relayer account on provider..." - @chmod +x ./scripts/add-relayer-key.sh - @./scripts/add-relayer-key.sh ./build/provider $(provider_home) - @echo "Funding relayer on provider..." - $(providerd) tx bank send val $$($(providerd) keys show relayer -a) 100000000uatone --fees 5000uatone -y - @echo "Waiting for provider tx..." - @sleep 5 - @echo "Removing old Hermes keys if they exist..." - @rm -rf $(HOME)/.vaas-hermes/keys - @echo "Adding relayer key to Hermes for provider..." - $(HERMES_CMD) keys add --chain provider-localnet --mnemonic-file $(RELAYER_MNEMONIC_FILE) --key-name relayer - @echo "Adding relayer key to Hermes for consumer..." - $(HERMES_CMD) keys add --chain consumer-localnet --mnemonic-file $(RELAYER_MNEMONIC_FILE) --key-name relayer - @echo "Relayer keys setup complete" - @echo "Relayer address: $$($(providerd) keys show relayer -a)" - -# Create the CCV/VAAS channel between provider and consumer -# IMPORTANT: Must use genesis clients (07-tendermint-0) for VAAS channel -# After a fresh localnet-clean, this will create connection-0 -relayer-channel: - @echo "Creating connection using genesis clients (07-tendermint-0)..." - $(HERMES_CMD) create connection --a-chain consumer-localnet --a-client 07-tendermint-0 --b-client 07-tendermint-0 - @sleep 2 - @echo "Creating VAAS channel on connection-0..." - $(HERMES_CMD) create channel --a-chain consumer-localnet --a-connection connection-0 --a-port consumer --b-port provider --order ordered --channel-version 1 - @echo "Channel created" - -# Start the relayer -relayer-start: - @echo "Starting Hermes relayer..." - $(HERMES_CMD) start +ts-relayer-start: + @echo "Starting ts-relayer..." + @docker rm -f vaas-ts-relayer 2>/dev/null || true + @docker run -d --name vaas-ts-relayer --network host \ + --cap-add IPC_LOCK \ + $(TS_RELAYER) + @sleep 3 + @echo "Configuring ts-relayer..." + @docker exec vaas-ts-relayer /bin/with_keyring ibc-v2-ts-relayer add-mnemonic \ + -c provider-localnet \ + --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" + @docker exec vaas-ts-relayer /bin/with_keyring ibc-v2-ts-relayer add-mnemonic \ + -c consumer-localnet \ + --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" + @docker exec vaas-ts-relayer /bin/with_keyring ibc-v2-ts-relayer add-gas-price \ + -c provider-localnet --gas-adjustment 2.0 0.025uatone + @docker exec vaas-ts-relayer /bin/with_keyring ibc-v2-ts-relayer add-gas-price \ + -c consumer-localnet --gas-adjustment 2.0 0.025uatone + @echo "Creating IBC v2 path..." + @docker exec vaas-ts-relayer /bin/with_keyring ibc-v2-ts-relayer add-path \ + -s provider-localnet \ + -d consumer-localnet \ + --surl http://127.0.0.1:26657 \ + --durl http://127.0.0.1:26667 \ + --ibc-version 2 + @echo "ts-relayer configured and running (log: /tmp/vaas-ts-relayer.log)" + +ts-relayer-stop: + @echo "Stopping ts-relayer..." + -@docker rm -f vaas-ts-relayer 2>/dev/null || true + +.PHONY: ts-relayer-start ts-relayer-stop -# Full relayer setup (requires both chains running) -relayer-setup: relayer-config relayer-keys relayer-channel - @echo "Relayer setup complete. Run 'make relayer-start' to start relaying." -.PHONY: relayer-install relayer-config relayer-keys relayer-channel relayer-start relayer-setup ############################################################################### ### Full Localnet ### @@ -237,21 +219,20 @@ localnet-clean: @echo "Stopping running processes..." -@pkill -f "provider.*start" 2>/dev/null || true -@pkill -f "consumer.*start" 2>/dev/null || true - -@pkill -f hermes 2>/dev/null || true + @$(MAKE) ts-relayer-stop @sleep 2 rm -rf $(provider_home) $(consumer_home) - rm -rf $(HOME)/.vaas-hermes - rm -f /tmp/vaas-provider.log /tmp/vaas-consumer.log /tmp/vaas-hermes.log + rm -f /tmp/vaas-provider.log /tmp/vaas-consumer.log /tmp/vaas-ts-relayer.log rm -rf /tmp/vaas-test @echo "Localnet data cleaned" -# Start the full localnet: provider, consumer, relayer — all in one command +# Start the full localnet: provider, consumer, and ts-relayer localnet-start: build-apps @echo "=== Starting VAAS Localnet ===" @echo "" - @echo "Step 1/6: Starting provider chain in background..." + @echo "Step 1/4: Starting provider chain in background..." @$(MAKE) provider-start > /tmp/vaas-provider.log 2>&1 & - @echo " Waiting for provider to produce blocks (http://localhost:26657) ..." + @echo " Waiting for provider to produce blocks..." @for i in $$(seq 1 60); do \ HEIGHT=$$(curl -sf http://localhost:26657/status 2>/dev/null | sed -n 's/.*"latest_block_height":"\([0-9]*\)".*/\1/p'); \ if [ -n "$$HEIGHT" ] && [ "$$HEIGHT" -gt 0 ] 2>/dev/null; then \ @@ -265,9 +246,9 @@ localnet-start: build-apps sleep 2; \ done @echo "" - @echo "Step 2/6: Starting consumer chain in background..." + @echo "Step 2/4: Starting consumer chain in background..." @$(MAKE) consumer-start > /tmp/vaas-consumer.log 2>&1 & - @echo " Waiting for consumer to produce blocks (http://localhost:26667) ..." + @echo " Waiting for consumer to produce blocks..." @for i in $$(seq 1 90); do \ HEIGHT=$$(curl -sf http://localhost:26667/status 2>/dev/null | sed -n 's/.*"latest_block_height":"\([0-9]*\)".*/\1/p'); \ if [ -n "$$HEIGHT" ] && [ "$$HEIGHT" -gt 0 ] 2>/dev/null; then \ @@ -281,15 +262,10 @@ localnet-start: build-apps sleep 2; \ done @echo "" - @echo "Step 3/6: Configuring relayer..." - @if [ -x $(HERMES) ]; then echo " Found Hermes binary"; else echo " Could not find Hermes binary. Please follow app/README.md to install it." && $(MAKE) localnet-clean && exit 1; fi - @$(MAKE) relayer-setup > /tmp/vaas-hermes.log 2>&1 + @echo "Step 3/4: Starting ts-relayer..." + @$(MAKE) ts-relayer-start > /tmp/vaas-ts-relayer.log 2>&1 @echo "" - @echo "Step 4/6: Starting relayer in background..." - @$(MAKE) relayer-start >> /tmp/vaas-hermes.log 2>&1 & - @sleep 3 - @echo "" - @echo "Step 5/6: Triggering valset change to send first VSC packet..." + @echo "Step 4/4: Triggering valset change to send first VSC packet..." @VALOPER=$$($(providerd) keys show val --bech val -a 2> /dev/null); \ $(providerd) tx staking delegate $$VALOPER 1000000uatone --from user --fees 5000uatone -y > /dev/null 2>&1 @echo " Delegation sent. Waiting for VSC packet to be relayed..." @@ -309,7 +285,7 @@ localnet-start: build-apps @echo "" @echo " Provider: http://localhost:26657 (log: /tmp/vaas-provider.log)" @echo " Consumer: http://localhost:26667 (log: /tmp/vaas-consumer.log)" - @echo " Relayer: (log: /tmp/vaas-hermes.log)" + @echo " Relayer: ts-relayer container (log: /tmp/vaas-ts-relayer.log)" @echo "" @echo " To stop: make localnet-clean" @@ -324,17 +300,12 @@ docker-build-debug: @echo "Building VAAS e2e chain image..." docker build -t cosmos/vaas-e2e -f tests/e2e/docker/e2e.Dockerfile . -# Build the Hermes relayer Docker image -docker-build-hermes: - @echo "Building Hermes e2e image..." - cd tests/e2e/docker && docker build -t ghcr.io/cosmos/hermes-e2e:1.13.1 -f hermes.Dockerfile . - # Build all Docker images needed for e2e tests -docker-build-all: docker-build-debug docker-build-hermes +docker-build-all: docker-build-debug # Run the e2e integration test suite test-e2e: docker-build-all @echo "Running e2e tests..." - cd tests/e2e && go test -timeout=25m -v ./... + cd tests/e2e && go test -timeout=25m -v ./... --count=1 -.PHONY: docker-build-debug docker-build-hermes docker-build-all test-e2e +.PHONY: docker-build-debug docker-build-all test-e2e diff --git a/README.md b/README.md index c3a366a..425c09d 100644 --- a/README.md +++ b/README.md @@ -8,30 +8,48 @@ VAAS allows Cosmos blockchains to lease their proof-of-stake security to consume ## Features +## IBC v2 support + +The VAAS implementation supports IBC v2 only. +IBC v2 is easily wireable by adding the IBC router v2 in a ibc-go >= 10.x.y compatible chain. + ### Kept from ICS -| Feature | Description | -|---------|-------------| -| Consumer Lifecycle | Full lifecycle management (REGISTERED → INITIALIZED → LAUNCHED → STOPPED → DELETED) | -| Key Assignment | Validators can use different consensus keys per consumer chain | -| Per-Consumer Infraction Parameters | Customizable slash/jail parameters per consumer | -| VSC Packets | Validator set updates sent at epoch boundaries | -| Double Voting Evidence | Handle double voting evidence from consumers | -| Light Client Misbehavior | Detection and logging of misbehavior | -| Consumer Metadata | Name, description, metadata for chain discovery | -| Client/Connection Reuse | Reuse existing IBC client/connection when creating consumer | +| Feature | Description | +| ---------------------------------- | ----------------------------------------------------------------------------------- | +| Consumer Lifecycle | Full lifecycle management (REGISTERED → INITIALIZED → LAUNCHED → STOPPED → DELETED) | +| Key Assignment | Validators can use different consensus keys per consumer chain | +| Per-Consumer Infraction Parameters | Customizable slash/jail parameters per consumer | +| VSC Packets | Validator set updates sent at epoch boundaries | +| Double Voting Evidence | Handle double voting evidence from consumers | +| Light Client Misbehavior | Detection and logging of misbehavior | +| Consumer Metadata | Name, description, metadata for chain discovery | +| Client/Connection Reuse | Reuse existing IBC client when creating consumer | ### Removed from ICS -| Feature | Reason | -|---------|--------| -| Partial Set Security (PSS) | All validators validate all consumers | -| Top N / Opt-In Chains | No validator selection per consumer | -| Power Shaping | No caps, allowlists, denylists, priority lists | -| Consumer Reward Distribution | No cross-chain rewards | -| Slash Packet Throttling | Simplified slash handling | -| Per-Consumer Commission Rates | Validators use same commission as provider | -| Standalone-to-Consumer Changeover | Only new chains as consumers | +| Feature | Reason | +| --------------------------------- | ---------------------------------------------- | +| Partial Set Security (PSS) | All validators validate all consumers | +| Top N / Opt-In Chains | No validator selection per consumer | +| Power Shaping | No caps, allowlists, denylists, priority lists | +| Consumer Reward Distribution | No cross-chain rewards | +| Slash Packet Throttling | Simplified slash handling | +| Per-Consumer Commission Rates | Validators use same commission as provider | +| IBC v1 Channel Support | IBC v2 only | +| Standalone-to-Consumer Changeover | Only new chains as consumers | + +## Build & Test + +```bash +make build # go build ./... +make test # unit tests (excludes e2e) +make lint # golangci-lint + +# E2E (Docker-based, spins up provider + consumer + ts-relayer) +make docker-build-all +make test-e2e +``` ## Learn More diff --git a/app/consumer/ante/msg_filter_ante.go b/app/consumer/ante/msg_filter_ante.go index f955bee..22b8a4c 100644 --- a/app/consumer/ante/msg_filter_ante.go +++ b/app/consumer/ante/msg_filter_ante.go @@ -11,7 +11,7 @@ import ( type ( // ConsumerKeeper defines the interface required by a consumer module keeper. ConsumerKeeper interface { - GetProviderChannel(ctx context.Context) (string, bool) + GetProviderClientID(ctx context.Context) (string, bool) } // MsgFilterDecorator defines an AnteHandler decorator that enables message @@ -32,7 +32,7 @@ func (mfd MsgFilterDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo // If the CCV channel has not yet been established, then we must only allow certain // message types. - if _, ok := mfd.ConsumerKeeper.GetProviderChannel(ctx); !ok { + if _, ok := mfd.ConsumerKeeper.GetProviderClientID(ctx); !ok { if !hasValidMsgsPreCCV(tx.GetMsgs()) { return ctx, fmt.Errorf("tx contains unsupported message types at height %d", currHeight) } diff --git a/app/consumer/app.go b/app/consumer/app.go index 5f16930..b1c1af3 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -10,17 +10,19 @@ import ( dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/gogoproto/proto" "github.com/cosmos/ibc-go/v10/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v10/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + transferv2 "github.com/cosmos/ibc-go/v10/modules/apps/transfer/v2" ibc "github.com/cosmos/ibc-go/v10/modules/core" ibcconnectiontypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v10/testing" - "github.com/cosmos/gogoproto/proto" "github.com/spf13/cast" @@ -31,10 +33,10 @@ import ( "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/tx/signing" "cosmossdk.io/x/upgrade" upgradekeeper "cosmossdk.io/x/upgrade/keeper" upgradetypes "cosmossdk.io/x/upgrade/types" - "cosmossdk.io/x/tx/signing" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -82,8 +84,8 @@ import ( paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" "github.com/cosmos/cosmos-sdk/x/slashing" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" abci "github.com/cometbft/cometbft/abci/types" @@ -94,11 +96,10 @@ import ( ibcconsumerkeeper "github.com/allinbits/vaas/x/vaas/consumer/keeper" ibcconsumertypes "github.com/allinbits/vaas/x/vaas/consumer/types" vaastypes "github.com/allinbits/vaas/x/vaas/types" - ) const ( - AppName = "vaas-consumer" + AppName = "vaas-consumer" upgradeName = "vaas-v1-to-v2" ) @@ -134,8 +135,8 @@ var ( // module account permissions maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + authtypes.FeeCollectorName: nil, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, } ) @@ -161,14 +162,12 @@ type App struct { // nolint: golint memKeys map[string]*storetypes.MemoryStoreKey // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.Keeper SlashingKeeper slashingkeeper.Keeper - - UpgradeKeeper upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper + ParamsKeeper paramskeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly TransferKeeper ibctransferkeeper.Keeper ConsumerKeeper ibcconsumerkeeper.Keeper @@ -287,18 +286,6 @@ func New( logger, ) - // consumer keeper satisfies the staking keeper interface - // of the slashing module - app.SlashingKeeper = slashingkeeper.NewKeeper( - appCodec, - legacyAmino, - runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), - &app.ConsumerKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - // consumer keeper satisfies the staking keeper interface - // of the slashing module app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, @@ -307,8 +294,6 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - - // get skipUpgradeHeights from the app options skipUpgradeHeights := map[int64]bool{} for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { @@ -346,13 +331,11 @@ func New( app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( appCodec, runtime.NewKVStoreService(keys[ibcconsumertypes.StoreKey]), - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.ConnectionKeeper, app.IBCKeeper.ClientKeeper, + app.IBCKeeper.ClientV2Keeper, app.SlashingKeeper, app.BankKeeper, app.AccountKeeper, - app.IBCKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), @@ -380,9 +363,13 @@ func New( // create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() ibcRouter.AddRoute(ibctransfertypes.ModuleName, ibcmodule) - ibcRouter.AddRoute(vaastypes.ConsumerPortID, consumerModule) app.IBCKeeper.SetRouter(ibcRouter) + ibcRouterV2 := ibcapi.NewRouter() + ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + ibcRouterV2.AddRoute(vaastypes.ConsumerAppID, ibcconsumer.NewIBCModule(&app.ConsumerKeeper)) + app.IBCKeeper.SetRouterV2(ibcRouterV2) + tmLightClientModule := ibctm.NewLightClientModule(appCodec, app.IBCKeeper.ClientKeeper.GetStoreProvider()) app.IBCKeeper.ClientKeeper.AddRoute(ibctm.ModuleName, tmLightClientModule) @@ -728,7 +715,6 @@ func (app *App) GetStakingKeeper() *ibcconsumerkeeper.Keeper { return &app.ConsumerKeeper } - // GetIBCKeeper implements the TestingApp interface. func (app *App) GetIBCKeeper() *ibckeeper.Keeper { return app.IBCKeeper diff --git a/app/go.mod b/app/go.mod index 2eb62af..3e166aa 100644 --- a/app/go.mod +++ b/app/go.mod @@ -1,6 +1,6 @@ module github.com/allinbits/vaas/app -go 1.25.0 +go 1.26.0 replace ( cosmossdk.io/store => github.com/atomone-hub/cosmos-sdk/store v1.1.2-0.20260107105933-680c2b513b67 @@ -80,7 +80,7 @@ require ( github.com/bgentry/speakeasy v0.2.0 // indirect github.com/bits-and-blooms/bitset v1.22.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/app/provider/app.go b/app/provider/app.go index a59485d..5bbb229 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -13,9 +13,11 @@ import ( "github.com/cosmos/ibc-go/v10/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v10/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + transferv2 "github.com/cosmos/ibc-go/v10/modules/apps/transfer/v2" ibc "github.com/cosmos/ibc-go/v10/modules/core" ibcconnectiontypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcapi "github.com/cosmos/ibc-go/v10/modules/core/api" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" @@ -28,10 +30,10 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/tx/signing" "cosmossdk.io/x/upgrade" upgradekeeper "cosmossdk.io/x/upgrade/keeper" upgradetypes "cosmossdk.io/x/upgrade/types" - "cosmossdk.io/x/tx/signing" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -101,14 +103,14 @@ import ( no_valupdates_genutil "github.com/allinbits/vaas/x/vaas/no_valupdates_genutil" no_valupdates_staking "github.com/allinbits/vaas/x/vaas/no_valupdates_staking" - ibcprovider "github.com/allinbits/vaas/x/vaas/provider" ibcproviderkeeper "github.com/allinbits/vaas/x/vaas/provider/keeper" providertypes "github.com/allinbits/vaas/x/vaas/provider/types" + vaastypes "github.com/allinbits/vaas/x/vaas/types" ) const ( - AppName = "vaas-provider" + AppName = "vaas-provider" upgradeName = "vaas-v1-to-v2" ) @@ -149,8 +151,7 @@ var ( stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, } ) @@ -194,7 +195,6 @@ type App struct { // nolint: golint ProviderKeeper ibcproviderkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper - // the module manager MM *module.Manager @@ -385,9 +385,8 @@ func New( app.ProviderKeeper = ibcproviderkeeper.NewKeeper( appCodec, runtime.NewKVStoreService(keys[providertypes.StoreKey]), - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.ConnectionKeeper, app.IBCKeeper.ClientKeeper, + app.IBCKeeper.ClientV2Keeper, app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper, @@ -422,7 +421,6 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - providerModule := ibcprovider.NewAppModule( &app.ProviderKeeper, ) @@ -439,17 +437,19 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - // // Add an IBC middleware callback to track the consumer rewards - // var transferStack porttypes.IBCModule - // transferStack = transfer.NewIBCModule(app.TransferKeeper) - // transferStack = ibcprovider.NewIBCMiddleware(transferStack, app.ProviderKeeper) + transferStack := transfer.NewIBCModule(app.TransferKeeper) - // create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() - // ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) - ibcRouter.AddRoute(providertypes.ModuleName, providerModule) + ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) app.IBCKeeper.SetRouter(ibcRouter) + ibcRouterV2 := ibcapi.NewRouter() + ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + ibcRouterV2.AddRoute(vaastypes.ProviderAppID, ibcprovider.NewIBCModule(&app.ProviderKeeper)) + app.IBCKeeper.SetRouterV2(ibcRouterV2) + + app.ProviderKeeper.SetChannelKeeperV2(app.IBCKeeper.ChannelKeeperV2) + govRouter := govv1beta1.NewRouter() govRouter. AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). @@ -477,7 +477,6 @@ func New( upgrade.NewAppModule(&app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), ibc.NewAppModule(app.IBCKeeper), ibctm.NewAppModule(tmLightClientModule), - params.NewAppModule(app.ParamsKeeper), transfer.NewAppModule(app.TransferKeeper), providerModule, ) diff --git a/devdeps/go.mod b/devdeps/go.mod index 20d32c0..830d801 100644 --- a/devdeps/go.mod +++ b/devdeps/go.mod @@ -1,6 +1,6 @@ module devdeps -go 1.25 +go 1.25.0 require ( github.com/golangci/golangci-lint v1.64.8 @@ -180,12 +180,12 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa // indirect golang.org/x/text v0.22.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/tools v0.44.0 // indirect golang.org/x/tools/go/expect v0.1.1-deprecated // indirect golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect google.golang.org/protobuf v1.36.5 // indirect @@ -193,6 +193,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.6.1 // indirect - mvdan.cc/gofumpt v0.9.2 // indirect + mvdan.cc/gofumpt v0.7.0 // indirect mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) diff --git a/devdeps/go.sum b/devdeps/go.sum index 7b5640e..56eda19 100644 --- a/devdeps/go.sum +++ b/devdeps/go.sum @@ -656,8 +656,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -698,8 +698,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -721,8 +721,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -775,10 +775,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa h1:efT73AJZfAAUV7SOip6pWGkwJDzIGiKBZGVzHYa+ve4= +golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -860,8 +860,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -977,8 +977,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI= honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4= -mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4= -mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s= +mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= +mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.mod b/go.mod index e6ae9f4..93c52dc 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,10 @@ module github.com/allinbits/vaas -go 1.25 +go 1.26.0 replace ( cosmossdk.io/x/evidence => github.com/atomone-hub/cosmos-sdk/x/evidence v0.1.1 cosmossdk.io/x/upgrade => github.com/atomone-hub/cosmos-sdk/x/upgrade v0.1.5-atomone.1.0.20251218143825-cbb67818e94a - github.com/bytedance/sonic => github.com/bytedance/sonic v1.12.7 github.com/cosmos/cosmos-sdk => github.com/atomone-hub/cosmos-sdk v0.50.14-atomone.1.0.20251218143825-cbb67818e94a github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) @@ -79,12 +78,13 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.2.0 // indirect github.com/bits-and-blooms/bitset v1.22.0 // indirect - github.com/bytedance/sonic v1.13.2 // indirect - github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect diff --git a/go.sum b/go.sum index cb55402..32f18cb 100644 --- a/go.sum +++ b/go.sum @@ -154,11 +154,12 @@ github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/ github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= -github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q= -github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= -github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -182,9 +183,8 @@ 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/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= -github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= @@ -546,10 +546,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -792,6 +790,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -1143,7 +1142,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/proto/vaas/consumer/v1/genesis.proto b/proto/vaas/consumer/v1/genesis.proto index b00aa72..196aeb7 100644 --- a/proto/vaas/consumer/v1/genesis.proto +++ b/proto/vaas/consumer/v1/genesis.proto @@ -19,24 +19,16 @@ import "tendermint/abci/types.proto"; message GenesisState { // ConsumerParams is a shared type with provider module vaas.v1.ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; - // Client ID of the provider. Empty for a new chain, filled in on restart. + // Client ID of the provider. This is the primary identifier for the provider. string provider_client_id = 2; - // Channel ID of the provider. Empty for a new chain, filled in on restart. - string provider_channel_id = 3; // true for new chain, false for chain restart. - bool new_chain = 4; + bool new_chain = 3; // HeightToValsetUpdateId nil on new chain, filled in on restart. - repeated HeightToValsetUpdateID height_to_valset_update_id = 5 + repeated HeightToValsetUpdateID height_to_valset_update_id = 4 [ (gogoproto.nullable) = false ]; // Flag indicating whether the consumer VAAS module starts in pre-VAAS state - bool preVAAS = 9; - vaas.v1.ProviderInfo provider = 10 [ (gogoproto.nullable) = false ]; - // The ID of the connection end on the consumer chain on top of which the - // VAAS channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using provider.client_state and - // provider.consensus_state. - string connection_id = 11; + bool preVAAS = 5; + vaas.v1.ProviderInfo provider = 6 [ (gogoproto.nullable) = false ]; } // HeightValsetUpdateID represents a mapping internal to the consumer VAAS module diff --git a/proto/vaas/consumer/v1/query.proto b/proto/vaas/consumer/v1/query.proto index 71ac685..865e6af 100644 --- a/proto/vaas/consumer/v1/query.proto +++ b/proto/vaas/consumer/v1/query.proto @@ -13,6 +13,7 @@ service Query { option (google.api.http).get = "/vaas/consumer/params"; } + // QueryProviderInfo returns information about the provider chain connection. rpc QueryProviderInfo(QueryProviderInfoRequest) returns (QueryProviderInfoResponse) { option (google.api.http).get = "/vaas/consumer/provider-info"; } @@ -33,9 +34,9 @@ message QueryProviderInfoResponse { ChainInfo provider = 2 [ (gogoproto.nullable) = false ]; } +// ChainInfo contains IBC connection information for a chain. message ChainInfo { string chainID = 1; + // clientID is the IBC client identifier. string clientID = 2; - string connectionID = 3; - string channelID = 4; } diff --git a/proto/vaas/provider/v1/genesis.proto b/proto/vaas/provider/v1/genesis.proto index bdcf7c0..ee000e3 100644 --- a/proto/vaas/provider/v1/genesis.proto +++ b/proto/vaas/provider/v1/genesis.proto @@ -40,22 +40,20 @@ message GenesisState { message ConsumerState { // ChainID defines the chain ID for the consumer chain string chain_id = 1; - // ChannelID defines the IBC channel ID for the consumer chain - string channel_id = 2; - // ClientID defines the IBC client ID for the consumer chain - string client_id = 3; + // ClientID defines the IBC client ID for the consumer chain. + string client_id = 2; // InitalHeight defines the initial block height for the consumer chain - uint64 initial_height = 4; + uint64 initial_height = 3; // ConsumerGenesis defines the initial consumer chain genesis states - vaas.v1.ConsumerGenesisState consumer_genesis = 5 + vaas.v1.ConsumerGenesisState consumer_genesis = 4 [ (gogoproto.nullable) = false ]; // PendingValsetChanges defines the pending validator set changes for the // consumer chain repeated vaas.v1.ValidatorSetChangePacketData - pending_valset_changes = 6 [ (gogoproto.nullable) = false ]; - repeated string slash_downtime_ack = 7; + pending_valset_changes = 5 [ (gogoproto.nullable) = false ]; + repeated string slash_downtime_ack = 6; // the phase of the consumer chain - ConsumerPhase phase = 8; + ConsumerPhase phase = 7; } // ValsetUpdateIdToHeight defines the genesis information for the mapping diff --git a/proto/vaas/provider/v1/provider.proto b/proto/vaas/provider/v1/provider.proto index 20c0094..cbbd1cd 100644 --- a/proto/vaas/provider/v1/provider.proto +++ b/proto/vaas/provider/v1/provider.proto @@ -23,20 +23,19 @@ option go_package = "github.com/allinbits/vaas/x/vaas/provider/types"; // Params defines the parameters for VAAS Provider module message Params { - ibc.lightclients.tendermint.v1.ClientState template_client = 1; // TrustingPeriodFraction is used to compute the consumer and provider IBC // client's TrustingPeriod from the chain defined UnbondingPeriod - string trusting_period_fraction = 2; + string trusting_period_fraction = 1; // Sent IBC packets will timeout after this duration - google.protobuf.Duration vaas_timeout_period = 3 + google.protobuf.Duration vaas_timeout_period = 2 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; // The number of blocks that comprise an epoch. - int64 blocks_per_epoch = 4; + int64 blocks_per_epoch = 3; // The maximal number of validators that will be passed // to the consensus engine on the provider. - int64 max_provider_consensus_validators = 5; + int64 max_provider_consensus_validators = 4; } // AddressList contains a list of consensus addresses @@ -136,7 +135,7 @@ message ConsumerInitializationParameters { // chain initialization. It is used for off-chain confirmation of binary // validity by validators and other parties. bytes binary_hash = 3; - // spawn time is the time on the provider chain at which the consumer chain + // spawn_time is the time on the provider chain at which the consumer chain // genesis is finalized and all validators will be responsible for starting // their consumer chain validator node. google.protobuf.Timestamp spawn_time = 4 @@ -159,13 +158,6 @@ message ConsumerInitializationParameters { // This param is a part of the cosmos sdk staking module. In the case of // a VAAS enabled consumer chain, the VAAS module acts as the staking module. int64 historical_entries = 7; - // The ID of the connection end on the provider chain on top of which the VAAS - // channel will be established. If connection_id == "", a new client of the - // consumer chain and a new connection on top of this client are created. - // Note that a standalone chain can transition to a consumer chain while - // maintaining existing IBC channels to other chains by providing a valid - // connection_id. - string connection_id = 8; } // ConsumerIds contains consumer ids of chains diff --git a/proto/vaas/provider/v1/tx.proto b/proto/vaas/provider/v1/tx.proto index b7e1092..e3b2eae 100644 --- a/proto/vaas/provider/v1/tx.proto +++ b/proto/vaas/provider/v1/tx.proto @@ -1,20 +1,20 @@ syntax = "proto3"; package vaas.provider.v1; -option go_package = "github.com/allinbits/vaas/x/vaas/provider/types"; - import "amino/amino.proto"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/duration.proto"; import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/msg/v1/msg.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; import "ibc/core/client/v1/client.proto"; -import "vaas/provider/v1/provider.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/types/evidence.proto"; +import "vaas/provider/v1/provider.proto"; + +option go_package = "github.com/allinbits/vaas/x/vaas/provider/types"; // Msg defines the Msg service. service Msg { @@ -29,7 +29,6 @@ service Msg { rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } - message MsgAssignConsumerKey { option (cosmos.msg.v1.signer) = "signer"; option (gogoproto.equal) = false; @@ -38,7 +37,7 @@ message MsgAssignConsumerKey { // the consumer id of the consumer chain to assign a consensus public key to string consumer_id = 1; // The validator address on the provider - string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + string provider_addr = 2 [(gogoproto.moretags) = "yaml:\"address\""]; // The consensus public key to use on the consumer. // in json string format corresponding to proto-any, ex: // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}` @@ -49,7 +48,6 @@ message MsgAssignConsumerKey { message MsgAssignConsumerKeyResponse {} - // MsgSubmitConsumerMisbehaviour defines a message that reports a light client attack, // also known as a misbehaviour, observed on a consumer chain message MsgSubmitConsumerMisbehaviour { @@ -67,7 +65,6 @@ message MsgSubmitConsumerMisbehaviour { message MsgSubmitConsumerMisbehaviourResponse {} - // MsgSubmitConsumerDoubleVoting defines a message that reports // a double signing infraction observed on a consumer chain message MsgSubmitConsumerDoubleVoting { @@ -114,7 +111,7 @@ message MsgRemoveConsumer { // MsgRemoveConsumerResponse defines response type for MsgRemoveConsumer messages message MsgRemoveConsumerResponse {} -// MsgCreateConsumer defines the message that creates a consumer chain +// MsgCreateConsumer defines the message that creates a consumer chain. message MsgCreateConsumer { option (cosmos.msg.v1.signer) = "submitter"; @@ -125,7 +122,7 @@ message MsgCreateConsumer { // the chain id of the new consumer chain string chain_id = 2; - ConsumerMetadata metadata = 3 [ (gogoproto.nullable) = false ]; + ConsumerMetadata metadata = 3 [(gogoproto.nullable) = false]; ConsumerInitializationParameters initialization_parameters = 4; diff --git a/proto/vaas/v1/shared_consumer.proto b/proto/vaas/v1/shared_consumer.proto index a5aa769..c7c676e 100644 --- a/proto/vaas/v1/shared_consumer.proto +++ b/proto/vaas/v1/shared_consumer.proto @@ -52,21 +52,14 @@ message ConsumerGenesisState { bool new_chain = 3; // Flag indicating whether the consumer VAAS module starts in pre-VAAS state bool preVAAS = 4; - // The ID of the connection end on the consumer chain on top of which the - // VAAS channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using client_state and consensus_state. - string connection_id = 5; } // ProviderInfo defines all information a consumer needs from a provider // Shared data type between provider and consumer message ProviderInfo { // The client state for the provider client filled in on new chain, nil on restart. - // If connection_id != "", then client_state is ignored. ibc.lightclients.tendermint.v1.ClientState client_state = 1; // The consensus state for the provider client filled in on new chain, nil on restart. - // If connection_id != "", then consensus_state is ignored. ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; // InitialValset filled in on new chain and on restart. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 diff --git a/proto/vaas/v1/wire.proto b/proto/vaas/v1/wire.proto index ceeee26..ce6d20d 100644 --- a/proto/vaas/v1/wire.proto +++ b/proto/vaas/v1/wire.proto @@ -11,15 +11,13 @@ import "tendermint/abci/types.proto"; // // Note any type defined in this file is used by both the consumer and provider -// AND SENT OVER THE WIRE via a VAAS channel. Ideally these schemas should never +// AND SENT OVER THE WIRE via IBC v2. Ideally these schemas should never // change, or at least be backwards compatible if ever changed. // // This packet is sent from provider chain to consumer chain if the validator // set for consumer chain changes (due to new bonding/unbonding messages or -// slashing events) A VSCMatured packet from consumer chain will be sent -// asynchronously once unbonding period is over, and this will function as -// `UnbondingOver` message for this packet. +// slashing events). message ValidatorSetChangePacketData { repeated .tendermint.abci.ValidatorUpdate validator_updates = 1 [ (gogoproto.nullable) = false, @@ -27,7 +25,3 @@ message ValidatorSetChangePacketData { ]; uint64 valset_update_id = 2; } - -// Note this type is used during IBC handshake methods for both the consumer and -// provider -message HandshakeMetadata { string version = 1; } diff --git a/scripts/go-mod-tidy-all.sh b/scripts/go-mod-tidy-all.sh new file mode 100755 index 0000000..c129f73 --- /dev/null +++ b/scripts/go-mod-tidy-all.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail + +for modfile in $(find . -name go.mod); do + echo "Updating $modfile" + DIR=$(dirname $modfile) + (cd $DIR; go mod tidy) +done diff --git a/scripts/hermes-config.sh b/scripts/hermes-config.sh deleted file mode 100755 index 9f5953f..0000000 --- a/scripts/hermes-config.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -# Create Hermes configuration for local VAAS testing - -HERMES_CONFIG="${HOME}/.vaas-hermes/config.toml" -mkdir -p "${HOME}/.vaas-hermes" - -cat > "${HERMES_CONFIG}" << EOF -[global] -log_level = 'info' - -[mode] -[mode.clients] -enabled = true -refresh = true -misbehaviour = false - -[mode.connections] -enabled = true - -[mode.channels] -enabled = true - -[mode.packets] -enabled = true -clear_interval = 100 -clear_on_start = true -tx_confirmation = false - -[rest] -enabled = false -host = '127.0.0.1' -port = 3000 - -[telemetry] -enabled = false -host = '127.0.0.1' -port = 3001 - -[[chains]] -id = 'provider-localnet' -type = 'CosmosSdk' -rpc_addr = 'http://127.0.0.1:26657' -grpc_addr = 'http://127.0.0.1:9090' -rpc_timeout = '10s' -trusted_node = true -account_prefix = 'cosmos' -key_name = 'relayer' -key_store_type = 'Test' -key_store_folder = '${HOME}/.vaas-hermes/keys' -store_prefix = 'ibc' -default_gas = 100000 -max_gas = 3000000 -gas_multiplier = 1.2 -max_msg_num = 30 -max_tx_size = 180000 -clock_drift = '5s' -max_block_time = '30s' -ccv_consumer_chain = false - -[chains.event_source] -mode = 'push' -url = 'ws://127.0.0.1:26657/websocket' -batch_delay = '500ms' - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.01 -denom = 'uatone' - -[chains.packet_filter] -policy = 'allow' -list = [['consumer', '*'], ['provider', '*'], ['transfer', '*']] - -[chains.address_type] -derivation = 'cosmos' - -[[chains]] -id = 'consumer-localnet' -type = 'CosmosSdk' -rpc_addr = 'http://127.0.0.1:26667' -grpc_addr = 'http://127.0.0.1:9092' -rpc_timeout = '10s' -trusted_node = true -account_prefix = 'cosmos' -key_name = 'relayer' -key_store_type = 'Test' -key_store_folder = '${HOME}/.vaas-hermes/keys' -store_prefix = 'ibc' -default_gas = 100000 -max_gas = 3000000 -gas_multiplier = 1.2 -max_msg_num = 30 -max_tx_size = 180000 -clock_drift = '5s' -max_block_time = '30s' -ccv_consumer_chain = false - -[chains.event_source] -mode = 'push' -url = 'ws://127.0.0.1:26667/websocket' -batch_delay = '500ms' - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.01 -denom = 'uatone' - -[chains.packet_filter] -policy = 'allow' -list = [['consumer', '*'], ['provider', '*'], ['transfer', '*']] - -[chains.address_type] -derivation = 'cosmos' -EOF - -echo "Hermes configuration created at ${HERMES_CONFIG}" diff --git a/tests/e2e/doc.go b/tests/e2e/doc.go index ff884ba..e1f2fea 100644 --- a/tests/e2e/doc.go +++ b/tests/e2e/doc.go @@ -2,12 +2,14 @@ // VAAS (Validation as a Service) provider-consumer chain setup. // // It uses Docker containers (via dockertest) to run a provider chain, -// a consumer chain, and a Hermes IBC relayer, validating the full -// CCV (Cross-Chain Validation) lifecycle including: +// a consumer chain, and the ibc-v2-ts-relayer, validating the full CCV +// (Cross-Chain Validation) lifecycle including: // // - Provider chain initialization and block production // - Consumer chain registration on the provider // - Consumer genesis bootstrapping from provider state -// - Validator set synchronization via VSC packets -// - IBC relaying of VAAS packets via Hermes +// - IBC v2 counterparty registration (via ts-relayer) +// - Validator set synchronization via VSC packets (relayed by ts-relayer) +// +// The ts-relayer is available at https://github.com/allinbits/ibc-v2-ts-relayer package e2e diff --git a/tests/e2e/docker/e2e.Dockerfile b/tests/e2e/docker/e2e.Dockerfile index 92d66c8..7861d3b 100644 --- a/tests/e2e/docker/e2e.Dockerfile +++ b/tests/e2e/docker/e2e.Dockerfile @@ -1,4 +1,4 @@ -ARG GO_VERSION=1.25 +ARG GO_VERSION=1.26.0 ARG IMG_TAG=latest # Compile provider and consumer binaries diff --git a/tests/e2e/docker/hermes.Dockerfile b/tests/e2e/docker/hermes.Dockerfile deleted file mode 100644 index 4fb2b65..0000000 --- a/tests/e2e/docker/hermes.Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM informalsystems/hermes:1.13.1 - -EXPOSE 3031 - -# No fixed entrypoint — the test suite specifies the command -ENTRYPOINT [] diff --git a/tests/e2e/e2e_exec_test.go b/tests/e2e/e2e_exec_test.go index a0118c8..acf6f42 100644 --- a/tests/e2e/e2e_exec_test.go +++ b/tests/e2e/e2e_exec_test.go @@ -41,41 +41,6 @@ func (s *IntegrationTestSuite) dockerExec(containerID string, cmd []string) (byt return stdout, stderr, nil } -// executeHermesCommand runs a command in the Hermes relayer container. -// Uses the container's default user instead of "nonroot". -func (s *IntegrationTestSuite) executeHermesCommand(cmd []string) (bytes.Buffer, bytes.Buffer, error) { - s.Require().NotNil(s.hermesResource, "hermes container not started") - - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) - defer cancel() - - var stdout, stderr bytes.Buffer - - exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ - Context: ctx, - AttachStdout: true, - AttachStderr: true, - Container: s.hermesResource.Container.ID, - Cmd: cmd, - }) - if err != nil { - return stdout, stderr, fmt.Errorf("failed to create exec: %w", err) - } - - err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ - Context: ctx, - Detach: false, - OutputStream: &stdout, - ErrorStream: &stderr, - }) - if err != nil { - return stdout, stderr, fmt.Errorf("failed to start exec: %w", err) - } - - return stdout, stderr, nil -} - - // dockerExecMust runs a command in a Docker container, failing the test on error. func (s *IntegrationTestSuite) dockerExecMust(containerID string, cmd []string) { stdout, stderr, err := s.dockerExec(containerID, cmd) diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index fdcb53a..e1d3358 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -23,26 +23,24 @@ import ( const ( e2eChainImage = "cosmos/vaas-e2e" - hermesImage = "ghcr.io/cosmos/hermes-e2e" - hermesImageTag = "1.13.1" dockerNetwork = "vaas-e2e-testnet" relayerMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" ) // IntegrationTestSuite is the main e2e test suite that orchestrates -// provider chain, consumer chain, and Hermes relayer containers. +// provider chain and consumer chain containers. type IntegrationTestSuite struct { suite.Suite - cdc codec.Codec - tmpDirs []string - provider *chain - consumer *chain - dkrPool *dockertest.Pool - dkrNet *dockertest.Network - hermesResource *dockertest.Resource - providerValRes []*dockertest.Resource - consumerValRes []*dockertest.Resource + cdc codec.Codec + tmpDirs []string + provider *chain + consumer *chain + dkrPool *dockertest.Pool + dkrNet *dockertest.Network + providerValRes []*dockertest.Resource + consumerValRes []*dockertest.Resource + tsRelayerResource *dockertest.Resource } // makeCodec creates a proto codec with the standard cosmos SDK interfaces registered. @@ -69,8 +67,7 @@ func testDir() string { // 3. Register consumer on provider // 4. Fetch consumer genesis from provider // 5. Initialize and start consumer chain -// 6. Setup Hermes relayer with IBC connection and VAAS channel -// 7. Trigger VSC +// 6. Start ts-relayer and create IBC v2 path func (s *IntegrationTestSuite) SetupSuite() { s.T().Log("setting up e2e integration test suite...") @@ -105,14 +102,11 @@ func (s *IntegrationTestSuite) SetupSuite() { s.consumer = &chain{id: consumerChainID} s.initAndStartConsumer(consumerGenesisJSON) - s.T().Log("step 5: setting up Hermes relayer...") - s.startHermesRelayer() + s.T().Log("step 5: starting ts-relayer and creating IBC v2 path...") + s.setupTSRelayer() - s.T().Log("step 6: creating IBC connection and VAAS channel...") - s.createIBCConnectionAndChannel() - - s.T().Log("step 7: triggering validator set change...") - s.triggerVSC() + s.T().Log("step 6: checking IBC counterparty registration...") + s.collectIBCDiagnosticsLog() s.T().Log("e2e test suite setup complete!") } @@ -126,12 +120,7 @@ func (s *IntegrationTestSuite) TearDownSuite() { return } - // Purge Hermes - if s.hermesResource != nil { - if err := s.dkrPool.Purge(s.hermesResource); err != nil { - s.T().Logf("failed to purge hermes: %v", err) - } - } + s.stopTSRelayer() // Purge consumer validators for _, r := range s.consumerValRes { @@ -167,7 +156,7 @@ func (s *IntegrationTestSuite) cleanupStaleContainers() { "consumer-init", fmt.Sprintf("%s-val0", providerChainID), fmt.Sprintf("%s-val0", consumerChainID), - "hermes-relayer", + fmt.Sprintf("%s-%s-ts-relayer", providerChainID, consumerChainID), } for _, name := range staleNames { c, err := s.dkrPool.Client.InspectContainer(name) @@ -444,138 +433,22 @@ func (s *IntegrationTestSuite) initAndStartConsumer(consumerGenesisJSON []byte) s.T().Log("consumer chain is producing blocks") } -// startHermesRelayer starts the Hermes relayer container. -func (s *IntegrationTestSuite) startHermesRelayer() { - hermesDir, err := os.MkdirTemp("", "vaas-e2e-hermes-") - s.Require().NoError(err) - s.tmpDirs = append(s.tmpDirs, hermesDir) - - // Write hermes config - hermesConfig := s.generateHermesConfig() - s.Require().NoError(os.MkdirAll(filepath.Join(hermesDir, ".hermes"), 0o750)) - s.Require().NoError(os.WriteFile(filepath.Join(hermesDir, ".hermes", "config.toml"), []byte(hermesConfig), 0o600)) - - // Make hermes dir accessible - s.Require().NoError(chmodRecursive(hermesDir, 0o777)) - - hermesInitScript := filepath.Join(testDir(), "scripts", "hermes-init.sh") - - resource, err := s.dkrPool.RunWithOptions( - &dockertest.RunOptions{ - Name: "hermes-relayer", - Repository: hermesImage, - Tag: hermesImageTag, - NetworkID: s.dkrNet.Network.ID, - Env: []string{ - "PROVIDER_CHAIN_ID=" + providerChainID, - "CONSUMER_CHAIN_ID=" + consumerChainID, - "RELAYER_MNEMONIC=" + relayerMnemonic, - }, - Mounts: []string{ - fmt.Sprintf("%s/.hermes:/home/hermes/.hermes", hermesDir), - fmt.Sprintf("%s:/home/hermes/hermes-init.sh", hermesInitScript), - }, - PortBindings: map[docker.Port][]docker.PortBinding{ - "3031/tcp": {{HostIP: "", HostPort: "3031"}}, - }, - Entrypoint: []string{"sh", "/home/hermes/hermes-init.sh"}, - }, - func(config *docker.HostConfig) { - config.RestartPolicy = docker.RestartPolicy{Name: "no"} - }, - ) - s.Require().NoError(err, "failed to start hermes container") - - s.hermesResource = resource - s.T().Logf("hermes container started: %s", resource.Container.ID[:12]) - - // Wait for hermes to start - time.Sleep(15 * time.Second) -} - -// createIBCConnectionAndChannel creates the IBC connection using genesis clients -// and then creates the VAAS channel. -func (s *IntegrationTestSuite) createIBCConnectionAndChannel() { - // Create connection using genesis clients (07-tendermint-0) - _, _, err := s.executeHermesCommand([]string{ - "hermes", "create", "connection", - "--a-chain", consumerChainID, - "--a-client", "07-tendermint-0", - "--b-client", "07-tendermint-0", - }) - - s.Require().NoError(err, "failed to create IBC connection") +// setupTSRelayer starts the ts-relayer container, configures it with +// mnemonics and gas prices for both chains, and creates an IBC v2 path. +// The ts-relayer handles counterparty registration and packet relaying. +func (s *IntegrationTestSuite) setupTSRelayer() { + s.startTSRelayer() - time.Sleep(5 * time.Second) + s.tsRelayerAddMnemonic(providerChainID, relayerMnemonic) + s.tsRelayerAddMnemonic(consumerChainID, relayerMnemonic) + s.tsRelayerAddGasPrice(providerChainID, "0.025"+bondDenom) + s.tsRelayerAddGasPrice(consumerChainID, "0.025"+bondDenom) - // Create VAAS channel (consumer/provider ports, ordered, version "1") - _, _, err = s.executeHermesCommand([]string{ - "hermes", "create", "channel", - "--a-chain", consumerChainID, - "--a-connection", "connection-0", - "--a-port", "consumer", - "--b-port", "provider", - "--order", "ordered", - "--channel-version", "1", - }) - - s.Require().NoError(err, "failed to create VAAS channel") - - s.T().Log("IBC connection and VAAS channel created") -} - -// triggerVSC triggers a validator set change on the provider. -func (s *IntegrationTestSuite) triggerVSC() { - // Get validator operator address - stdout, _, err := s.dockerExec(s.providerValRes[0].Container.ID, []string{ - providerBinary, "keys", "show", "val", "--bech", "val", "-a", - "--home", providerHomePath, - "--keyring-backend", "test", - }) - s.Require().NoError(err, "failed to get validator address") - valAddr := strings.TrimSpace(stdout.String()) - - // Delegate to trigger validator set change - _, _, err = s.dockerExec(s.providerValRes[0].Container.ID, []string{ - providerBinary, "tx", "staking", "delegate", valAddr, "1000000" + bondDenom, - "--from", "user", - "--home", providerHomePath, - "--keyring-backend", "test", - "--chain-id", providerChainID, - "--fees", "10000" + bondDenom, - "-y", - }) - s.Require().NoError(err, "failed to delegate on provider") - - s.T().Log("delegation sent, waiting for VSC packet relay...") - - // Wait for VSC to be relayed — poll consumer for provider info - for i := 0; i < 60; i++ { - time.Sleep(2 * time.Second) - - stdout, _, err := s.dockerExec(s.consumerValRes[0].Container.ID, []string{ - consumerBinary, "query", "vaasconsumer", "provider-info", - "--home", consumerHomePath, - }) - if err == nil && stdout.Len() > 0 && !strings.Contains(stdout.String(), "error") { - s.T().Logf("VSC relayed after %d seconds", (i+1)*2) - return - } - } - - s.T().Log("WARNING: VSC packet may not have been relayed within timeout") -} - -// generateHermesConfig reads the Hermes config template and substitutes chain IDs. -func (s *IntegrationTestSuite) generateHermesConfig() string { - templatePath := filepath.Join(testDir(), "testdata", "hermes_config.toml") - templateBytes, err := os.ReadFile(templatePath) - s.Require().NoError(err, "failed to read hermes_config.toml template") + s.tsRelayerAddPath(IBCv2) - config := string(templateBytes) - config = strings.ReplaceAll(config, "PROVIDER_CHAIN_ID", providerChainID) - config = strings.ReplaceAll(config, "CONSUMER_CHAIN_ID", consumerChainID) - return config + s.tsRelayerDumpPaths() + s.startTSRelayerRelay() + s.T().Log("ts-relayer IBC v2 path configured") } // waitForChainHeight polls a CometBFT RPC endpoint until the chain reaches diff --git a/tests/e2e/e2e_tsrelayer_test.go b/tests/e2e/e2e_tsrelayer_test.go new file mode 100644 index 0000000..4607ac0 --- /dev/null +++ b/tests/e2e/e2e_tsrelayer_test.go @@ -0,0 +1,333 @@ +package e2e + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "regexp" + "strings" + "time" + + "github.com/ory/dockertest/v3" + "github.com/ory/dockertest/v3/docker" +) + +const ( + tsRelayerImage = "ghcr.io/allinbits/ibc-v2-ts-relayer" + tsRelayerImageTag = "latest" + IBCv2 = "2" +) + +type tsRelayerPath struct { + ID int `json:"id"` + Version int `json:"version"` + ChainIdA string `json:"chainIdA"` + ChainIdB string `json:"chainIdB"` + ClientA string `json:"clientA"` + ClientB string `json:"clientB"` + NodeA string `json:"nodeA"` + NodeB string `json:"nodeB"` +} + +func noRestart(config *docker.HostConfig) { + config.RestartPolicy = docker.RestartPolicy{Name: "no"} +} + +func (s *IntegrationTestSuite) startTSRelayer() { + s.T().Log("starting ts-relayer container") + + resource, err := s.dkrPool.RunWithOptions( + &dockertest.RunOptions{ + Name: fmt.Sprintf("%s-%s-ts-relayer", providerChainID, consumerChainID), + Repository: tsRelayerImage, + Tag: tsRelayerImageTag, + NetworkID: s.dkrNet.Network.ID, + User: "root", + CapAdd: []string{"IPC_LOCK"}, + }, + noRestart, + ) + s.Require().NoError(err, "failed to start ts-relayer container") + s.tsRelayerResource = resource + s.T().Logf("ts-relayer container started: %s", resource.Container.ID[:12]) + + time.Sleep(3 * time.Second) + + providerURL := "http://" + s.providerValRes[0].Container.Name[1:] + ":26657" + consumerURL := "http://" + s.consumerValRes[0].Container.Name[1:] + ":26657" + + s.verifyTSRelayerConnectivity("provider", providerURL) + s.verifyTSRelayerConnectivity("consumer", consumerURL) +} + +func (s *IntegrationTestSuite) verifyTSRelayerConnectivity(chainName, rpcURL string) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + for attempt := 0; attempt < 10; attempt++ { + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.tsRelayerResource.Container.ID, + User: "root", + Cmd: []string{"wget", "-qO-", fmt.Sprintf("%s/status", rpcURL)}, + }) + s.Require().NoError(err) + + var out bytes.Buffer + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &out, + ErrorStream: &out, + }) + + for { + inspectExec, err := s.dkrPool.Client.InspectExec(exec.ID) + s.Require().NoError(err) + if !inspectExec.Running { + if inspectExec.ExitCode == 0 && strings.Contains(out.String(), "latest_block_height") { + s.T().Logf("ts-relayer can reach %s RPC at %s", chainName, rpcURL) + return + } + break + } + } + + s.T().Logf("ts-relayer connectivity to %s (%s) attempt %d failed (output=%s)", + chainName, rpcURL, attempt+1, out.String()) + time.Sleep(2 * time.Second) + } + + s.Require().Fail("ts-relayer cannot reach %s RPC at %s", chainName, rpcURL) +} + +func (s *IntegrationTestSuite) startTSRelayerRelay() { + s.T().Log("ts-relayer: starting relay process") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + cmd := []string{"/bin/with_keyring", "ibc-v2-ts-relayer", "relay"} + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.tsRelayerResource.Container.ID, + User: "root", + Cmd: cmd, + }) + s.Require().NoError(err, "failed to create relay exec") + + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: true, + }) + s.Require().NoError(err, "failed to start relay process") + + time.Sleep(3 * time.Second) + + inspectExec, err := s.dkrPool.Client.InspectExec(exec.ID) + s.Require().NoError(err, "failed to inspect relay exec") + s.Require().True(inspectExec.Running, "relay process is not running") + s.T().Log("ts-relayer: relay process started") +} + +func (s *IntegrationTestSuite) stopTSRelayer() { + if s.tsRelayerResource != nil { + s.T().Log("tearing down ts-relayer...") + s.Require().NoError(s.dkrPool.Purge(s.tsRelayerResource)) + s.tsRelayerResource = nil + } +} + +func (s *IntegrationTestSuite) executeTSRelayerCommand(ctx context.Context, args []string) []byte { + tsRelayerBinary := []string{"/bin/with_keyring", "ibc-v2-ts-relayer"} + cmd := append(tsRelayerBinary, args...) + exec, err := s.dkrPool.Client.CreateExec(docker.CreateExecOptions{ + Context: ctx, + AttachStdout: true, + AttachStderr: true, + Container: s.tsRelayerResource.Container.ID, + User: "root", + Cmd: cmd, + }) + s.Require().NoError(err) + + var out bytes.Buffer + err = s.dkrPool.Client.StartExec(exec.ID, docker.StartExecOptions{ + Context: ctx, + Detach: false, + OutputStream: &out, + ErrorStream: &out, + }) + s.Require().NoError(err, "ts-relayer startExec error: %s", out.String()) + + for { + inspectExec, err := s.dkrPool.Client.InspectExec(exec.ID) + s.Require().NoError(err, "ts-relayer inspectExec error: %s", out.String()) + if !inspectExec.Running { + if inspectExec.ExitCode != 0 { + s.T().Logf("ts-relayer cmd '%s' full output:\n%s", strings.Join(cmd, " "), out.String()) + chainDiag := s.collectChainDiagnostics() + ibcDiag := s.collectIBCDiagnostics() + s.Require().Equal(0, inspectExec.ExitCode, + "ts-relayer cmd '%s' failed (exit=%d): %s\n\nchain diagnostics:\n%s\n\nibc diagnostics:\n%s", + strings.Join(cmd, " "), inspectExec.ExitCode, out.String(), chainDiag, ibcDiag) + } + s.Require().Equal(0, inspectExec.ExitCode, "ts-relayer cmd '%s' failed (exit=%d): %s", + strings.Join(cmd, " "), inspectExec.ExitCode, out.String()) + break + } + } + return out.Bytes() +} + +func (s *IntegrationTestSuite) tsRelayerAddMnemonic(chainID, mnemonic string) { + s.T().Logf("ts-relayer: adding mnemonic for chain %s", chainID) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + s.executeTSRelayerCommand(ctx, []string{ + "add-mnemonic", + "-c", chainID, + "--mnemonic", mnemonic, + }) +} + +func (s *IntegrationTestSuite) tsRelayerAddGasPrice(chainID, gasPrice string) { + s.T().Logf("ts-relayer: adding gas-price for chain %s", chainID) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + s.executeTSRelayerCommand(ctx, []string{ + "add-gas-price", + "-c", chainID, + "--gas-adjustment", "2.0", + gasPrice, + }) +} + +func (s *IntegrationTestSuite) tsRelayerAddPath(ibcVersion string) { + s.T().Logf("ts-relayer: adding IBCv%s path between %s and %s", ibcVersion, providerChainID, consumerChainID) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + s.executeTSRelayerCommand(ctx, []string{ + "add-path", + "-s", providerChainID, + "-d", consumerChainID, + "--surl", "http://" + s.providerValRes[0].Container.Name[1:] + ":26657", + "--durl", "http://" + s.consumerValRes[0].Container.Name[1:] + ":26657", + "--st", "cosmos", + "--dt", "cosmos", + "--ibc-version", ibcVersion, + }) +} + +var ansiEscapeRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) + +func (s *IntegrationTestSuite) tsRelayerDumpPaths() []tsRelayerPath { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + out := s.executeTSRelayerCommand(ctx, []string{"dump-paths"}) + cleaned := ansiEscapeRegex.ReplaceAll(out, []byte{}) + jsonStart := bytes.Index(cleaned, []byte("\t[")) + if jsonStart < 0 { + jsonStart = bytes.Index(cleaned, []byte("\n[")) + } + jsonStart++ + s.Require().GreaterOrEqual(jsonStart, 1, "no JSON array found in ts-relayer dump-paths output: %s", cleaned) + var paths []tsRelayerPath + s.Require().NoError(json.Unmarshal(cleaned[jsonStart:], &paths), "parsing ts-relayer dump-paths: %s", cleaned) + return paths +} + +func (s *IntegrationTestSuite) collectChainDiagnostics() string { + var sb strings.Builder + for _, chain := range []struct { + name string + res []*dockertest.Resource + }{ + {"provider", s.providerValRes}, + {"consumer", s.consumerValRes}, + } { + for _, r := range chain.res { + var logBuf bytes.Buffer + _ = s.dkrPool.Client.Logs(docker.LogsOptions{ + Container: r.Container.ID, + OutputStream: &logBuf, + ErrorStream: &logBuf, + Stdout: true, + Stderr: true, + Tail: "100", + }) + sb.WriteString(fmt.Sprintf("=== %s chain (tail 100) ===\n%s\n", chain.name, logBuf.String())) + } + } + return sb.String() +} + +func (s *IntegrationTestSuite) collectIBCDiagnosticsLog() { + chains := []struct { + name string + container *dockertest.Resource + binary string + home string + }{ + {"provider", s.providerValRes[0], providerBinary, providerHomePath}, + {"consumer", s.consumerValRes[0], consumerBinary, consumerHomePath}, + } + for _, c := range chains { + stdout, _, err := s.dockerExec(c.container.Container.ID, []string{ + c.binary, "query", "ibc", "client", "states", "--home", c.home, "--output", "json", + }) + if err != nil { + s.T().Logf("%s ibc client states: ERROR: %v", c.name, err) + } else { + s.T().Logf("%s ibc client states: %s", c.name, stdout.String()) + } + + for _, clientID := range []string{"07-tendermint-0", "07-tendermint-1"} { + stdout2, _, err := s.dockerExec(c.container.Container.ID, []string{ + c.binary, "query", "ibc", "client", "counterparty-info", clientID, "--home", c.home, "--output", "json", + }) + if err != nil { + s.T().Logf("%s ibc counterparty %s: ERROR: %v (output: %s)", c.name, clientID, err, stdout2.String()) + } else { + s.T().Logf("%s ibc counterparty %s: %s", c.name, clientID, stdout2.String()) + } + } + } +} + +func (s *IntegrationTestSuite) collectIBCDiagnostics() string { + var sb strings.Builder + chains := []struct { + name string + container *dockertest.Resource + binary string + home string + }{ + {"provider", s.providerValRes[0], providerBinary, providerHomePath}, + {"consumer", s.consumerValRes[0], consumerBinary, consumerHomePath}, + } + for _, c := range chains { + stdout, _, err := s.dockerExec(c.container.Container.ID, []string{ + c.binary, "query", "ibc", "client", "states", "--home", c.home, "--output", "json", + }) + if err != nil { + sb.WriteString(fmt.Sprintf("=== %s ibc client states: ERROR: %v ===\n", c.name, err)) + } else { + sb.WriteString(fmt.Sprintf("=== %s ibc client states ===\n%s\n", c.name, stdout.String())) + } + + stdout2, _, err := s.dockerExec(c.container.Container.ID, []string{ + c.binary, "query", "ibc", "client", "counterparty-info", "07-tendermint-1", "--home", c.home, "--output", "json", + }) + if err != nil { + sb.WriteString(fmt.Sprintf("=== %s ibc counterparty 07-tendermint-1: ERROR: %v (output: %s) ===\n", c.name, err, stdout2.String())) + } else { + sb.WriteString(fmt.Sprintf("=== %s ibc counterparty 07-tendermint-1 ===\n%s\n", c.name, stdout2.String())) + } + } + return sb.String() +} diff --git a/tests/e2e/e2e_vaas_test.go b/tests/e2e/e2e_vaas_test.go index 815b30d..ffde8a7 100644 --- a/tests/e2e/e2e_vaas_test.go +++ b/tests/e2e/e2e_vaas_test.go @@ -74,7 +74,6 @@ func (s *IntegrationTestSuite) testValidatorSetSync() { consumerVals, err := s.queryConsumerNetValidators() s.Require().NoError(err, "failed to query consumer validators") - // Extract pub keys and vp from both chains providerPubKeys, providerVP := s.extractPubKeys(providerVals) consumerPubKeys, consumerVP := s.extractPubKeys(consumerVals) @@ -83,8 +82,6 @@ func (s *IntegrationTestSuite) testValidatorSetSync() { s.Require().Equal(providerPubKeys[0], consumerPubKeys[0]) s.Require().Equal(providerVP[0], consumerVP[0]) - // Increase delegation of val on provider chain - // Get validator operator address stdout, _, err := s.dockerExec(s.providerValRes[0].Container.ID, []string{ providerBinary, "keys", "show", "val", "--bech", "val", "-a", "--home", providerHomePath, @@ -93,7 +90,6 @@ func (s *IntegrationTestSuite) testValidatorSetSync() { s.Require().NoError(err, "failed to get validator address") valAddr := strings.TrimSpace(stdout.String()) - // Delegate to trigger validator set change _, _, err = s.dockerExec(s.providerValRes[0].Container.ID, []string{ providerBinary, "tx", "staking", "delegate", valAddr, "1000000" + bondDenom, "--from", "user", @@ -105,29 +101,37 @@ func (s *IntegrationTestSuite) testValidatorSetSync() { }) s.Require().NoError(err, "failed to perform delegation") - // Check increase in VP for Val0 on Provider var providerVPAfter []uint64 - s.Require().Eventually( func() bool { + s.Require().Eventually(func() bool { providerValsAfter, err := s.queryProviderNetValidators() - s.Require().NoError(err, "failed to query provider validators") - _ , providerVPAfter = s.extractPubKeys(providerValsAfter) - return providerVPAfter[0] == providerVP[0] + 1 + if err != nil { + return false + } + _, providerVPAfter = s.extractPubKeys(providerValsAfter) + if len(providerVPAfter) == 0 { + return false + } + return providerVPAfter[0] == providerVP[0]+1 }, - 50*time.Second, - time.Second) - + 50*time.Second, + time.Second) // Check increase in VP for Val0 on Consumer var consumerVPAfter []uint64 s.Require().Eventually( func() bool { consumerValsAfter, err := s.queryConsumerNetValidators() - s.Require().NoError(err, "failed to query consumer validators") + if err != nil { + return false + } _, consumerVPAfter = s.extractPubKeys(consumerValsAfter) + if len(consumerVPAfter) == 0 { + return false + } return consumerVPAfter[0] == providerVPAfter[0] }, - 50*time.Second, - time.Second, + 3*time.Minute, + 3*time.Second, "consumer validator set is not updated", ) }) diff --git a/tests/e2e/scripts/hermes-init.sh b/tests/e2e/scripts/hermes-init.sh deleted file mode 100755 index 871140a..0000000 --- a/tests/e2e/scripts/hermes-init.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# Hermes relayer initialization script for VAAS e2e tests. -# This script is mounted into the Hermes container and executed -# as the entrypoint. It imports relayer keys and starts Hermes. - -set -e - -PROVIDER_CHAIN_ID="${PROVIDER_CHAIN_ID:-provider-e2e}" -CONSUMER_CHAIN_ID="${CONSUMER_CHAIN_ID:-consumer-e2e}" -RELAYER_MNEMONIC="${RELAYER_MNEMONIC:-abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art}" - -echo "Waiting for chains to be ready..." -sleep 5 - -# Import relayer keys for both chains -echo "$RELAYER_MNEMONIC" > /tmp/mnemonic.txt -hermes keys add --chain "$PROVIDER_CHAIN_ID" --mnemonic-file /tmp/mnemonic.txt --key-name relayer 2>/dev/null || true -hermes keys add --chain "$CONSUMER_CHAIN_ID" --mnemonic-file /tmp/mnemonic.txt --key-name relayer 2>/dev/null || true -rm -f /tmp/mnemonic.txt - -echo "Hermes keys configured, starting relayer..." -hermes start diff --git a/tests/e2e/testdata/create_consumer.json b/tests/e2e/testdata/create_consumer.json index ec544f2..48aeb1c 100644 --- a/tests/e2e/testdata/create_consumer.json +++ b/tests/e2e/testdata/create_consumer.json @@ -15,8 +15,7 @@ "spawn_time": "2024-01-01T00:00:00Z", "unbonding_period": 1728000000000000, "vaas_timeout_period": 2419200000000000, - "historical_entries": 10000, - "connection_id": "" + "historical_entries": 10000 }, "infraction_parameters": { "double_sign": { diff --git a/tests/e2e/testdata/hermes_config.toml b/tests/e2e/testdata/hermes_config.toml deleted file mode 100644 index efbb1c7..0000000 --- a/tests/e2e/testdata/hermes_config.toml +++ /dev/null @@ -1,112 +0,0 @@ -[global] -log_level = 'info' - -[mode] -[mode.clients] -enabled = true -refresh = true -misbehaviour = false - -[mode.connections] -enabled = true - -[mode.channels] -enabled = true - -[mode.packets] -enabled = true -clear_interval = 100 -clear_on_start = true -tx_confirmation = false - -[rest] -enabled = true -host = '0.0.0.0' -port = 3031 - -[telemetry] -enabled = false -host = '127.0.0.1' -port = 3001 - -[[chains]] -id = 'PROVIDER_CHAIN_ID' -type = 'CosmosSdk' -rpc_addr = 'http://PROVIDER_CHAIN_ID-val0:26657' -grpc_addr = 'http://PROVIDER_CHAIN_ID-val0:9090' -rpc_timeout = '10s' -trusted_node = true -account_prefix = 'cosmos' -key_name = 'relayer' -key_store_type = 'Test' -key_store_folder = '/home/hermes/.hermes/keys' -store_prefix = 'ibc' -default_gas = 100000 -max_gas = 3000000 -gas_multiplier = 1.2 -max_msg_num = 30 -max_tx_size = 180000 -clock_drift = '5s' -max_block_time = '30s' -ccv_consumer_chain = false - -[chains.event_source] -mode = 'push' -url = 'ws://PROVIDER_CHAIN_ID-val0:26657/websocket' -batch_delay = '500ms' - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.01 -denom = 'uatone' - -[chains.packet_filter] -policy = 'allow' -list = [['consumer', '*'], ['provider', '*'], ['transfer', '*']] - -[chains.address_type] -derivation = 'cosmos' - -[[chains]] -id = 'CONSUMER_CHAIN_ID' -type = 'CosmosSdk' -rpc_addr = 'http://CONSUMER_CHAIN_ID-val0:26657' -grpc_addr = 'http://CONSUMER_CHAIN_ID-val0:9090' -rpc_timeout = '10s' -trusted_node = true -account_prefix = 'cosmos' -key_name = 'relayer' -key_store_type = 'Test' -key_store_folder = '/home/hermes/.hermes/keys' -store_prefix = 'ibc' -default_gas = 100000 -max_gas = 3000000 -gas_multiplier = 1.2 -max_msg_num = 30 -max_tx_size = 180000 -clock_drift = '5s' -max_block_time = '30s' -ccv_consumer_chain = false - -[chains.event_source] -mode = 'push' -url = 'ws://CONSUMER_CHAIN_ID-val0:26657/websocket' -batch_delay = '500ms' - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.01 -denom = 'uatone' - -[chains.packet_filter] -policy = 'allow' -list = [['consumer', '*'], ['provider', '*'], ['transfer', '*']] - -[chains.address_type] -derivation = 'cosmos' diff --git a/testutil/crypto/crypto.go b/testutil/crypto/crypto.go index bd3ad46..b2c17f5 100644 --- a/testutil/crypto/crypto.go +++ b/testutil/crypto/crypto.go @@ -50,7 +50,7 @@ func NewCryptoIdentityFromIntSeed(i int) *CryptoIdentity { // GenMultipleCryptoIds generates and returns multiple CryptoIdentities from a starting int seed. func GenMultipleCryptoIds(num, fromIntSeed int) []*CryptoIdentity { ids := make([]*CryptoIdentity, num) - for i := 0; i < num; i++ { + for i := range num { ids[i] = NewCryptoIdentityFromIntSeed(fromIntSeed + i) } return ids diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go deleted file mode 100644 index f7bced3..0000000 --- a/testutil/keeper/expectations.go +++ /dev/null @@ -1,216 +0,0 @@ -package keeper - -import ( - time "time" - - providertypes "github.com/allinbits/vaas/x/vaas/provider/types" - "github.com/allinbits/vaas/x/vaas/types" - "go.uber.org/mock/gomock" - - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" - ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" - - math "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -// -// A file containing groups of commonly used mock expectations. -// Note: Each group of mock expectations is associated with a single method -// that may be called during unit tests. -// - -// GetMocksForCreateConsumerClient returns mock expectations needed to call CreateConsumerClient(). -func GetMocksForCreateConsumerClient(ctx sdk.Context, mocks *MockedKeepers, - expectedChainID string, expectedLatestHeight clienttypes.Height, -) []any { - return []any{ - mocks.MockClientKeeper.EXPECT().CreateClient( - gomock.Any(), - gomock.Any(), - gomock.Any(), - gomock.Any(), - ).Return("clientID", nil).Times(1), - } -} - -// GetMocksForMakeConsumerGenesis returns mock expectations needed to call MakeConsumerGenesis(). -func GetMocksForMakeConsumerGenesis(ctx sdk.Context, mocks *MockedKeepers, - unbondingTimeToInject time.Duration, revisionHeight int64, -) []any { - return []any{ - mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTimeToInject, nil).Times(1), - mocks.MockStakingKeeper.EXPECT().GetHistoricalInfo(gomock.Any(), revisionHeight).Times(1), - } -} - -// GetMocksForSetConsumerChain returns mock expectations needed to call SetConsumerChain(). -func GetMocksForSetConsumerChain(ctx sdk.Context, mocks *MockedKeepers, - chainIDToInject string, -) []any { - return []any{ - mocks.MockChannelKeeper.EXPECT().GetChannel(ctx, types.ProviderPortID, gomock.Any()).Return( - channeltypes.Channel{ - State: channeltypes.OPEN, - ConnectionHops: []string{"connectionID"}, - }, - true, - ).Times(1), - mocks.MockConnectionKeeper.EXPECT().GetConnection(ctx, "connectionID").Return( - conntypes.ConnectionEnd{ClientId: "clientID"}, true, - ).Times(1), - mocks.MockClientKeeper.EXPECT().GetClientState(ctx, "clientID").Return( - &ibctmtypes.ClientState{ChainId: chainIDToInject}, true, - ).Times(1), - } -} - -// GetMocksForDeleteConsumerChain returns mock expectations needed to call `DeleteConsumerChain` -func GetMocksForDeleteConsumerChain(ctx sdk.Context, mocks *MockedKeepers) []any { - return []any{ - mocks.MockChannelKeeper.EXPECT().GetChannel(gomock.Any(), types.ProviderPortID, "channelID").Return( - channeltypes.Channel{State: channeltypes.OPEN}, true, - ).Times(1), - mocks.MockChannelKeeper.EXPECT().ChanCloseInit(gomock.Any(), types.ProviderPortID, "channelID").Times(1), - } -} - -func GetMocksForHandleSlashPacket(ctx sdk.Context, mocks MockedKeepers, - expectedProviderValConsAddr providertypes.ProviderConsAddress, - valToReturn stakingtypes.Validator, expectJailing bool, -) []any { - // These first two calls are always made. - calls := []any{ - mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( - ctx, expectedProviderValConsAddr.ToSdkConsAddr()).Return( - valToReturn, nil, - ).Times(1), - - mocks.MockSlashingKeeper.EXPECT().IsTombstoned(ctx, - expectedProviderValConsAddr.ToSdkConsAddr()).Return(false).Times(1), - } - - if expectJailing { - // slash - calls = append(calls, mocks.MockStakingKeeper.EXPECT().SlashWithInfractionReason(ctx, expectedProviderValConsAddr.ToSdkConsAddr(), gomock.Any(), - gomock.Any(), gomock.Any(), gomock.Any()).Return(math.NewInt(0), nil).Times(1)) - // jail - calls = append(calls, mocks.MockStakingKeeper.EXPECT().Jail( - gomock.Eq(ctx), - gomock.Eq(expectedProviderValConsAddr.ToSdkConsAddr()), - ).Return(nil)) - - // JailUntil is set in this code path. - calls = append(calls, mocks.MockSlashingKeeper.EXPECT().JailUntil(ctx, - expectedProviderValConsAddr.ToSdkConsAddr(), gomock.Any()).Return(nil).Times(1)) - } - - return calls -} - -func ExpectLatestConsensusStateMock(ctx sdk.Context, mocks MockedKeepers, clientID string, consState *ibctmtypes.ConsensusState) *gomock.Call { - return mocks.MockClientKeeper.EXPECT(). - GetLatestClientConsensusState(ctx, clientID).Return(consState, true).Times(1) -} - -func ExpectCreateClientMock(ctx sdk.Context, mocks MockedKeepers, clientType, clientID string, - clientState, consState []byte, -) *gomock.Call { - return mocks.MockClientKeeper.EXPECT().CreateClient(ctx, clientType, clientState, consState).Return(clientID, - nil).Times(1) -} - -func GetMocksForSendIBCPacket(ctx sdk.Context, mocks MockedKeepers, channelID string, times int) []any { - return []any{ - mocks.MockChannelKeeper.EXPECT().GetChannel(ctx, types.ConsumerPortID, - "consumerCCVChannelID").Return(channeltypes.Channel{}, true).Times(times), - mocks.MockChannelKeeper.EXPECT().SendPacket(ctx, - types.ConsumerPortID, - "consumerCCVChannelID", - gomock.Any(), - gomock.Any(), - gomock.Any(), - ).Return(uint64(888), nil).Times(times), - } -} - -func GetMocksForSlashValidator( - ctx sdk.Context, - mocks MockedKeepers, - validator stakingtypes.Validator, - consAddr sdk.ConsAddress, - undelegations []stakingtypes.UnbondingDelegation, - redelegations []stakingtypes.Redelegation, - powerReduction math.Int, - slashFraction math.LegacyDec, - currentPower, - expectedInfractionHeight, - expectedSlashPower int64, -) []any { - return []any{ - mocks.MockStakingKeeper.EXPECT(). - GetUnbondingDelegationsFromValidator(ctx, validator.GetOperator()). - Return(undelegations), - mocks.MockStakingKeeper.EXPECT(). - GetRedelegationsFromSrcValidator(ctx, validator.GetOperator()). - Return(redelegations), - mocks.MockStakingKeeper.EXPECT(). - GetLastValidatorPower(ctx, validator.GetOperator()). - Return(currentPower), - mocks.MockStakingKeeper.EXPECT(). - PowerReduction(ctx). - Return(powerReduction), - mocks.MockStakingKeeper.EXPECT(). - SlashUnbondingDelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn( - func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ math.LegacyDec) math.Int { - sum := math.NewInt(0) - for _, r := range undelegation.Entries { - if r.IsMature(ctx.BlockTime()) { - continue - } - sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) - } - return sum - }).AnyTimes(), - mocks.MockStakingKeeper.EXPECT(). - SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn( - func(_ sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ math.LegacyDec) math.Int { - sum := math.NewInt(0) - for _, r := range redelegation.Entries { - if r.IsMature(ctx.BlockTime()) { - continue - } - sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) - } - return sum - }).AnyTimes(), - mocks.MockSlashingKeeper.EXPECT(). - SlashFractionDoubleSign(ctx). - Return(slashFraction), - mocks.MockStakingKeeper.EXPECT(). - SlashWithInfractionReason(ctx, consAddr, expectedInfractionHeight, expectedSlashPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN). - Times(1), - } -} - -// SetupMocksForLastBondedValidatorsExpectation sets up the expectation for the `GetBondedValidatorsByPower` and `MaxValidators` methods of the `mockStakingKeeper` object. -// These are needed in particular when calling `GetLastBondedValidators` from the provider keeper. -// Times is the number of times the expectation should be called. Provide -1 for `AnyTimes“. -func SetupMocksForLastBondedValidatorsExpectation(mockStakingKeeper *MockStakingKeeper, maxValidators uint32, vals []stakingtypes.Validator, times int) { - validatorsCall := mockStakingKeeper.EXPECT().GetBondedValidatorsByPower(gomock.Any()).Return(vals, nil) - maxValidatorsCall := mockStakingKeeper.EXPECT().MaxValidators(gomock.Any()).Return(maxValidators, nil) - - if times == -1 { - validatorsCall.AnyTimes() - maxValidatorsCall.AnyTimes() - } else { - validatorsCall.Times(times) - maxValidatorsCall.Times(times) - } -} diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks.go index 4141f34..d8850f5 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks.go @@ -19,8 +19,7 @@ import ( types "github.com/cosmos/cosmos-sdk/types" types0 "github.com/cosmos/cosmos-sdk/x/staking/types" types1 "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - types2 "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - types3 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" + clientv2types "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" exported "github.com/cosmos/ibc-go/v10/modules/core/exported" gomock "go.uber.org/mock/gomock" ) @@ -455,129 +454,6 @@ func (mr *MockSlashingKeeperMockRecorder) Tombstone(arg0, arg1 any) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tombstone", reflect.TypeOf((*MockSlashingKeeper)(nil).Tombstone), arg0, arg1) } -// MockChannelKeeper is a mock of ChannelKeeper interface. -type MockChannelKeeper struct { - ctrl *gomock.Controller - recorder *MockChannelKeeperMockRecorder - isgomock struct{} -} - -// MockChannelKeeperMockRecorder is the mock recorder for MockChannelKeeper. -type MockChannelKeeperMockRecorder struct { - mock *MockChannelKeeper -} - -// NewMockChannelKeeper creates a new mock instance. -func NewMockChannelKeeper(ctrl *gomock.Controller) *MockChannelKeeper { - mock := &MockChannelKeeper{ctrl: ctrl} - mock.recorder = &MockChannelKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChannelKeeper) EXPECT() *MockChannelKeeperMockRecorder { - return m.recorder -} - -// ChanCloseInit mocks base method. -func (m *MockChannelKeeper) ChanCloseInit(ctx types.Context, portID, channelID string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ChanCloseInit", ctx, portID, channelID) - ret0, _ := ret[0].(error) - return ret0 -} - -// ChanCloseInit indicates an expected call of ChanCloseInit. -func (mr *MockChannelKeeperMockRecorder) ChanCloseInit(ctx, portID, channelID any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChanCloseInit", reflect.TypeOf((*MockChannelKeeper)(nil).ChanCloseInit), ctx, portID, channelID) -} - -// GetChannel mocks base method. -func (m *MockChannelKeeper) GetChannel(ctx types.Context, srcPort, srcChan string) (types3.Channel, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChannel", ctx, srcPort, srcChan) - ret0, _ := ret[0].(types3.Channel) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetChannel indicates an expected call of GetChannel. -func (mr *MockChannelKeeperMockRecorder) GetChannel(ctx, srcPort, srcChan any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannel", reflect.TypeOf((*MockChannelKeeper)(nil).GetChannel), ctx, srcPort, srcChan) -} - -// GetChannelConnection mocks base method. -func (m *MockChannelKeeper) GetChannelConnection(ctx types.Context, portID, channelID string) (string, types2.ConnectionEnd, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChannelConnection", ctx, portID, channelID) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(types2.ConnectionEnd) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetChannelConnection indicates an expected call of GetChannelConnection. -func (mr *MockChannelKeeperMockRecorder) GetChannelConnection(ctx, portID, channelID any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannelConnection", reflect.TypeOf((*MockChannelKeeper)(nil).GetChannelConnection), ctx, portID, channelID) -} - -// SendPacket mocks base method. -func (m *MockChannelKeeper) SendPacket(ctx types.Context, sourcePort, sourceChannel string, timeoutHeight types1.Height, timeoutTimestamp uint64, data []byte) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendPacket", ctx, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// SendPacket indicates an expected call of SendPacket. -func (mr *MockChannelKeeperMockRecorder) SendPacket(ctx, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacket", reflect.TypeOf((*MockChannelKeeper)(nil).SendPacket), ctx, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) -} - -// MockConnectionKeeper is a mock of ConnectionKeeper interface. -type MockConnectionKeeper struct { - ctrl *gomock.Controller - recorder *MockConnectionKeeperMockRecorder - isgomock struct{} -} - -// MockConnectionKeeperMockRecorder is the mock recorder for MockConnectionKeeper. -type MockConnectionKeeperMockRecorder struct { - mock *MockConnectionKeeper -} - -// NewMockConnectionKeeper creates a new mock instance. -func NewMockConnectionKeeper(ctrl *gomock.Controller) *MockConnectionKeeper { - mock := &MockConnectionKeeper{ctrl: ctrl} - mock.recorder = &MockConnectionKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockConnectionKeeper) EXPECT() *MockConnectionKeeperMockRecorder { - return m.recorder -} - -// GetConnection mocks base method. -func (m *MockConnectionKeeper) GetConnection(ctx types.Context, connectionID string) (types2.ConnectionEnd, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetConnection", ctx, connectionID) - ret0, _ := ret[0].(types2.ConnectionEnd) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetConnection indicates an expected call of GetConnection. -func (mr *MockConnectionKeeperMockRecorder) GetConnection(ctx, connectionID any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConnection", reflect.TypeOf((*MockConnectionKeeper)(nil).GetConnection), ctx, connectionID) -} - // MockClientKeeper is a mock of ClientKeeper interface. type MockClientKeeper struct { ctrl *gomock.Controller @@ -647,19 +523,18 @@ func (mr *MockClientKeeperMockRecorder) GetClientState(ctx, clientID any) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClientState", reflect.TypeOf((*MockClientKeeper)(nil).GetClientState), ctx, clientID) } -// GetLatestClientConsensusState mocks base method. -func (m *MockClientKeeper) GetLatestClientConsensusState(ctx types.Context, clientID string) (exported.ConsensusState, bool) { +// GetClientStatus mocks base method. +func (m *MockClientKeeper) GetClientStatus(ctx types.Context, clientID string) exported.Status { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLatestClientConsensusState", ctx, clientID) - ret0, _ := ret[0].(exported.ConsensusState) - ret1, _ := ret[1].(bool) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetClientStatus", ctx, clientID) + ret0, _ := ret[0].(exported.Status) + return ret0 } -// GetLatestClientConsensusState indicates an expected call of GetLatestClientConsensusState. -func (mr *MockClientKeeperMockRecorder) GetLatestClientConsensusState(ctx, clientID any) *gomock.Call { +// GetClientStatus indicates an expected call of GetClientStatus. +func (mr *MockClientKeeperMockRecorder) GetClientStatus(ctx, clientID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestClientConsensusState", reflect.TypeOf((*MockClientKeeper)(nil).GetLatestClientConsensusState), ctx, clientID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClientStatus", reflect.TypeOf((*MockClientKeeper)(nil).GetClientStatus), ctx, clientID) } // GetStoreProvider mocks base method. @@ -676,6 +551,69 @@ func (mr *MockClientKeeperMockRecorder) GetStoreProvider() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStoreProvider", reflect.TypeOf((*MockClientKeeper)(nil).GetStoreProvider)) } +// IterateClientStates mocks base method. +func (m *MockClientKeeper) IterateClientStates(ctx types.Context, storePrefix []byte, cb func(string, exported.ClientState) bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "IterateClientStates", ctx, storePrefix, cb) +} + +// IterateClientStates indicates an expected call of IterateClientStates. +func (mr *MockClientKeeperMockRecorder) IterateClientStates(ctx, storePrefix, cb any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IterateClientStates", reflect.TypeOf((*MockClientKeeper)(nil).IterateClientStates), ctx, storePrefix, cb) +} + +// MockClientV2Keeper is a mock of ClientV2Keeper interface. +type MockClientV2Keeper struct { + ctrl *gomock.Controller + recorder *MockClientV2KeeperMockRecorder + isgomock struct{} +} + +// MockClientV2KeeperMockRecorder is the mock recorder for MockClientV2Keeper. +type MockClientV2KeeperMockRecorder struct { + mock *MockClientV2Keeper +} + +// NewMockClientV2Keeper creates a new mock instance. +func NewMockClientV2Keeper(ctrl *gomock.Controller) *MockClientV2Keeper { + mock := &MockClientV2Keeper{ctrl: ctrl} + mock.recorder = &MockClientV2KeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClientV2Keeper) EXPECT() *MockClientV2KeeperMockRecorder { + return m.recorder +} + +// GetClientCounterparty mocks base method. +func (m *MockClientV2Keeper) GetClientCounterparty(ctx types.Context, clientID string) (clientv2types.CounterpartyInfo, bool) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetClientCounterparty", ctx, clientID) + ret0, _ := ret[0].(clientv2types.CounterpartyInfo) + ret1, _ := ret[1].(bool) + return ret0, ret1 +} + +// GetClientCounterparty indicates an expected call of GetClientCounterparty. +func (mr *MockClientV2KeeperMockRecorder) GetClientCounterparty(ctx, clientID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClientCounterparty", reflect.TypeOf((*MockClientV2Keeper)(nil).GetClientCounterparty), ctx, clientID) +} + +// SetClientCounterparty mocks base method. +func (m *MockClientV2Keeper) SetClientCounterparty(ctx types.Context, clientID string, counterparty clientv2types.CounterpartyInfo) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetClientCounterparty", ctx, clientID, counterparty) +} + +// SetClientCounterparty indicates an expected call of SetClientCounterparty. +func (mr *MockClientV2KeeperMockRecorder) SetClientCounterparty(ctx, clientID, counterparty any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClientCounterparty", reflect.TypeOf((*MockClientV2Keeper)(nil).SetClientCounterparty), ctx, clientID, counterparty) +} + // MockConsumerHooks is a mock of ConsumerHooks interface. type MockConsumerHooks struct { ctrl *gomock.Controller @@ -817,42 +755,3 @@ func (mr *MockAccountKeeperMockRecorder) GetModuleAccount(ctx, name any) *gomock mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModuleAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetModuleAccount), ctx, name) } - -// MockIBCCoreKeeper is a mock of IBCCoreKeeper interface. -type MockIBCCoreKeeper struct { - ctrl *gomock.Controller - recorder *MockIBCCoreKeeperMockRecorder - isgomock struct{} -} - -// MockIBCCoreKeeperMockRecorder is the mock recorder for MockIBCCoreKeeper. -type MockIBCCoreKeeperMockRecorder struct { - mock *MockIBCCoreKeeper -} - -// NewMockIBCCoreKeeper creates a new mock instance. -func NewMockIBCCoreKeeper(ctrl *gomock.Controller) *MockIBCCoreKeeper { - mock := &MockIBCCoreKeeper{ctrl: ctrl} - mock.recorder = &MockIBCCoreKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIBCCoreKeeper) EXPECT() *MockIBCCoreKeeperMockRecorder { - return m.recorder -} - -// ChannelOpenInit mocks base method. -func (m *MockIBCCoreKeeper) ChannelOpenInit(goCtx context.Context, msg *types3.MsgChannelOpenInit) (*types3.MsgChannelOpenInitResponse, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ChannelOpenInit", goCtx, msg) - ret0, _ := ret[0].(*types3.MsgChannelOpenInitResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ChannelOpenInit indicates an expected call of ChannelOpenInit. -func (mr *MockIBCCoreKeeperMockRecorder) ChannelOpenInit(goCtx, msg any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChannelOpenInit", reflect.TypeOf((*MockIBCCoreKeeper)(nil).ChannelOpenInit), goCtx, msg) -} diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index e269d13..4c00289 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -4,12 +4,10 @@ import ( "crypto/rand" "encoding/binary" "testing" - "time" consumerkeeper "github.com/allinbits/vaas/x/vaas/consumer/keeper" consumertypes "github.com/allinbits/vaas/x/vaas/consumer/types" providerkeeper "github.com/allinbits/vaas/x/vaas/provider/keeper" - providertypes "github.com/allinbits/vaas/x/vaas/provider/types" "github.com/allinbits/vaas/x/vaas/types" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -17,10 +15,9 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + clientv2types "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" "cosmossdk.io/log" - math "cosmossdk.io/math" "cosmossdk.io/store" "cosmossdk.io/store/metrics" storetypes "cosmossdk.io/store/types" @@ -30,12 +27,12 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // InMemKeeperParams parameters needed to instantiate an in-memory keeper @@ -58,7 +55,7 @@ func NewInMemKeeperParams(tb testing.TB) InMemKeeperParams { require.NoError(tb, stateStore.LoadLatestVersion()) registry := codectypes.NewInterfaceRegistry() - cryptocodec.RegisterInterfaces(registry) // Public key implementation registered here + cryptocodec.RegisterInterfaces(registry) cdc := codec.NewProtoCodec(registry) ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) @@ -72,29 +69,27 @@ func NewInMemKeeperParams(tb testing.TB) InMemKeeperParams { // A struct holding pointers to any mocked external keeper needed for provider/consumer keeper setup. type MockedKeepers struct { - *MockChannelKeeper - *MockConnectionKeeper *MockClientKeeper + *MockClientV2Keeper *MockStakingKeeper *MockSlashingKeeper *MockAccountKeeper *MockBankKeeper - *MockIBCCoreKeeper - // *MockGovKeeper } // NewMockedKeepers instantiates a struct with pointers to properly instantiated mocked keepers. func NewMockedKeepers(ctrl *gomock.Controller) MockedKeepers { - return MockedKeepers{ - MockChannelKeeper: NewMockChannelKeeper(ctrl), - MockConnectionKeeper: NewMockConnectionKeeper(ctrl), - MockClientKeeper: NewMockClientKeeper(ctrl), - MockStakingKeeper: NewMockStakingKeeper(ctrl), - MockSlashingKeeper: NewMockSlashingKeeper(ctrl), - MockAccountKeeper: NewMockAccountKeeper(ctrl), - MockBankKeeper: NewMockBankKeeper(ctrl), - MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl), + mocks := MockedKeepers{ + MockClientKeeper: NewMockClientKeeper(ctrl), + MockClientV2Keeper: NewMockClientV2Keeper(ctrl), + MockStakingKeeper: NewMockStakingKeeper(ctrl), + MockSlashingKeeper: NewMockSlashingKeeper(ctrl), + MockAccountKeeper: NewMockAccountKeeper(ctrl), + MockBankKeeper: NewMockBankKeeper(ctrl), } + mocks.MockClientV2Keeper.EXPECT().GetClientCounterparty(gomock.Any(), gomock.Any()).Return(clientv2types.CounterpartyInfo{}, false).AnyTimes() + mocks.MockClientV2Keeper.EXPECT().SetClientCounterparty(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + return mocks } // NewInMemProviderKeeper instantiates an in-mem provider keeper from params and mocked keepers @@ -103,14 +98,12 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi return providerkeeper.NewKeeper( params.Cdc, storeService, - mocks.MockChannelKeeper, - mocks.MockConnectionKeeper, mocks.MockClientKeeper, + mocks.MockClientV2Keeper, mocks.MockStakingKeeper, mocks.MockSlashingKeeper, mocks.MockAccountKeeper, mocks.MockBankKeeper, - // mocks.MockGovKeeper, govkeeper.Keeper{}, // HACK: to make parts of the test work authtypes.NewModuleAddress(govtypes.ModuleName).String(), address.NewBech32Codec("cosmosvaloper"), @@ -126,13 +119,11 @@ func NewInMemConsumerKeeper(params InMemKeeperParams, mocks MockedKeepers) consu return consumerkeeper.NewKeeper( params.Cdc, storeService, - mocks.MockChannelKeeper, - mocks.MockConnectionKeeper, mocks.MockClientKeeper, + mocks.MockClientV2Keeper, mocks.MockSlashingKeeper, mocks.MockBankKeeper, mocks.MockAccountKeeper, - mocks.MockIBCCoreKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), address.NewBech32Codec("cosmosvaloper"), @@ -166,103 +157,23 @@ func GetConsumerKeeperAndCtx(t *testing.T, params InMemKeeperParams) ( return NewInMemConsumerKeeper(params, mocks), params.Ctx, ctrl, mocks } -type PrivateKey struct { - PrivKey cryptotypes.PrivKey +func ExpectCreateClientMock(ctx sdk.Context, mocks MockedKeepers, clientType, clientID string, + clientState, consState []byte, +) *gomock.Call { + return mocks.MockClientKeeper.EXPECT().CreateClient(ctx, clientType, clientState, consState).Return(clientID, + nil).Times(1) } -// SetupForDeleteConsumerChain registers expected mock calls and corresponding state setup -// which assert that a consumer chain was properly setup to be later deleted with `DeleteConsumerChain`. -// Note: This function only setups and tests that we correctly setup a consumer chain that we could later delete when -// calling `DeleteConsumerChain` -- this does NOT necessarily mean that the consumer chain is deleted. -// Also see `TestProviderStateIsCleanedAfterConsumerChainIsDeleted`. -func SetupForDeleteConsumerChain(t *testing.T, ctx sdk.Context, - providerKeeper *providerkeeper.Keeper, mocks MockedKeepers, - consumerId string, -) { - t.Helper() - - expectations := GetMocksForCreateConsumerClient(ctx, &mocks, - "chainID", clienttypes.NewHeight(0, 5)) - expectations = append(expectations, GetMocksForSetConsumerChain(ctx, &mocks, "chainID")...) - - gomock.InOrder(expectations...) - - providerKeeper.SetConsumerChainId(ctx, consumerId, "chainID") - err := providerKeeper.SetConsumerMetadata(ctx, consumerId, GetTestConsumerMetadata()) - require.NoError(t, err) - err = providerKeeper.SetConsumerInitializationParameters(ctx, consumerId, GetTestInitializationParameters()) - require.NoError(t, err) - // Power shaping parameters removed - all validators validate all consumers +func SetupMocksForLastBondedValidatorsExpectation(mockStakingKeeper *MockStakingKeeper, maxValidators uint32, vals []stakingtypes.Validator, times int) { + validatorsCall := mockStakingKeeper.EXPECT().GetBondedValidatorsByPower(gomock.Any()).Return(vals, nil) + maxValidatorsCall := mockStakingKeeper.EXPECT().MaxValidators(gomock.Any()).Return(maxValidators, nil) - // set the chain to initialized so that we can create a consumer client - providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_INITIALIZED) - - err = providerKeeper.CreateConsumerClient(ctx, consumerId, []byte{}) - require.NoError(t, err) - // set the mapping consumer ID <> client ID for the consumer chain - providerKeeper.SetConsumerClientId(ctx, consumerId, "clientID") - // set the channel ID for the consumer chain - err = providerKeeper.SetConsumerChain(ctx, "channelID") - require.NoError(t, err) - - // set the chain to stopped sto the chain can be deleted - providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_STOPPED) -} - -// TestProviderStateIsCleanedAfterConsumerChainIsDeleted executes test assertions for the provider's state being cleaned -// after a deleted consumer chain. -func TestProviderStateIsCleanedAfterConsumerChainIsDeleted(t *testing.T, ctx sdk.Context, providerKeeper providerkeeper.Keeper, - consumerId, expectedChannelID string, expErr bool, -) { - t.Helper() - _, found := providerKeeper.GetConsumerClientId(ctx, consumerId) - require.False(t, found) - _, found = providerKeeper.GetConsumerIdToChannelId(ctx, consumerId) - require.False(t, found) - _, found = providerKeeper.GetChannelIdToConsumerId(ctx, expectedChannelID) - require.False(t, found) - _, found = providerKeeper.GetInitChainHeight(ctx, consumerId) - require.False(t, found) - - // test key assignment state is cleaned - require.Empty(t, providerKeeper.GetAllValidatorConsumerPubKeys(ctx, &consumerId)) - require.Empty(t, providerKeeper.GetAllValidatorsByConsumerAddr(ctx, &consumerId)) - require.Empty(t, providerKeeper.GetAllConsumerAddrsToPrune(ctx, consumerId)) - require.Zero(t, providerKeeper.GetEquivocationEvidenceMinHeight(ctx, consumerId)) -} - -func GetTestConsumerMetadata() providertypes.ConsumerMetadata { - return providertypes.ConsumerMetadata{ - Name: "chain name", - Description: "description", - Metadata: "metadata", - } -} - -func GetTestInitializationParameters() providertypes.ConsumerInitializationParameters { - return providertypes.ConsumerInitializationParameters{ - InitialHeight: clienttypes.NewHeight(0, 5), - GenesisHash: []byte("gen_hash"), - BinaryHash: []byte("bin_hash"), - SpawnTime: time.Now().UTC(), - HistoricalEntries: types.DefaultHistoricalEntries, - VaasTimeoutPeriod: types.DefaultVAASTimeoutPeriod, - UnbondingPeriod: types.DefaultConsumerUnbondingPeriod, - } -} - -func GetTestInfractionParameters() providertypes.InfractionParameters { - return providertypes.InfractionParameters{ - DoubleSign: &providertypes.SlashJailParameters{ - JailDuration: 1200 * time.Second, - SlashFraction: math.LegacyNewDecWithPrec(5, 1), // 0.5 - Tombstone: true, - }, - Downtime: &providertypes.SlashJailParameters{ - JailDuration: 600 * time.Second, - SlashFraction: math.LegacyNewDec(0), - Tombstone: false, - }, + if times == -1 { + validatorsCall.AnyTimes() + maxValidatorsCall.AnyTimes() + } else { + validatorsCall.Times(times) + maxValidatorsCall.Times(times) } } @@ -277,13 +188,3 @@ func GetNewCrossChainValidator(t *testing.T) consumertypes.CrossChainValidator { require.NoError(t, err) return validator } - -// Must panics if err is not nil, otherwise returns v. -// This is useful to get a value from a function that returns a value and an error -// in a single line. -func Must[T any](v T, err error) T { - if err != nil { - panic(err) - } - return v -} diff --git a/x/vaas/consumer/ibc_module.go b/x/vaas/consumer/ibc_module.go index 62b54ab..1a77aa2 100644 --- a/x/vaas/consumer/ibc_module.go +++ b/x/vaas/consumer/ibc_module.go @@ -3,15 +3,13 @@ package consumer import ( "fmt" "strconv" - "strings" "github.com/allinbits/vaas/x/vaas/consumer/keeper" consumertypes "github.com/allinbits/vaas/x/vaas/consumer/types" - "github.com/allinbits/vaas/x/vaas/types" + vaastypes "github.com/allinbits/vaas/x/vaas/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" - ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/ibc-go/v10/modules/core/api" errorsmod "cosmossdk.io/errors" @@ -19,262 +17,128 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// OnChanOpenInit implements the IBCModule interface -// this function is called by the relayer. -func (am AppModule) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - // set to the default version if the provided version is empty according to the ICS26 spec - // https://github.com/cosmos/ibc/blob/main/spec/core/ics-026-routing-module/README.md#technical-specification - if strings.TrimSpace(version) == "" { - version = types.Version - } - - // ensure provider channel hasn't already been created - if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok { - return "", errorsmod.Wrapf(types.ErrDuplicateChannel, - "provider channel: %s already set", providerChannel) - } - - // Validate parameters - if err := validateVAASChannelParams( - ctx, am.keeper, order, portID, version, - ); err != nil { - return "", err - } - - // ensure the counterparty port ID matches the expected provider port ID - if counterparty.PortId != types.ProviderPortID { - return "", errorsmod.Wrapf(porttypes.ErrInvalidPort, - "invalid counterparty port: %s, expected %s", counterparty.PortId, types.ProviderPortID) - } - - if err := am.keeper.VerifyProviderChain(ctx, connectionHops); err != nil { - return "", err - } - - return version, nil -} - -// validateVAASChannelParams validates a VAAS channel -func validateVAASChannelParams( - ctx sdk.Context, - keeper keeper.Keeper, - order channeltypes.Order, - portID string, - version string, -) error { - // Only ordered channels allowed - if order != channeltypes.ORDERED { - return errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) - } - - // the port ID must match the port ID the VAAS module is bounded to - boundPort := keeper.GetPort(ctx) - if boundPort != portID { - return errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) - } - - // the version must match the expected version - if version != types.Version { - return errorsmod.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) - } - return nil -} - -// OnChanOpenTry implements the IBCModule interface -func (am AppModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - return "", errorsmod.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") -} - -// OnChanOpenAck implements the IBCModule interface -// Note: Distribution transfer channel initialization has been removed. -func (am AppModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - _ string, // Counter party channel ID is unused per spec - counterpartyMetadata string, -) error { - // ensure provider channel has not already been created - if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok { - return errorsmod.Wrapf(types.ErrDuplicateChannel, - "provider channel: %s already established", providerChannel) - } - - var md types.HandshakeMetadata - if err := (&md).Unmarshal([]byte(counterpartyMetadata)); err != nil { - return errorsmod.Wrapf(types.ErrInvalidHandshakeMetadata, - "error unmarshalling ibc-ack metadata: \n%v; \nmetadata: %v", err, counterpartyMetadata) - } - - if md.Version != types.Version { - return errorsmod.Wrapf(types.ErrInvalidVersion, - "invalid counterparty version: %s, expected %s", md.Version, types.Version) - } - - // Note: Distribution functionality has been removed, so we no longer - // store the provider fee pool address or initialize transfer channels. +var _ api.IBCModule = (*IBCModule)(nil) - return nil +type IBCModule struct { + keeper *keeper.Keeper } -// OnChanOpenConfirm implements the IBCModule interface -func (am AppModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - return errorsmod.Wrap(types.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") +func NewIBCModule(k *keeper.Keeper) IBCModule { + return IBCModule{keeper: k} } -// OnChanCloseInit implements the IBCModule interface -func (am AppModule) OnChanCloseInit( +func (im IBCModule) OnSendPacket( ctx sdk.Context, - portID, - channelID string, + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + signer sdk.AccAddress, ) error { - // allow relayers to close duplicate OPEN channels, if the provider channel has already been established - if providerChannel, ok := am.keeper.GetProviderChannel(ctx); ok && providerChannel != channelID { - return nil - } - return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") -} + im.keeper.Logger(ctx).Error("consumer attempted to send packet", + "sourceClient", sourceClient, + "destinationClient", destinationClient, + "sequence", sequence, + ) -// OnChanCloseConfirm implements the IBCModule interface -func (am AppModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - return nil + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "consumer does not send packets") } -// OnRecvPacket implements the IBCModule interface. A successful acknowledgement -// is returned if the packet data is successfully decoded and the receive application -// logic returns without error. -func (am AppModule) OnRecvPacket( +func (im IBCModule) OnRecvPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - _ sdk.AccAddress, -) ibcexported.Acknowledgement { - logger := am.keeper.Logger(ctx) - ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) - - var data types.ValidatorSetChangePacketData - var ackErr error - if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - ackErr = errorsmod.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal VSCPacket data") - logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence)) - ack = channeltypes.NewErrorAcknowledgement(ackErr) + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, +) channeltypesv2.RecvPacketResult { + logger := im.keeper.Logger(ctx) + + if payload.DestinationPort != vaastypes.ConsumerAppID { + logger.Error("invalid destination port", + "expected", vaastypes.ConsumerAppID, + "got", payload.DestinationPort, + ) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } } - // only attempt the application logic if the packet data - // was successfully decoded - if ack.Success() { - err := am.keeper.OnRecvVSCPacket(ctx, packet, data) - if err != nil { - ack = channeltypes.NewErrorAcknowledgement(err) - ackErr = err - logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence)) - } else { - logger.Info("successfully handled VSCPacket", "sequence", packet.Sequence) + var data vaastypes.ValidatorSetChangePacketData + if err := vaastypes.ModuleCdc.UnmarshalJSON(payload.Value, &data); err != nil { + ackErr := errorsmod.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal VSCPacket data") + logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, } } - eventAttributes := []sdk.Attribute{ - sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute(types.AttributeValSetUpdateID, strconv.Itoa(int(data.ValsetUpdateId))), - sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), + if err := im.keeper.OnRecvVSCPacketV2(ctx, sourceClient, data); err != nil { + logger.Error(fmt.Sprintf("%s sequence %d", err.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } } - if ackErr != nil { - eventAttributes = append(eventAttributes, sdk.NewAttribute(types.AttributeKeyAckError, ackErr.Error())) - } + logger.Info("successfully handled VSCPacket", + "sequence", sequence, + "sourceClient", sourceClient, + "vscID", data.ValsetUpdateId, + ) ctx.EventManager().EmitEvent( sdk.NewEvent( - types.EventTypePacket, - eventAttributes..., + vaastypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, vaastypes.ModuleName), + sdk.NewAttribute(vaastypes.AttributeValSetUpdateID, strconv.Itoa(int(data.ValsetUpdateId))), + sdk.NewAttribute(vaastypes.AttributeKeyAckSuccess, "true"), + sdk.NewAttribute("source_client", sourceClient), ), ) - // NOTE: acknowledgement will be written synchronously during IBC handler execution. - return ack + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Success, + Acknowledgement: []byte{byte(1)}, + } } -// OnAcknowledgementPacket implements the IBCModule interface -func (am AppModule) OnAcknowledgementPacket( +func (im IBCModule) OnTimeoutPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - acknowledgement []byte, - _ sdk.AccAddress, + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, ) error { - var ack channeltypes.Acknowledgement - if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal consumer packet acknowledgement: %v", err) - } - - if err := am.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { - return err - } + im.keeper.Logger(ctx).Error("unexpected timeout on consumer", + "sourceClient", sourceClient, + "sequence", sequence, + ) ctx.EventManager().EmitEvent( sdk.NewEvent( - types.EventTypePacket, + vaastypes.EventTypeTimeout, sdk.NewAttribute(sdk.AttributeKeyModule, consumertypes.ModuleName), - sdk.NewAttribute(types.AttributeKeyAck, ack.String()), + sdk.NewAttribute("source_client", sourceClient), + sdk.NewAttribute("sequence", strconv.FormatUint(sequence, 10)), ), ) - switch resp := ack.Response.(type) { - case *channeltypes.Acknowledgement_Result: - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypePacket, - sdk.NewAttribute(types.AttributeKeyAckSuccess, string(resp.Result)), - ), - ) - case *channeltypes.Acknowledgement_Error: - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypePacket, - sdk.NewAttribute(types.AttributeKeyAckError, resp.Error), - ), - ) - } + return nil } -// OnTimeoutPacket implements the IBCModule interface -// the CCV channel state is changed to CLOSED -// by the IBC module as the channel is ORDERED -func (am AppModule) OnTimeoutPacket( +func (im IBCModule) OnAcknowledgementPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - _ sdk.AccAddress, + sourceClient string, + destinationClient string, + sequence uint64, + acknowledgement []byte, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, ) error { - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeTimeout, - sdk.NewAttribute(sdk.AttributeKeyModule, consumertypes.ModuleName), - ), + im.keeper.Logger(ctx).Error("unexpected acknowledgement on consumer", + "sourceClient", sourceClient, + "sequence", sequence, ) return nil diff --git a/x/vaas/consumer/keeper/genesis.go b/x/vaas/consumer/keeper/genesis.go index b18becf..dd4567b 100644 --- a/x/vaas/consumer/keeper/genesis.go +++ b/x/vaas/consumer/keeper/genesis.go @@ -2,25 +2,14 @@ package keeper import ( "github.com/allinbits/vaas/x/vaas/consumer/types" - vaastypes "github.com/allinbits/vaas/x/vaas/types" abci "github.com/cometbft/cometbft/abci/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" - errorsmod "cosmossdk.io/errors" - sdk "github.com/cosmos/cosmos-sdk/types" ) -// InitGenesis initializes the CCV consumer state and binds to PortID. -// The three states in which a consumer chain can start/restart: -// -// 1. A client to the provider was never created, i.e. a new consumer chain is started for the first time. -// 2. A consumer chain restarts after a client to the provider was created, but the CCV channel handshake is still in progress -// 3. A consumer chain restarts after the CCV channel handshake was completed. func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.ValidatorUpdate { // PreVAAS is true during the process of a standalone to consumer changeover. // At the PreVAAS point in the process, the standalone chain has just been upgraded to include @@ -33,96 +22,38 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.V k.MarkAsPrevStandaloneChain(ctx) k.SetInitialValSet(ctx, state.Provider.InitialValSet) } - k.SetInitGenesisHeight(ctx, ctx.BlockHeight()) // Usually 0, but not the case for changeover chains + k.SetInitGenesisHeight(ctx, ctx.BlockHeight()) k.SetParams(ctx, state.Params) - // TODO: Remove enabled flag and find a better way to setup integration tests - // See: https://github.com/cosmos/interchain-security/issues/339 if !state.Params.Enabled { return nil } - k.SetPort(ctx, vaastypes.ConsumerPortID) - - // initialValSet is checked in NewChain case by ValidateGenesis - // start a new chain if state.NewChain { - var clientID string - if state.ConnectionId == "" { - // create the provider client in InitGenesis for new consumer chain. CCV Handshake must be established with this client id. - clientStateBytes, err := state.Provider.ClientState.Marshal() - if err != nil { - panic(err) - } - consensusStateBytes, err := state.Provider.ConsensusState.Marshal() - if err != nil { - panic(err) - } - - // this means the client must be tendermint - cid, err := k.clientKeeper.CreateClient(ctx, ibchost.Tendermint, clientStateBytes, consensusStateBytes) - if err != nil { - // If the client creation fails, the chain MUST NOT start - panic(err) - } - clientID = cid - - k.Logger(ctx).Info("create new provider chain client", - "client id", clientID, - ) - } else { - // if connection id is provided, then the client is already created - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, state.ConnectionId) - if !found { - panic(errorsmod.Wrapf(conntypes.ErrConnectionNotFound, "could not find connection(%s)", state.ConnectionId)) - } - clientID = connectionEnd.ClientId - - k.Logger(ctx).Info("use existing client and connection to provider chain", - "client id", clientID, - "connection id", state.ConnectionId, - ) + clientStateBytes, err := state.Provider.ClientState.Marshal() + if err != nil { + panic(err) + } + consensusStateBytes, err := state.Provider.ConsensusState.Marshal() + if err != nil { + panic(err) } - // set provider client id. - k.SetProviderClientID(ctx, clientID) + cid, err := k.clientKeeper.CreateClient(ctx, ibchost.Tendermint, clientStateBytes, consensusStateBytes) + if err != nil { + panic(err) + } - // set default value for valset update ID + k.SetProviderClientID(ctx, cid) k.SetHeightValsetUpdateID(ctx, uint64(ctx.BlockHeight()), uint64(0)) - if state.ConnectionId != "" { - // initiate CCV channel handshake - ccvChannelOpenInitMsg := channeltypes.NewMsgChannelOpenInit( - vaastypes.ConsumerPortID, - vaastypes.Version, - channeltypes.ORDERED, - []string{state.ConnectionId}, - vaastypes.ProviderPortID, - "", // signer unused - ) - _, err := k.ChannelOpenInit(ctx, ccvChannelOpenInitMsg) - if err != nil { - panic(err) - } - - // Note that if the connection ID is not provider, we cannot initiate - // the connection handshake as the counterparty client ID is unknown - // at this point. The connection handshake must be initiated by a relayer. - } - + k.Logger(ctx).Info("create new provider chain client", + "client id", cid, + ) } else { - // chain restarts with the CCV channel established - if state.ProviderChannelId != "" { - // set provider channel ID - k.SetProviderChannel(ctx, state.ProviderChannelId) - } - - // set height to valset update id mapping for _, h2v := range state.HeightToValsetUpdateId { k.SetHeightValsetUpdateID(ctx, h2v.Height, h2v.ValsetUpdateId) } - - // set provider client id k.SetProviderClientID(ctx, state.ProviderClientId) } @@ -145,38 +76,17 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *types.GenesisState) { // export the current validator set valset := k.MustGetCurrentValidatorsAsABCIUpdates(ctx) - // export all the states created after a provider channel got established - if channelID, ok := k.GetProviderChannel(ctx); ok { - clientID, found := k.GetProviderClientID(ctx) - if !found { - // This should never happen - panic("provider client does not exist although provider channel does exist") - } - - genesis = types.NewRestartGenesisState( - clientID, - channelID, - valset, - k.GetAllHeightToValsetUpdateIDs(ctx), - params, - ) - } else { - clientID, ok := k.GetProviderClientID(ctx) - // if provider clientID and channelID don't exist on the consumer chain, - // then CCV protocol is disabled for this chain return a default genesis state - if !ok { - return types.DefaultGenesisState() - } - - // export client states into a new chain genesis - genesis = types.NewRestartGenesisState( - clientID, - "", - valset, - k.GetAllHeightToValsetUpdateIDs(ctx), - params, - ) + clientID, ok := k.GetProviderClientID(ctx) + if !ok { + return types.DefaultGenesisState() } + genesis = types.NewRestartGenesisState( + clientID, + valset, + k.GetAllHeightToValsetUpdateIDs(ctx), + params, + ) + return genesis } diff --git a/x/vaas/consumer/keeper/genesis_test.go b/x/vaas/consumer/keeper/genesis_test.go index 412b354..201250c 100644 --- a/x/vaas/consumer/keeper/genesis_test.go +++ b/x/vaas/consumer/keeper/genesis_test.go @@ -32,7 +32,6 @@ import ( func TestInitGenesis(t *testing.T) { // mock the consumer genesis state values provClientID := "tendermint-07" - provChannelID := "ChannelID" provClientType := "07-tendermint" vscID := uint64(0) @@ -66,16 +65,10 @@ func TestInitGenesis(t *testing.T) { defaultHeightValsetUpdateIDs := []consumertypes.HeightToValsetUpdateID{ {ValsetUpdateId: vscID, Height: blockHeight}, } - updatedHeightValsetUpdateIDs := append(defaultHeightValsetUpdateIDs, - consumertypes.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, - ) - // create default parameters for a new chain params := vaastypes.DefaultParams() params.Enabled = true - // define three test cases which respectively create a genesis struct, use it to call InitGenesis - // and finally check that the genesis states are successfully imported in the consumer keeper stores testCases := []struct { name string malleate func(sdk.Context, testkeeper.MockedKeepers) @@ -113,7 +106,6 @@ func TestInitGenesis(t *testing.T) { }, consumertypes.NewRestartGenesisState( provClientID, - "", valset, defaultHeightValsetUpdateIDs, params, @@ -122,30 +114,6 @@ func TestInitGenesis(t *testing.T) { assertHeightValsetUpdateIDs(t, ctx, &ck, defaultHeightValsetUpdateIDs) assertProviderClientID(t, ctx, &ck, provClientID) require.Equal(t, validator.Address.Bytes(), ck.GetAllCCValidator(ctx)[0].Address) - require.Equal(t, gs.Params, ck.GetConsumerParams(ctx)) - }, - }, { - "restart a chain with an established CCV channel", - func(ctx sdk.Context, mocks testkeeper.MockedKeepers) { - // simulate a CCV channel handshake completion - gomock.InOrder() - }, - // create a genesis for a restarted chain - consumertypes.NewRestartGenesisState( - provClientID, - provChannelID, - valset, - updatedHeightValsetUpdateIDs, - params, - ), - func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *consumertypes.GenesisState) { - gotChannelID, ok := ck.GetProviderChannel(ctx) - require.True(t, ok) - require.Equal(t, provChannelID, gotChannelID) - - assertHeightValsetUpdateIDs(t, ctx, &ck, updatedHeightValsetUpdateIDs) - assertProviderClientID(t, ctx, &ck, provClientID) - require.Equal(t, gs.Params, ck.GetConsumerParams(ctx)) }, }, @@ -157,49 +125,33 @@ func TestInitGenesis(t *testing.T) { consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) defer ctrl.Finish() - // test setup tc.malleate(ctx, mocks) - // init chain states consumerKeeper.InitGenesis(ctx, tc.genesis) - // assert consumer keeper states tc.assertStates(ctx, consumerKeeper, tc.genesis) }) } } -// TestExportGenesis tests that a consumer chain genesis is correctly exported to genesis -// It covers the restart of chain when a CCV channel is or isn't established yet. func TestExportGenesis(t *testing.T) { - // create provider channel and client ids provClientID := "tendermint-07" - provChannelID := "provChannelID" vscID := uint64(0) blockHeight := uint64(0) - // mock a validator set pubKey := ed25519.GenPrivKey().PubKey() tmPK, err := cryptocodec.ToCmtPubKeyInterface(pubKey) require.NoError(t, err) validator := tmtypes.NewValidator(tmPK, 1) valset := []abci.ValidatorUpdate{tmtypes.TM2PB.ValidatorUpdate(validator)} - // mock height to valset update ID values defaultHeightValsetUpdateIDs := []consumertypes.HeightToValsetUpdateID{ {ValsetUpdateId: vscID, Height: blockHeight}, } - updatedHeightValsetUpdateIDs := append(defaultHeightValsetUpdateIDs, - consumertypes.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, - ) - // create default parameters for a new chain params := vaastypes.DefaultParams() params.Enabled = true - // define two test cases which respectively populate the consumer chain store - // using the states declared above then call ExportGenesis to finally check - // that the resulting genesis struct contains the same states testCases := []struct { name string malleate func(sdk.Context, consumerkeeper.Keeper, testkeeper.MockedKeepers) @@ -208,7 +160,6 @@ func TestExportGenesis(t *testing.T) { { "export a chain without an established CCV channel", func(ctx sdk.Context, ck consumerkeeper.Keeper, mocks testkeeper.MockedKeepers) { - // populate the states allowed before a CCV channel is established ck.SetProviderClientID(ctx, provClientID) cVal, err := consumertypes.NewCCValidator(validator.Address.Bytes(), 1, pubKey) require.NoError(t, err) @@ -219,35 +170,11 @@ func TestExportGenesis(t *testing.T) { }, consumertypes.NewRestartGenesisState( provClientID, - "", valset, defaultHeightValsetUpdateIDs, params, ), }, - { - "export a chain with an established CCV channel", - func(ctx sdk.Context, ck consumerkeeper.Keeper, mocks testkeeper.MockedKeepers) { - ck.SetProviderClientID(ctx, provClientID) - ck.SetProviderChannel(ctx, provChannelID) - - cVal, err := consumertypes.NewCCValidator(validator.Address.Bytes(), 1, pubKey) - require.NoError(t, err) - ck.SetCCValidator(ctx, cVal) - - ck.SetParams(ctx, params) - - ck.SetHeightValsetUpdateID(ctx, updatedHeightValsetUpdateIDs[0].Height, updatedHeightValsetUpdateIDs[0].ValsetUpdateId) - ck.SetHeightValsetUpdateID(ctx, updatedHeightValsetUpdateIDs[1].Height, updatedHeightValsetUpdateIDs[1].ValsetUpdateId) - }, - consumertypes.NewRestartGenesisState( - provClientID, - provChannelID, - valset, - updatedHeightValsetUpdateIDs, - params, - ), - }, } for _, tc := range testCases { @@ -257,19 +184,15 @@ func TestExportGenesis(t *testing.T) { defer ctrl.Finish() consumerKeeper.SetParams(ctx, params) - // test setup tc.malleate(ctx, consumerKeeper, mocks) - // export states to genesis gotGen := consumerKeeper.ExportGenesis(ctx) - // check obtained genesis require.EqualValues(t, tc.expGenesis, gotGen) }) } } -// assert that the given client ID matches the provider client ID in the store func assertProviderClientID(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Keeper, clientID string) { t.Helper() cid, ok := ck.GetProviderClientID(ctx) @@ -277,7 +200,6 @@ func assertProviderClientID(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Ke require.Equal(t, clientID, cid) } -// assert that the given input match the height to valset update ID mappings in the store func assertHeightValsetUpdateIDs(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Keeper, heighValsetUpdateIDs []consumertypes.HeightToValsetUpdateID) { t.Helper() ctr := 0 @@ -288,3 +210,31 @@ func assertHeightValsetUpdateIDs(t *testing.T, ctx sdk.Context, ck *consumerkeep ctr++ } } + +func TestHighestValsetUpdateID(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + highestID, found, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.False(t, found) + require.Equal(t, uint64(0), highestID) + + consumerKeeper.SetHighestValsetUpdateID(ctx, 5) + highestID, found, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, uint64(5), highestID) + + consumerKeeper.SetHighestValsetUpdateID(ctx, 10) + highestID, found, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, uint64(10), highestID) + + consumerKeeper.SetHighestValsetUpdateID(ctx, 3) + highestID, found, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, uint64(3), highestID) +} diff --git a/x/vaas/consumer/keeper/grpc_query.go b/x/vaas/consumer/keeper/grpc_query.go index 2561985..51c2150 100644 --- a/x/vaas/consumer/keeper/grpc_query.go +++ b/x/vaas/consumer/keeper/grpc_query.go @@ -26,6 +26,7 @@ func (k Keeper) QueryParams(c context.Context, //nolint:golint return &types.QueryParamsResponse{Params: p}, nil } +// QueryProviderInfo returns provider information. func (k Keeper) QueryProviderInfo(c context.Context, //nolint:golint req *types.QueryProviderInfoRequest, ) (*types.QueryProviderInfoResponse, error) { @@ -34,5 +35,5 @@ func (k Keeper) QueryProviderInfo(c context.Context, //nolint:golint return nil, status.Errorf(codes.InvalidArgument, "empty request") } - return k.GetProviderInfo(ctx) + return k.GetProviderInfoV2(ctx) } diff --git a/x/vaas/consumer/keeper/ibc_v2_integration_test.go b/x/vaas/consumer/keeper/ibc_v2_integration_test.go new file mode 100644 index 0000000..7958539 --- /dev/null +++ b/x/vaas/consumer/keeper/ibc_v2_integration_test.go @@ -0,0 +1,226 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + abci "github.com/cometbft/cometbft/abci/types" + + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + + testkeeper "github.com/allinbits/vaas/testutil/keeper" + "github.com/allinbits/vaas/x/vaas/types" +) + +// TestIBCV2ConsumerFullVSCFlow tests the complete consumer-side IBC v2 VSC packet flow: +// 1. Consumer receives first VSC packet and establishes provider client +// 2. Consumer accumulates validator updates +// 3. Consumer tracks highest valset update ID for out-of-order handling +func TestIBCV2ConsumerFullVSCFlow(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerClientID := "07-tendermint-0" + + // Create validator updates + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + // Step 1: Receive first VSC packet - should establish provider client + valUpdates1 := []abci.ValidatorUpdate{ + {PubKey: pk1, Power: 100}, + } + vscPacket1 := types.NewValidatorSetChangePacketData(valUpdates1, 1) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket1) + require.NoError(t, err) + + // Verify provider client was established + clientID, found := consumerKeeper.GetProviderClientID(ctx) + require.True(t, found) + require.Equal(t, providerClientID, clientID) + + // Verify pending changes + pendingChanges, found := consumerKeeper.GetPendingChanges(ctx) + require.True(t, found) + require.Len(t, pendingChanges.ValidatorUpdates, 1) + require.Equal(t, int64(100), pendingChanges.ValidatorUpdates[0].Power) + + // Verify highest valset update ID + highestID, _, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(1), highestID) + + // Step 2: Receive second VSC packet - should accumulate updates + valUpdates2 := []abci.ValidatorUpdate{ + {PubKey: pk2, Power: 50}, + } + vscPacket2 := types.NewValidatorSetChangePacketData(valUpdates2, 2) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket2) + require.NoError(t, err) + + // Verify accumulated pending changes + pendingChanges, found = consumerKeeper.GetPendingChanges(ctx) + require.True(t, found) + require.Len(t, pendingChanges.ValidatorUpdates, 2) + + // Verify highest valset update ID updated + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(2), highestID) +} + +// TestIBCV2ConsumerOutOfOrderHandling tests that out-of-order packets are +// acknowledged but not processed. +func TestIBCV2ConsumerOutOfOrderHandling(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerClientID := "07-tendermint-0" + + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + // Send packet with valset ID 5 first (simulating out-of-order delivery) + valUpdates5 := []abci.ValidatorUpdate{{PubKey: pk1, Power: 500}} + vscPacket5 := types.NewValidatorSetChangePacketData(valUpdates5, 5) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket5) + require.NoError(t, err) + + highestID, _, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(5), highestID) + + // Send packet with valset ID 3 (arrives late - should be ignored) + valUpdates3 := []abci.ValidatorUpdate{{PubKey: pk2, Power: 300}} + vscPacket3 := types.NewValidatorSetChangePacketData(valUpdates3, 3) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket3) + require.NoError(t, err, "out-of-order packet should be acknowledged without error") + + // Highest ID should still be 5 + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(5), highestID) + + // Pending changes should only contain pk1 (from packet 5) + pendingChanges, _ := consumerKeeper.GetPendingChanges(ctx) + require.Len(t, pendingChanges.ValidatorUpdates, 1) + require.Equal(t, int64(500), pendingChanges.ValidatorUpdates[0].Power) + + // Send packet with valset ID 6 (should be processed normally) + valUpdates6 := []abci.ValidatorUpdate{{PubKey: pk2, Power: 600}} + vscPacket6 := types.NewValidatorSetChangePacketData(valUpdates6, 6) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket6) + require.NoError(t, err) + + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(6), highestID) + + // Pending changes should now include pk2 + pendingChanges, _ = consumerKeeper.GetPendingChanges(ctx) + require.Len(t, pendingChanges.ValidatorUpdates, 2) +} + +// TestIBCV2ConsumerRejectsUnknownProvider tests that packets from an unknown +// provider client are rejected after the provider is established. +func TestIBCV2ConsumerRejectsUnknownProvider(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerClientID := "07-tendermint-0" + unknownClientID := "07-tendermint-999" + + pk, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + // Establish provider with first packet + valUpdates := []abci.ValidatorUpdate{{PubKey: pk, Power: 100}} + vscPacket := types.NewValidatorSetChangePacketData(valUpdates, 1) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket) + require.NoError(t, err) + + // Verify provider is established + clientID, found := consumerKeeper.GetProviderClientID(ctx) + require.True(t, found) + require.Equal(t, providerClientID, clientID) + + // Try to send packet from different client - should succeed + // (IBC v2 layer handles counterparty validation) + vscPacket2 := types.NewValidatorSetChangePacketData(valUpdates, 2) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, unknownClientID, vscPacket2) + require.NoError(t, err, "packet from different client should succeed (IBC v2 validates counterparties)") + + // Highest ID should be updated to 2 + highestID, _, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(2), highestID) +} + +// TestIBCV2ConsumerProviderInfoQuery tests the v2 provider info query. +func TestIBCV2ConsumerProviderInfoQuery(t *testing.T) { + consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerClientID := "07-tendermint-0" + + // Initially, no provider client - v2 query should fail + _, err := consumerKeeper.GetProviderInfoV2(ctx) + require.Error(t, err) + + // Set provider client ID + consumerKeeper.SetProviderClientID(ctx, providerClientID) + + // Mock GetClientState for the query + mocks.MockClientKeeper.EXPECT().GetClientState(ctx, providerClientID).Return(nil, false).Times(1) + + // Query should fail because client state not found + _, err = consumerKeeper.GetProviderInfoV2(ctx) + require.Error(t, err) +} + +// TestIBCV2ConsumerDuplicatePacketHandling tests that duplicate packets +// (same valset update ID) are acknowledged but ignored. +func TestIBCV2ConsumerDuplicatePacketHandling(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerClientID := "07-tendermint-0" + + pk, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + // Send first packet + valUpdates := []abci.ValidatorUpdate{{PubKey: pk, Power: 100}} + vscPacket := types.NewValidatorSetChangePacketData(valUpdates, 5) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacket) + require.NoError(t, err) + + pendingChanges, _ := consumerKeeper.GetPendingChanges(ctx) + require.Len(t, pendingChanges.ValidatorUpdates, 1) + require.Equal(t, int64(100), pendingChanges.ValidatorUpdates[0].Power) + + // Send duplicate packet (same valset update ID, different power) + valUpdatesDup := []abci.ValidatorUpdate{{PubKey: pk, Power: 999}} + vscPacketDup := types.NewValidatorSetChangePacketData(valUpdatesDup, 5) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscPacketDup) + require.NoError(t, err, "duplicate packet should be acknowledged") + + // Pending changes should still have original power (duplicate ignored) + pendingChanges, _ = consumerKeeper.GetPendingChanges(ctx) + require.Len(t, pendingChanges.ValidatorUpdates, 1) + require.Equal(t, int64(100), pendingChanges.ValidatorUpdates[0].Power) +} diff --git a/x/vaas/consumer/keeper/keeper.go b/x/vaas/consumer/keeper/keeper.go index 2334aff..e86562b 100644 --- a/x/vaas/consumer/keeper/keeper.go +++ b/x/vaas/consumer/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "errors" "fmt" "github.com/allinbits/vaas/x/vaas/consumer/types" @@ -9,15 +10,11 @@ import ( tmtypes "github.com/cometbft/cometbft/abci/types" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v10/modules/core/24-host" "cosmossdk.io/collections" addresscodec "cosmossdk.io/core/address" corestoretypes "cosmossdk.io/core/store" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" @@ -31,11 +28,10 @@ type Keeper struct { // should be the x/gov module account. authority string - storeService corestoretypes.KVStoreService - cdc codec.BinaryCodec - channelKeeper vaastypes.ChannelKeeper - connectionKeeper vaastypes.ConnectionKeeper - clientKeeper vaastypes.ClientKeeper + storeService corestoretypes.KVStoreService + cdc codec.BinaryCodec + clientKeeper vaastypes.ClientKeeper + clientV2Keeper vaastypes.ClientV2Keeper // standaloneStakingKeeper is the staking keeper that managed proof of stake for a previously standalone chain, // before the chain went through a standalone to consumer changeover. // This keeper is not used for consumers that launched with ICS, and is therefore set after the constructor. @@ -44,7 +40,6 @@ type Keeper struct { hooks vaastypes.ConsumerHooks bankKeeper vaastypes.BankKeeper authKeeper vaastypes.AccountKeeper - ibcCoreKeeper vaastypes.IBCCoreKeeper feeCollectorName string validatorAddressCodec addresscodec.Codec @@ -56,7 +51,6 @@ type Keeper struct { // State collections Port collections.Item[string] ProviderClientID collections.Item[string] - ProviderChannelID collections.Item[string] PendingChanges collections.Item[vaastypes.ValidatorSetChangePacketData] InitGenesisHeight collections.Item[uint64] PreVAAS collections.Item[uint64] @@ -66,6 +60,7 @@ type Keeper struct { HeightValsetUpdateIDs collections.Map[uint64, uint64] CrossChainValidators collections.Map[[]byte, types.CrossChainValidator] HistoricalInfos collections.Map[int64, stakingtypes.HistoricalInfo] + HighestValsetUpdateID collections.Item[uint64] } // NewKeeper creates a new Consumer Keeper instance @@ -73,10 +68,9 @@ type Keeper struct { // collector (and not the provider chain) func NewKeeper( cdc codec.BinaryCodec, storeService corestoretypes.KVStoreService, - channelKeeper vaastypes.ChannelKeeper, - connectionKeeper vaastypes.ConnectionKeeper, clientKeeper vaastypes.ClientKeeper, + clientKeeper vaastypes.ClientKeeper, + clientV2Keeper vaastypes.ClientV2Keeper, slashingKeeper vaastypes.SlashingKeeper, bankKeeper vaastypes.BankKeeper, accountKeeper vaastypes.AccountKeeper, - ibcCoreKeeper vaastypes.IBCCoreKeeper, feeCollectorName, authority string, validatorAddressCodec, consensusAddressCodec addresscodec.Codec, ) Keeper { @@ -86,13 +80,11 @@ func NewKeeper( authority: authority, storeService: storeService, cdc: cdc, - channelKeeper: channelKeeper, - connectionKeeper: connectionKeeper, clientKeeper: clientKeeper, + clientV2Keeper: clientV2Keeper, slashingKeeper: slashingKeeper, bankKeeper: bankKeeper, authKeeper: accountKeeper, - ibcCoreKeeper: ibcCoreKeeper, feeCollectorName: feeCollectorName, standaloneStakingKeeper: nil, validatorAddressCodec: validatorAddressCodec, @@ -101,7 +93,6 @@ func NewKeeper( // Initialize collections Port: collections.NewItem(sb, types.PortPrefix, "port", collections.StringValue), ProviderClientID: collections.NewItem(sb, types.ProviderClientIDPrefix, "provider_client_id", collections.StringValue), - ProviderChannelID: collections.NewItem(sb, types.ProviderChannelIDPrefix, "provider_channel_id", collections.StringValue), PendingChanges: collections.NewItem(sb, types.PendingChangesPrefix, "pending_changes", codec.CollValue[vaastypes.ValidatorSetChangePacketData](cdc)), InitGenesisHeight: collections.NewItem(sb, types.InitGenesisHeightPrefix, "init_genesis_height", collections.Uint64Value), PreVAAS: collections.NewItem(sb, types.PreVAASPrefix, "pre_vaas", collections.Uint64Value), @@ -111,6 +102,7 @@ func NewKeeper( HeightValsetUpdateIDs: collections.NewMap(sb, types.HeightValsetUpdateIDPrefix, "height_valset_update_ids", collections.Uint64Key, collections.Uint64Value), CrossChainValidators: collections.NewMap(sb, types.CrossChainValidatorPrefix, "cross_chain_validators", collections.BytesKey, codec.CollValue[types.CrossChainValidator](cdc)), HistoricalInfos: collections.NewMap(sb, types.HistoricalInfoPrefix, "historical_infos", collections.Int64Key, codec.CollValue[stakingtypes.HistoricalInfo](cdc)), + HighestValsetUpdateID: collections.NewItem(sb, types.HighestValsetUpdateIDPrefix, "highest_valset_update_id", collections.Uint64Value), } schema, err := sb.Build() @@ -139,7 +131,6 @@ func NewNonZeroKeeper(cdc codec.BinaryCodec, storeService corestoretypes.KVStore // Initialize collections with minimal setup for testing Port: collections.NewItem(sb, types.PortPrefix, "port", collections.StringValue), ProviderClientID: collections.NewItem(sb, types.ProviderClientIDPrefix, "provider_client_id", collections.StringValue), - ProviderChannelID: collections.NewItem(sb, types.ProviderChannelIDPrefix, "provider_channel_id", collections.StringValue), PendingChanges: collections.NewItem(sb, types.PendingChangesPrefix, "pending_changes", codec.CollValue[vaastypes.ValidatorSetChangePacketData](cdc)), InitGenesisHeight: collections.NewItem(sb, types.InitGenesisHeightPrefix, "init_genesis_height", collections.Uint64Value), PreVAAS: collections.NewItem(sb, types.PreVAASPrefix, "pre_vaas", collections.Uint64Value), @@ -149,6 +140,7 @@ func NewNonZeroKeeper(cdc codec.BinaryCodec, storeService corestoretypes.KVStore HeightValsetUpdateIDs: collections.NewMap(sb, types.HeightValsetUpdateIDPrefix, "height_valset_update_ids", collections.Uint64Key, collections.Uint64Value), CrossChainValidators: collections.NewMap(sb, types.CrossChainValidatorPrefix, "cross_chain_validators", collections.BytesKey, codec.CollValue[types.CrossChainValidator](cdc)), HistoricalInfos: collections.NewMap(sb, types.HistoricalInfoPrefix, "historical_infos", collections.Int64Key, codec.CollValue[stakingtypes.HistoricalInfo](cdc)), + HighestValsetUpdateID: collections.NewItem(sb, types.HighestValsetUpdateIDPrefix, "highest_valset_update_id", collections.Uint64Value), } schema, err := sb.Build() @@ -193,19 +185,6 @@ func (k *Keeper) SetHooks(sh vaastypes.ConsumerHooks) *Keeper { return k } -// ChanCloseInit defines a wrapper function for the channel Keeper's function -// Following ICS 004: https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics#closing-handshake -func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { - return k.channelKeeper.ChanCloseInit(ctx, portID, channelID) -} - -// ChannelOpenInit defines a wrapper function for the ibcCoreKeeper's function -func (k Keeper) ChannelOpenInit(ctx sdk.Context, msg *channeltypes.MsgChannelOpenInit) ( - *channeltypes.MsgChannelOpenInitResponse, error, -) { - return k.ibcCoreKeeper.ChannelOpenInit(ctx, msg) -} - // GetPort returns the portID for the transfer module. Used in ExportGenesis func (k Keeper) GetPort(ctx context.Context) string { port, err := k.Port.Get(ctx) @@ -239,32 +218,6 @@ func (k Keeper) GetProviderClientID(ctx context.Context) (string, bool) { return clientID, true } -// SetProviderChannel sets the channelID for the channel to the provider. -func (k Keeper) SetProviderChannel(ctx context.Context, channelID string) { - if err := k.ProviderChannelID.Set(ctx, channelID); err != nil { - panic(fmt.Errorf("failed to set provider channel: %w", err)) - } -} - -// GetProviderChannel gets the channelID for the channel to the provider. -func (k Keeper) GetProviderChannel(ctx context.Context) (string, bool) { - channelID, err := k.ProviderChannelID.Get(ctx) - if err != nil { - return "", false - } - if channelID == "" { - return "", false - } - return channelID, true -} - -// DeleteProviderChannel deletes the channelID for the channel to the provider. -func (k Keeper) DeleteProviderChannel(ctx context.Context) { - if err := k.ProviderChannelID.Remove(ctx); err != nil { - panic(fmt.Errorf("failed to delete provider channel: %w", err)) - } -} - // SetPendingChanges sets the pending validator set change packet that haven't been flushed to ABCI func (k Keeper) SetPendingChanges(ctx context.Context, updates vaastypes.ValidatorSetChangePacketData) { if err := k.PendingChanges.Set(ctx, updates); err != nil { @@ -347,29 +300,6 @@ func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) ([]stakingtypes.Val return k.GetLastBondedValidators(ctx) } -// VerifyProviderChain verifies that the chain trying to connect on the channel handshake -// is the expected provider chain. -func (k Keeper) VerifyProviderChain(ctx sdk.Context, connectionHops []string) error { - if len(connectionHops) != 1 { - return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") - } - connectionID := connectionHops[0] - conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) - if !ok { - return errorsmod.Wrapf(conntypes.ErrConnectionNotFound, "connection not found for connection ID: %s", connectionID) - } - // Verify that client id is expected clientID - expectedClientId, ok := k.GetProviderClientID(ctx) - if !ok { - return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "could not find provider client id") - } - if expectedClientId != conn.ClientId { - return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "invalid client: %s, channel must be built on top of client: %s", conn.ClientId, expectedClientId) - } - - return nil -} - // SetHeightValsetUpdateID sets the valset update id for a given block height func (k Keeper) SetHeightValsetUpdateID(ctx context.Context, height, valsetUpdateId uint64) { if err := k.HeightValsetUpdateIDs.Set(ctx, height, valsetUpdateId); err != nil { @@ -488,3 +418,27 @@ func (k Keeper) GetLastBondedValidators(ctx sdk.Context) ([]stakingtypes.Validat } return vaastypes.GetLastBondedValidatorsUtil(ctx, k.standaloneStakingKeeper, maxVals) } + +// SetHighestValsetUpdateID sets the highest valset update ID that has been processed. +// Used for IBC v2 out-of-order packet handling - packets with lower IDs are ignored. +func (k Keeper) SetHighestValsetUpdateID(ctx context.Context, id uint64) error { + if err := k.HighestValsetUpdateID.Set(ctx, id); err != nil { + return fmt.Errorf("failed to set highest valset update ID: %w", err) + } + + return nil +} + +// GetHighestValsetUpdateID gets the highest valset update ID that has been processed. +// Returns (0, false) if not set, indicating no packets have been processed yet. +func (k Keeper) GetHighestValsetUpdateID(ctx context.Context) (uint64, bool, error) { + val, err := k.HighestValsetUpdateID.Get(ctx) + if err != nil { + if errors.Is(err, collections.ErrNotFound) { + return 0, false, nil + } + return 0, false, err + } + + return val, true, nil +} diff --git a/x/vaas/consumer/keeper/keeper_test.go b/x/vaas/consumer/keeper/keeper_test.go index 9bf7efe..9dcfccc 100644 --- a/x/vaas/consumer/keeper/keeper_test.go +++ b/x/vaas/consumer/keeper/keeper_test.go @@ -6,13 +6,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" @@ -36,19 +32,6 @@ func TestProviderClientID(t *testing.T) { require.Equal(t, "someClientID", clientID) } -// TestProviderChannel tests getter and setter functionality for the channel ID stored on consumer keeper -func TestProviderChannel(t *testing.T) { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - _, ok := consumerKeeper.GetProviderChannel(ctx) - require.False(t, ok) - consumerKeeper.SetProviderChannel(ctx, "channelID") - channelID, ok := consumerKeeper.GetProviderChannel(ctx) - require.True(t, ok) - require.Equal(t, "channelID", channelID) -} - // TestPendingChanges tests getter, setter, and delete functionality for pending VSCs on a consumer chain func TestPendingChanges(t *testing.T) { pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) @@ -244,7 +227,7 @@ func TestGetAllCCValidator(t *testing.T) { numValidators := 4 validators := []types.CrossChainValidator{} - for i := 0; i < numValidators; i++ { + for range numValidators { validators = append(validators, testkeeper.GetNewCrossChainValidator(t)) } // sorting by CrossChainValidator.Address @@ -263,89 +246,6 @@ func TestGetAllCCValidator(t *testing.T) { require.Equal(t, result, expectedGetAllOrder) } -// TestVerifyProviderChain tests the VerifyProviderChain method for the consumer keeper -func TestVerifyProviderChain(t *testing.T) { - testCases := []struct { - name string - // State-mutating setup specific to this test case - mockSetup func(sdk.Context, testkeeper.MockedKeepers) - connectionHops []string - expError bool - }{ - { - name: "success", - mockSetup: func(ctx sdk.Context, mocks testkeeper.MockedKeepers) { - gomock.InOrder( - mocks.MockConnectionKeeper.EXPECT().GetConnection( - ctx, "connectionID", - ).Return(conntypes.ConnectionEnd{ClientId: "clientID"}, true).Times(1), - ) - }, - connectionHops: []string{"connectionID"}, - expError: false, - }, - { - name: "connection hops is not length 1", - mockSetup: func(ctx sdk.Context, mocks testkeeper.MockedKeepers) { - // Expect no calls to GetConnection(), VerifyProviderChain will return from first step. - gomock.InAnyOrder( - mocks.MockConnectionKeeper.EXPECT().GetConnection(gomock.Any(), gomock.Any()).Times(0), - ) - }, - connectionHops: []string{"connectionID", "otherConnID"}, - expError: true, - }, - { - name: "connection does not exist", - mockSetup: func(ctx sdk.Context, mocks testkeeper.MockedKeepers) { - gomock.InOrder( - mocks.MockConnectionKeeper.EXPECT().GetConnection( - ctx, "connectionID").Return(conntypes.ConnectionEnd{}, - false, // Found is returned as false - ).Times(1), - ) - }, - connectionHops: []string{"connectionID"}, - expError: true, - }, - { - name: "found clientID does not match expectation", - mockSetup: func(ctx sdk.Context, mocks testkeeper.MockedKeepers) { - gomock.InOrder( - mocks.MockConnectionKeeper.EXPECT().GetConnection( - ctx, "connectionID").Return( - conntypes.ConnectionEnd{ClientId: "unexpectedClientID"}, true, - ).Times(1), - ) - }, - connectionHops: []string{"connectionID"}, - expError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - keeperParams := testkeeper.NewInMemKeeperParams(t) - consumerKeeper, ctx, ctrl, mocks := testkeeper.GetConsumerKeeperAndCtx(t, keeperParams) - - // Common setup - consumerKeeper.SetProviderClientID(ctx, "clientID") // Set expected provider clientID - - // Specific mock setup - tc.mockSetup(ctx, mocks) - - err := consumerKeeper.VerifyProviderChain(ctx, tc.connectionHops) - - if tc.expError { - require.Error(t, err, "invalid case did not return error") - } else { - require.NoError(t, err, "valid case returned error") - } - ctrl.Finish() - }) - } -} - // TestGetAllHeightToValsetUpdateIDs tests GetAllHeightToValsetUpdateIDs behaviour correctness func TestGetAllHeightToValsetUpdateIDs(t *testing.T) { ck, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) diff --git a/x/vaas/consumer/keeper/provider_info.go b/x/vaas/consumer/keeper/provider_info.go index 19490f6..ec25b37 100644 --- a/x/vaas/consumer/keeper/provider_info.go +++ b/x/vaas/consumer/keeper/provider_info.go @@ -9,44 +9,25 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func (k Keeper) GetProviderInfo(ctx sdk.Context) (*types.QueryProviderInfoResponse, error) { //nolint:golint - consumerChannelID, found := k.GetProviderChannel(ctx) +func (k Keeper) GetProviderInfoV2(ctx sdk.Context) (*types.QueryProviderInfoResponse, error) { + providerClientID, found := k.GetProviderClientID(ctx) if !found { - return nil, vaastypes.ErrChannelNotFound - } - consumerChannel, found := k.channelKeeper.GetChannel(ctx, vaastypes.ConsumerPortID, consumerChannelID) - if !found { - return nil, vaastypes.ErrChannelNotFound - } - - // from channel get connection - consumerConnectionID, consumerConnection, err := k.channelKeeper.GetChannelConnection(ctx, vaastypes.ConsumerPortID, consumerChannelID) - if err != nil { - return nil, err + return nil, vaastypes.ErrClientNotFound } - providerChannelID := consumerChannel.Counterparty.ChannelId - providerConnection := consumerConnection.Counterparty - - consumerClientState, found := k.clientKeeper.GetClientState(ctx, consumerConnection.ClientId) + providerClientState, found := k.clientKeeper.GetClientState(ctx, providerClientID) if !found { return nil, vaastypes.ErrClientNotFound } - providerChainID := consumerClientState.(*ibctm.ClientState).ChainId + providerChainID := providerClientState.(*ibctm.ClientState).ChainId resp := types.QueryProviderInfoResponse{ Consumer: types.ChainInfo{ - ChainID: ctx.ChainID(), - ClientID: consumerConnection.ClientId, - ConnectionID: consumerConnectionID, - ChannelID: consumerChannelID, + ChainID: ctx.ChainID(), + ClientID: providerClientID, }, - Provider: types.ChainInfo{ - ChainID: providerChainID, - ClientID: providerConnection.ClientId, - ConnectionID: providerConnection.ConnectionId, - ChannelID: providerChannelID, + ChainID: providerChainID, }, } diff --git a/x/vaas/consumer/keeper/relay.go b/x/vaas/consumer/keeper/relay.go index 24b7110..c4b026c 100644 --- a/x/vaas/consumer/keeper/relay.go +++ b/x/vaas/consumer/keeper/relay.go @@ -1,57 +1,49 @@ package keeper import ( - "fmt" - "github.com/allinbits/vaas/x/vaas/consumer/types" vaastypes "github.com/allinbits/vaas/x/vaas/types" abci "github.com/cometbft/cometbft/abci/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" - errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" ) -// OnRecvVSCPacket sets the pending validator set changes that will be flushed to ABCI on Endblock -// and set the maturity time for the packet. Once the maturity time elapses, a VSCMatured packet is -// sent back to the provider chain. -// -// Note: CCV uses an ordered IBC channel, meaning VSC packet changes will be accumulated (and later -// processed by ApplyCCValidatorChanges) s.t. more recent val power changes overwrite older ones. -func (k Keeper) OnRecvVSCPacket(ctx sdk.Context, packet channeltypes.Packet, newChanges vaastypes.ValidatorSetChangePacketData) error { - // validate packet data upon receiving +func (k Keeper) OnRecvVSCPacketV2(ctx sdk.Context, sourceClientID string, newChanges vaastypes.ValidatorSetChangePacketData) error { if err := newChanges.Validate(); err != nil { return errorsmod.Wrapf(err, "error validating VSCPacket data") } - // get the provider channel - providerChannel, found := k.GetProviderChannel(ctx) - if found && providerChannel != packet.DestinationChannel { - // VSC packet was sent on a channel different than the provider channel; - // this should never happen - panic(fmt.Errorf("VSCPacket received on unknown channel %s; expected: %s", - packet.DestinationChannel, providerChannel)) + highestID, found, err := k.GetHighestValsetUpdateID(ctx) + if err != nil { + return errorsmod.Wrapf(err, "error getting highest valset update ID") + } + + if found && newChanges.ValsetUpdateId <= highestID { + k.Logger(ctx).Info("skipping out-of-order VSCPacket", + "packetVscID", newChanges.ValsetUpdateId, + "highestVscID", highestID, + "sourceClientID", sourceClientID, + ) + return nil } + + _, found = k.GetProviderClientID(ctx) if !found { - // the first packet from the provider chain - // - mark the CCV channel as established - k.SetProviderChannel(ctx, packet.DestinationChannel) - k.Logger(ctx).Info("CCV channel established", "port", packet.DestinationPort, "channel", packet.DestinationChannel) + k.SetProviderClientID(ctx, sourceClientID) + k.Logger(ctx).Info("Provider client established", "clientID", sourceClientID) - // emit event on first VSC packet to signal that CCV is working ctx.EventManager().EmitEvent( sdk.NewEvent( vaastypes.EventTypeChannelEstablished, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute(channeltypes.AttributeKeyChannelID, packet.DestinationChannel), - sdk.NewAttribute(channeltypes.AttributeKeyPortID, packet.DestinationPort), + sdk.NewAttribute("client_id", sourceClientID), ), ) } - // Set pending changes by accumulating changes from this packet with all prior changes + currentValUpdates := []abci.ValidatorUpdate{} currentChanges, exists := k.GetPendingChanges(ctx) if exists { @@ -63,65 +55,18 @@ func (k Keeper) OnRecvVSCPacket(ctx sdk.Context, packet channeltypes.Packet, new ValidatorUpdates: pendingChanges, }) - // set height to VSC id mapping blockHeight := uint64(ctx.BlockHeight()) + 1 k.SetHeightValsetUpdateID(ctx, blockHeight, newChanges.ValsetUpdateId) k.Logger(ctx).Debug("block height was mapped to vscID", "height", blockHeight, "vscID", newChanges.ValsetUpdateId) - // Note: Slash acks processing removed as slash functionality is not supported + if err := k.SetHighestValsetUpdateID(ctx, newChanges.ValsetUpdateId); err != nil { + return errorsmod.Wrapf(err, "error setting highest valset update ID") + } k.Logger(ctx).Info("finished receiving/handling VSCPacket", "vscID", newChanges.ValsetUpdateId, "len updates", len(newChanges.ValidatorUpdates), + "sourceClientID", sourceClientID, ) return nil } - -// Note: SendPackets removed - consumer does not send any packets to provider in vaas -// (slash packets removed, VSCMatured packets removed) - -// OnAcknowledgementPacket executes application logic for acknowledgments of sent VSCMatured packets -// in conjunction with the ibc module's execution of "acknowledgePacket", -// according to https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics#processing-acknowledgements -func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, ack channeltypes.Acknowledgement) error { - if res := ack.GetResult(); res != nil { - // VSCMatured packets are popped from the consumer pending packets queue on send. - // Nothing more to do here. - return nil - } - - if err := ack.GetError(); err != "" { - // Reasons for ErrorAcknowledgment - // - packet data could not be successfully decoded - // This should never happen. - k.Logger(ctx).Error( - "recv ErrorAcknowledgement", - "channel", packet.SourceChannel, - "error", err, - ) - // Initiate ChanCloseInit using packet source (non-counterparty) port and channel - err := k.ChanCloseInit(ctx, packet.SourcePort, packet.SourceChannel) - if err != nil { - return fmt.Errorf("ChanCloseInit(%s) failed: %s", packet.SourceChannel, err.Error()) - } - // check if there is an established CCV channel to provider - channelID, found := k.GetProviderChannel(ctx) - if !found { - return errorsmod.Wrapf(types.ErrNoProposerChannelId, "recv ErrorAcknowledgement on non-established channel %s", packet.SourceChannel) - } - if channelID != packet.SourceChannel { - // Close the established CCV channel as well - return k.ChanCloseInit(ctx, vaastypes.ConsumerPortID, channelID) - } - } - return nil -} - -// IsChannelClosed returns a boolean whether a given channel is in the CLOSED state -func (k Keeper) IsChannelClosed(ctx sdk.Context, channelID string) bool { - channel, found := k.channelKeeper.GetChannel(ctx, vaastypes.ConsumerPortID, channelID) - if !found || channel.State == channeltypes.CLOSED { - return true - } - return false -} diff --git a/x/vaas/consumer/keeper/relay_test.go b/x/vaas/consumer/keeper/relay_test.go index 192c850..eba7daa 100644 --- a/x/vaas/consumer/keeper/relay_test.go +++ b/x/vaas/consumer/keeper/relay_test.go @@ -4,8 +4,6 @@ import ( "sort" "testing" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -13,15 +11,13 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/allinbits/vaas/testutil/crypto" + testcrypto "github.com/allinbits/vaas/testutil/crypto" testkeeper "github.com/allinbits/vaas/testutil/keeper" "github.com/allinbits/vaas/x/vaas/types" ) -// TestOnRecvVSCPacket tests the behavior of OnRecvVSCPacket over various packet scenarios -func TestOnRecvVSCPacket(t *testing.T) { - consumerCCVChannelID := "consumerCCVChannelID" - providerCCVChannelID := "providerCCVChannelID" +func TestOnRecvVSCPacketV2(t *testing.T) { + providerClientID := "07-tendermint-0" pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) @@ -31,164 +27,198 @@ func TestOnRecvVSCPacket(t *testing.T) { require.NoError(t, err) changes1 := []abci.ValidatorUpdate{ - { - PubKey: pk1, - Power: 30, - }, - { - PubKey: pk2, - Power: 20, - }, + {PubKey: pk1, Power: 30}, + {PubKey: pk2, Power: 20}, } changes2 := []abci.ValidatorUpdate{ - { - PubKey: pk2, - Power: 40, - }, - { - PubKey: pk3, - Power: 10, - }, + {PubKey: pk2, Power: 40}, + {PubKey: pk3, Power: 10}, } - pd := types.NewValidatorSetChangePacketData( - changes1, - 1, - ) - - pd2 := types.NewValidatorSetChangePacketData( - changes2, - 2, - ) - - testCases := []struct { - name string - expError bool - packet channeltypes.Packet - expectedPendingChanges types.ValidatorSetChangePacketData - }{ - { - "success on first packet", - false, - channeltypes.NewPacket(pd.GetBytes(), 1, types.ProviderPortID, providerCCVChannelID, types.ConsumerPortID, consumerCCVChannelID, - clienttypes.NewHeight(1, 0), 0), - types.ValidatorSetChangePacketData{ValidatorUpdates: changes1}, - }, - { - "success on subsequent packet", - false, - channeltypes.NewPacket(pd.GetBytes(), 2, types.ProviderPortID, providerCCVChannelID, types.ConsumerPortID, consumerCCVChannelID, - clienttypes.NewHeight(1, 0), 0), - types.ValidatorSetChangePacketData{ValidatorUpdates: changes1}, - }, - { - "success on packet with more changes", - false, - channeltypes.NewPacket(pd2.GetBytes(), 3, types.ProviderPortID, providerCCVChannelID, types.ConsumerPortID, consumerCCVChannelID, - clienttypes.NewHeight(1, 0), 0), - types.ValidatorSetChangePacketData{ValidatorUpdates: []abci.ValidatorUpdate{ - { - PubKey: pk1, - Power: 30, - }, - { - PubKey: pk2, - Power: 40, - }, - { - PubKey: pk3, - Power: 10, - }, - }}, - }, - } + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + pd1 := types.NewValidatorSetChangePacketData(changes1, 1) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd1) + require.NoError(t, err, "first packet should succeed") + + clientID, found := consumerKeeper.GetProviderClientID(ctx) + require.True(t, found) + require.Equal(t, providerClientID, clientID) + + pendingChanges, ok := consumerKeeper.GetPendingChanges(ctx) + require.True(t, ok) + require.Equal(t, 2, len(pendingChanges.ValidatorUpdates)) + + highestID, _, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(1), highestID) + + pd2 := types.NewValidatorSetChangePacketData(changes2, 2) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd2) + require.NoError(t, err, "second packet should succeed") + + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(2), highestID) + + differentClientID := "07-tendermint-999" + pd3 := types.NewValidatorSetChangePacketData(changes1, 3) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, differentClientID, pd3) + require.NoError(t, err, "packet from different client should succeed (IBC v2 validates counterparties)") + + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(3), highestID) +} + +func TestOnRecvVSCPacketV2OutOfOrder(t *testing.T) { + providerClientID := "07-tendermint-0" + + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + changes5 := []abci.ValidatorUpdate{{PubKey: pk1, Power: 50}} + pd5 := types.NewValidatorSetChangePacketData(changes5, 5) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd5) + require.NoError(t, err) + + highestID, _, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(5), highestID) + + pendingChanges, _ := consumerKeeper.GetPendingChanges(ctx) + require.Equal(t, int64(50), pendingChanges.ValidatorUpdates[0].Power) + + changes3 := []abci.ValidatorUpdate{{PubKey: pk2, Power: 30}} + pd3 := types.NewValidatorSetChangePacketData(changes3, 3) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd3) + require.NoError(t, err, "out-of-order packet should be acknowledged without error") + + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(5), highestID) + + pendingChanges, _ = consumerKeeper.GetPendingChanges(ctx) + require.Equal(t, 1, len(pendingChanges.ValidatorUpdates)) + require.Equal(t, int64(50), pendingChanges.ValidatorUpdates[0].Power) + + changes6 := []abci.ValidatorUpdate{{PubKey: pk2, Power: 60}} + pd6 := types.NewValidatorSetChangePacketData(changes6, 6) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd6) + require.NoError(t, err) + + highestID, _, err = consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.Equal(t, uint64(6), highestID) + + pendingChanges, _ = consumerKeeper.GetPendingChanges(ctx) + require.Equal(t, 2, len(pendingChanges.ValidatorUpdates)) +} + +func TestOnRecvVSCPacketV2FirstPacketNotDropped(t *testing.T) { + providerClientID := "07-tendermint-0" + + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - // Set channel to provider, still in context of consumer chain - consumerKeeper.SetProviderChannel(ctx, consumerCCVChannelID) - - for _, tc := range testCases { - var newChanges types.ValidatorSetChangePacketData - err := types.ModuleCdc.UnmarshalJSON(tc.packet.GetData(), &newChanges) - require.Nil(t, err, "invalid test case: %s - cannot unmarshal VSCPacket data", tc.name) - err = consumerKeeper.OnRecvVSCPacket(ctx, tc.packet, newChanges) - if tc.expError { - require.Error(t, err, "%s - invalid but OnRecvVSCPacket did not return error", tc.name) - continue - } - require.NoError(t, err, "%s - valid but OnRecvVSCPacket returned error: %w", tc.name, err) - - providerChannel, ok := consumerKeeper.GetProviderChannel(ctx) - require.True(t, ok) - require.Equal(t, tc.packet.DestinationChannel, providerChannel, - "provider channel is not destination channel on successful receive for valid test case: %s", tc.name) - - // Check that pending changes are accumulated and stored correctly - actualPendingChanges, ok := consumerKeeper.GetPendingChanges(ctx) - require.True(t, ok) - // Sort to avoid dumb inequalities - sort.SliceStable(actualPendingChanges.ValidatorUpdates, func(i, j int) bool { - return actualPendingChanges.ValidatorUpdates[i].PubKey.Compare(actualPendingChanges.ValidatorUpdates[j].PubKey) == -1 - }) - sort.SliceStable(tc.expectedPendingChanges.ValidatorUpdates, func(i, j int) bool { - return tc.expectedPendingChanges.ValidatorUpdates[i].PubKey.Compare(tc.expectedPendingChanges.ValidatorUpdates[j].PubKey) == -1 - }) - require.Equal(t, tc.expectedPendingChanges, *actualPendingChanges, "pending changes not equal to expected changes after successful packet receive. case: %s", tc.name) + _, found, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.False(t, found, "unset HighestValsetUpdateID should return found=false") + + changes := []abci.ValidatorUpdate{{PubKey: pk1, Power: 100}} + pd1 := types.NewValidatorSetChangePacketData(changes, 1) + + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd1) + require.NoError(t, err, "first packet should be processed when no highest ID is set") + + pendingChanges, ok := consumerKeeper.GetPendingChanges(ctx) + require.True(t, ok) + require.Equal(t, int64(100), pendingChanges.ValidatorUpdates[0].Power) + + highestID, found, err := consumerKeeper.GetHighestValsetUpdateID(ctx) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, uint64(1), highestID) +} + +func TestOnRecvVSCPacketV2AccumulatesChanges(t *testing.T) { + providerClientID := "07-tendermint-0" + + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk3, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + changes1 := []abci.ValidatorUpdate{ + {PubKey: pk1, Power: 30}, + {PubKey: pk2, Power: 20}, + } + + changes2 := []abci.ValidatorUpdate{ + {PubKey: pk2, Power: 40}, + {PubKey: pk3, Power: 10}, } + + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + pd1 := types.NewValidatorSetChangePacketData(changes1, 1) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd1) + require.NoError(t, err) + + pd2 := types.NewValidatorSetChangePacketData(changes2, 2) + err = consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, pd2) + require.NoError(t, err) + + pendingChanges, ok := consumerKeeper.GetPendingChanges(ctx) + require.True(t, ok) + + expected := types.ValidatorSetChangePacketData{ValidatorUpdates: []abci.ValidatorUpdate{ + {PubKey: pk1, Power: 30}, + {PubKey: pk2, Power: 40}, + {PubKey: pk3, Power: 10}, + }} + + sort.SliceStable(pendingChanges.ValidatorUpdates, func(i, j int) bool { + return pendingChanges.ValidatorUpdates[i].PubKey.Compare(pendingChanges.ValidatorUpdates[j].PubKey) == -1 + }) + sort.SliceStable(expected.ValidatorUpdates, func(i, j int) bool { + return expected.ValidatorUpdates[i].PubKey.Compare(expected.ValidatorUpdates[j].PubKey) == -1 + }) + require.Equal(t, expected, *pendingChanges) } -// TestOnRecvVSCPacketDuplicateUpdates tests that the consumer can correctly handle a single VSC packet -// with duplicate valUpdates for the same pub key. -// -// Note: This scenario shouldn't usually happen, ie. the provider shouldn't send duplicate val updates -// for the same pub key. But it's useful to guard against. -func TestOnRecvVSCPacketDuplicateUpdates(t *testing.T) { - // Arbitrary channel IDs - consumerCCVChannelID := "consumerCCVChannelID" - providerCCVChannelID := "providerCCVChannelID" - - // Keeper setup +func TestOnRecvVSCPacketV2DuplicateUpdates(t *testing.T) { + providerClientID := "07-tendermint-0" + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - consumerKeeper.SetProviderChannel(ctx, consumerCCVChannelID) - consumerKeeper.SetParams(ctx, types.DefaultParams()) - // Construct packet/data with duplicate val updates for the same pub key - cId := crypto.NewCryptoIdentityFromIntSeed(43278947) + cId := testcrypto.NewCryptoIdentityFromIntSeed(43278947) valUpdates := []abci.ValidatorUpdate{ - { - PubKey: cId.TMProtoCryptoPublicKey(), - Power: 0, - }, - { - PubKey: cId.TMProtoCryptoPublicKey(), - Power: 473289, - }, + {PubKey: cId.TMProtoCryptoPublicKey(), Power: 0}, + {PubKey: cId.TMProtoCryptoPublicKey(), Power: 473289}, } - vscData := types.NewValidatorSetChangePacketData( - valUpdates, - 1, - ) - packet := channeltypes.NewPacket(vscData.GetBytes(), 2, types.ProviderPortID, - providerCCVChannelID, types.ConsumerPortID, consumerCCVChannelID, clienttypes.NewHeight(1, 0), 0) - - // Confirm no pending changes exist before OnRecvVSCPacket - _, ok := consumerKeeper.GetPendingChanges(ctx) - require.False(t, ok) - - // Execute OnRecvVSCPacket - err := consumerKeeper.OnRecvVSCPacket(ctx, packet, vscData) - require.Nil(t, err) - - // Confirm pending changes are queued by OnRecvVSCPacket + vscData := types.NewValidatorSetChangePacketData(valUpdates, 1) + + err := consumerKeeper.OnRecvVSCPacketV2(ctx, providerClientID, vscData) + require.NoError(t, err) + gotPendingChanges, ok := consumerKeeper.GetPendingChanges(ctx) require.True(t, ok) - // Confirm that only the latest update is kept, duplicate update is discarded require.Equal(t, 1, len(gotPendingChanges.ValidatorUpdates)) - require.Equal(t, valUpdates[1], gotPendingChanges.ValidatorUpdates[0]) // Only latest update should be kept + require.Equal(t, valUpdates[1], gotPendingChanges.ValidatorUpdates[0]) } - diff --git a/x/vaas/consumer/keeper/validators_test.go b/x/vaas/consumer/keeper/validators_test.go index 0442a28..247b542 100644 --- a/x/vaas/consumer/keeper/validators_test.go +++ b/x/vaas/consumer/keeper/validators_test.go @@ -206,7 +206,7 @@ func GenerateValidators(tb testing.TB) []*tmtypes.Validator { tb.Helper() numValidators := 4 validators := []*tmtypes.Validator{} - for i := 0; i < numValidators; i++ { + for i := range numValidators { cId := crypto.NewCryptoIdentityFromIntSeed(234 + i) pubKey := cId.TMCryptoPubKey() diff --git a/x/vaas/consumer/module.go b/x/vaas/consumer/module.go index b148fec..53278a3 100644 --- a/x/vaas/consumer/module.go +++ b/x/vaas/consumer/module.go @@ -145,21 +145,9 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } -// BeginBlock implements the AppModule interface -// Set the VSC ID for the subsequent block to the same value as the current block -// Panic if the provider's channel was established and then closed func (am AppModule) BeginBlock(goCtx context.Context) error { ctx := sdk.UnwrapSDKContext(goCtx) - channelID, found := am.keeper.GetProviderChannel(ctx) - if found && am.keeper.IsChannelClosed(ctx, channelID) { - // The VAAS channel was established, but it was then closed; - // the consumer chain is not secured anymore, but we allow it to run as a POA chain and log an error. - channelClosedMsg := fmt.Sprintf("VAAS channel %q was closed - shutdown consumer chain since it is not secured anymore", channelID) - am.keeper.Logger(ctx).Error(channelClosedMsg) - } - - // map next block height to the vscID of the current block height blockHeight := uint64(ctx.BlockHeight()) vID := am.keeper.GetHeightValsetUpdateID(ctx, blockHeight) am.keeper.SetHeightValsetUpdateID(ctx, blockHeight+1, vID) diff --git a/x/vaas/consumer/types/errors.go b/x/vaas/consumer/types/errors.go index f1fc684..679d908 100644 --- a/x/vaas/consumer/types/errors.go +++ b/x/vaas/consumer/types/errors.go @@ -4,7 +4,4 @@ import ( errorsmod "cosmossdk.io/errors" ) -// Consumer sentinel errors -var ( - ErrNoProposerChannelId = errorsmod.Register(ModuleName, 1, "no established VAAS channel") -) +var ErrInvalidProviderClient = errorsmod.Register(ModuleName, 2, "invalid provider client") diff --git a/x/vaas/consumer/types/genesis.go b/x/vaas/consumer/types/genesis.go index a61404c..6cac60b 100644 --- a/x/vaas/consumer/types/genesis.go +++ b/x/vaas/consumer/types/genesis.go @@ -14,7 +14,7 @@ import ( // Note: OutstandingDowntimeSlashing and LastTransmissionBlockHeight are deprecated // as slash and distribution features have been removed. func NewRestartGenesisState( - clientID, channelID string, + clientID string, initValSet []abci.ValidatorUpdate, heightToValsetUpdateIDs []HeightToValsetUpdateID, params vaastypes.ConsumerParams, @@ -27,7 +27,6 @@ func NewRestartGenesisState( }, HeightToValsetUpdateId: heightToValsetUpdateIDs, ProviderClientId: clientID, - ProviderChannelId: channelID, } } @@ -55,24 +54,6 @@ func NewInitialGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.Co } // Validate performs basic genesis state validation returning an error upon any failure. -// -// The three cases where a consumer chain starts/restarts -// expect the following optional and mandatory genesis states: -// -// 1. New chain starts: -// - Params, InitialValset // mandatory -// -// 1a. ConnectionId is empty -// - provider client state, provider consensus state // mandatory -// -// 1b. ConnectionId is not empty -// - provider client state, provider consensus state // nil -// -// 2. Chain restarts with CCV handshake still in progress: -// - Params, InitialValset, ProviderID, HeightToValidatorSetUpdateID // mandatory -// -// 3. Chain restarts with CCV handshake completed: -// - Params, InitialValset, ProviderID, channelID, HeightToValidatorSetUpdateID // mandatory func (gs GenesisState) Validate() error { if !gs.Params.Enabled { return nil @@ -85,53 +66,29 @@ func (gs GenesisState) Validate() error { } if gs.NewChain { - if gs.ConnectionId == "" { - // connection ID is not provided - if gs.Provider.ClientState == nil { - return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client state cannot be nil for new chain") - } - if err := gs.Provider.ClientState.Validate(); err != nil { - return errorsmod.Wrapf(vaastypes.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) - } - if gs.Provider.ConsensusState == nil { - return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") - } - if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { - return errorsmod.Wrapf(vaastypes.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) - } - } else { - // connection ID is provided - if gs.Provider.ClientState != nil { - return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client state must be nil when connection id is provided") - } - if gs.Provider.ConsensusState != nil { - return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider consensus state must be nil when connection id is provided") - } - if err := vaastypes.ValidateConnectionIdentifier(gs.ConnectionId); err != nil { - return errorsmod.Wrapf(vaastypes.ErrInvalidGenesis, "invalid connection id: %s", err.Error()) - } + if gs.Provider.ClientState == nil { + return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client state cannot be nil for new chain") + } + if err := gs.Provider.ClientState.Validate(); err != nil { + return errorsmod.Wrapf(vaastypes.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) + } + if gs.Provider.ConsensusState == nil { + return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") + } + if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { + return errorsmod.Wrapf(vaastypes.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) } if gs.ProviderClientId != "" { return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") } - if gs.ProviderChannelId != "" { - return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") - } if len(gs.HeightToValsetUpdateId) != 0 { return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "HeightToValsetUpdateId must be nil for new chain") } } else { - // NOTE: For restart genesis, we will verify initial validator set in InitGenesis. if gs.ProviderClientId == "" { return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state") } - /* if gs.HeightToValsetUpdateId == nil { - return errorsmod.Wrap( - vaastypes.ErrInvalidGenesis, - "empty height to validator set update id mapping", - ) - } */ if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { return errorsmod.Wrap(vaastypes.ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") } diff --git a/x/vaas/consumer/types/genesis.pb.go b/x/vaas/consumer/types/genesis.pb.go index 13c94f1..07a5546 100644 --- a/x/vaas/consumer/types/genesis.pb.go +++ b/x/vaas/consumer/types/genesis.pb.go @@ -34,23 +34,15 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { // ConsumerParams is a shared type with provider module Params types.ConsumerParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - // Client ID of the provider. Empty for a new chain, filled in on restart. + // Client ID of the provider. This is the primary identifier for the provider. ProviderClientId string `protobuf:"bytes,2,opt,name=provider_client_id,json=providerClientId,proto3" json:"provider_client_id,omitempty"` - // Channel ID of the provider. Empty for a new chain, filled in on restart. - ProviderChannelId string `protobuf:"bytes,3,opt,name=provider_channel_id,json=providerChannelId,proto3" json:"provider_channel_id,omitempty"` // true for new chain, false for chain restart. - NewChain bool `protobuf:"varint,4,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` + NewChain bool `protobuf:"varint,3,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` // HeightToValsetUpdateId nil on new chain, filled in on restart. - HeightToValsetUpdateId []HeightToValsetUpdateID `protobuf:"bytes,5,rep,name=height_to_valset_update_id,json=heightToValsetUpdateId,proto3" json:"height_to_valset_update_id"` + HeightToValsetUpdateId []HeightToValsetUpdateID `protobuf:"bytes,4,rep,name=height_to_valset_update_id,json=heightToValsetUpdateId,proto3" json:"height_to_valset_update_id"` // Flag indicating whether the consumer VAAS module starts in pre-VAAS state - PreVAAS bool `protobuf:"varint,9,opt,name=preVAAS,proto3" json:"preVAAS,omitempty"` - Provider types.ProviderInfo `protobuf:"bytes,10,opt,name=provider,proto3" json:"provider"` - // The ID of the connection end on the consumer chain on top of which the - // VAAS channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using provider.client_state and - // provider.consensus_state. - ConnectionId string `protobuf:"bytes,11,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` + PreVAAS bool `protobuf:"varint,5,opt,name=preVAAS,proto3" json:"preVAAS,omitempty"` + Provider types.ProviderInfo `protobuf:"bytes,6,opt,name=provider,proto3" json:"provider"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -100,13 +92,6 @@ func (m *GenesisState) GetProviderClientId() string { return "" } -func (m *GenesisState) GetProviderChannelId() string { - if m != nil { - return m.ProviderChannelId - } - return "" -} - func (m *GenesisState) GetNewChain() bool { if m != nil { return m.NewChain @@ -135,13 +120,6 @@ func (m *GenesisState) GetProvider() types.ProviderInfo { return types.ProviderInfo{} } -func (m *GenesisState) GetConnectionId() string { - if m != nil { - return m.ConnectionId - } - return "" -} - // HeightValsetUpdateID represents a mapping internal to the consumer VAAS module // which links a block height to each recv valset update id. type HeightToValsetUpdateID struct { @@ -204,38 +182,36 @@ func init() { func init() { proto.RegisterFile("vaas/consumer/v1/genesis.proto", fileDescriptor_cc650057d919c311) } var fileDescriptor_cc650057d919c311 = []byte{ - // 496 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x41, 0x6f, 0xd3, 0x30, - 0x14, 0x6e, 0xd6, 0x52, 0x5a, 0x77, 0xa0, 0x62, 0xa0, 0x44, 0x9d, 0xc8, 0xaa, 0x71, 0xc9, 0x01, - 0xc5, 0xea, 0x10, 0xe2, 0xbc, 0x15, 0x09, 0x72, 0x9b, 0x3a, 0xd8, 0x61, 0x97, 0xc8, 0x49, 0xde, - 0x12, 0xa3, 0xc4, 0x8e, 0x62, 0x37, 0x85, 0x7f, 0xc1, 0x8f, 0xe0, 0xc7, 0xec, 0xb8, 0x23, 0x27, - 0x84, 0xda, 0x3f, 0x82, 0xe2, 0x3a, 0x2d, 0x83, 0xde, 0xfc, 0xfc, 0x7d, 0x5f, 0xde, 0xfb, 0x3e, - 0xbf, 0x20, 0xa7, 0xa2, 0x54, 0x92, 0x48, 0x70, 0xb9, 0xc8, 0xa1, 0x24, 0xd5, 0x94, 0x24, 0xc0, - 0x41, 0x32, 0xe9, 0x15, 0xa5, 0x50, 0x02, 0x0f, 0x6b, 0xdc, 0x6b, 0x70, 0xaf, 0x9a, 0x8e, 0x5f, - 0x6a, 0x45, 0x35, 0x25, 0x32, 0xa5, 0x25, 0xc4, 0xc1, 0x16, 0xd3, 0x82, 0x31, 0x61, 0x61, 0x44, - 0x32, 0x96, 0xa4, 0x2a, 0xca, 0x18, 0x70, 0x25, 0x89, 0x02, 0x1e, 0x43, 0x99, 0x33, 0xae, 0x6a, - 0xd5, 0xae, 0x32, 0x82, 0x67, 0x89, 0x48, 0x84, 0x3e, 0x92, 0xfa, 0x64, 0x6e, 0x71, 0xd3, 0x65, - 0xc9, 0x4a, 0x30, 0x77, 0xc7, 0x89, 0x10, 0x49, 0x06, 0x44, 0x57, 0xe1, 0xe2, 0x86, 0x28, 0x96, - 0x83, 0x54, 0x34, 0x2f, 0x0c, 0xe1, 0xe8, 0xaf, 0x56, 0x34, 0x8c, 0x18, 0x51, 0xdf, 0x0a, 0x30, - 0x4e, 0x4e, 0x7e, 0xb4, 0xd1, 0xe1, 0x87, 0x8d, 0xb7, 0x4b, 0x45, 0x15, 0xe0, 0xb7, 0xa8, 0x5b, - 0xd0, 0x92, 0xe6, 0xd2, 0xb6, 0x26, 0x96, 0x3b, 0x38, 0x7d, 0xe1, 0x69, 0xaf, 0xd5, 0xd4, 0x9b, - 0x19, 0x4b, 0x17, 0x1a, 0x3e, 0xef, 0xdc, 0xfe, 0x3a, 0x6e, 0xcd, 0x0d, 0x19, 0xbf, 0x46, 0xb8, - 0x28, 0x45, 0xc5, 0x62, 0x28, 0x83, 0x8d, 0xc5, 0x80, 0xc5, 0xf6, 0xc1, 0xc4, 0x72, 0xfb, 0xf3, - 0x61, 0x83, 0xcc, 0x34, 0xe0, 0xc7, 0xd8, 0x43, 0x4f, 0x77, 0xec, 0x94, 0x72, 0x0e, 0x59, 0x4d, - 0x6f, 0x6b, 0xfa, 0x93, 0x2d, 0x7d, 0x83, 0xf8, 0x31, 0x3e, 0x42, 0x7d, 0x0e, 0xcb, 0x9a, 0xca, - 0xb8, 0xdd, 0x99, 0x58, 0x6e, 0x6f, 0xde, 0xe3, 0xb0, 0x9c, 0xd5, 0x35, 0xfe, 0x82, 0xc6, 0x29, - 0xd4, 0xd1, 0x06, 0x4a, 0x04, 0x15, 0xcd, 0x24, 0xa8, 0x60, 0x51, 0xc4, 0x54, 0x41, 0xfd, 0xcd, - 0x07, 0x93, 0xb6, 0x3b, 0x38, 0x75, 0xbd, 0x7f, 0x5f, 0xcc, 0xfb, 0xa8, 0x35, 0x9f, 0xc4, 0x95, - 0x56, 0x7c, 0xd6, 0x02, 0xff, 0xbd, 0xb1, 0x35, 0x4a, 0xf7, 0xa1, 0x31, 0xb6, 0xd1, 0xc3, 0xa2, - 0x84, 0xab, 0xb3, 0xb3, 0x4b, 0xbb, 0xaf, 0xc7, 0x68, 0x4a, 0xfc, 0x0e, 0xf5, 0x9a, 0xb9, 0x6d, - 0xa4, 0x93, 0x7b, 0xbe, 0x4d, 0xee, 0xc2, 0x00, 0x3e, 0xbf, 0x11, 0xa6, 0xc1, 0x96, 0x8c, 0x5f, - 0xa1, 0x47, 0x91, 0xe0, 0x1c, 0x22, 0xc5, 0x04, 0xaf, 0x27, 0x1e, 0xe8, 0x14, 0x0e, 0x77, 0x97, - 0x7e, 0x7c, 0x72, 0x8d, 0x46, 0xfb, 0xe7, 0xc5, 0x23, 0xd4, 0xdd, 0xcc, 0xaa, 0xdf, 0xab, 0x33, - 0x37, 0x15, 0x76, 0xd1, 0xf0, 0xbf, 0x2c, 0x0e, 0x34, 0xe3, 0x71, 0x75, 0xcf, 0xd3, 0xb9, 0x7f, - 0xbb, 0x72, 0xac, 0xbb, 0x95, 0x63, 0xfd, 0x5e, 0x39, 0xd6, 0xf7, 0xb5, 0xd3, 0xba, 0x5b, 0x3b, - 0xad, 0x9f, 0x6b, 0xa7, 0x75, 0x4d, 0x12, 0xa6, 0xd2, 0x45, 0xe8, 0x45, 0x22, 0x27, 0x34, 0xcb, - 0x18, 0x0f, 0x99, 0x92, 0x44, 0xef, 0xe0, 0x57, 0x72, 0xff, 0x17, 0xd1, 0x3b, 0x15, 0x76, 0xf5, - 0x52, 0xbd, 0xf9, 0x13, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa6, 0x41, 0x25, 0x40, 0x03, 0x00, 0x00, + // 456 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0x6e, 0xba, 0x52, 0x3a, 0x0f, 0xa1, 0xca, 0x82, 0x12, 0x75, 0x22, 0xab, 0x76, 0xca, 0x01, + 0xc5, 0xea, 0x10, 0xe2, 0xbc, 0x15, 0x09, 0x7a, 0x9b, 0x3a, 0xd8, 0x61, 0x97, 0xc8, 0x49, 0xde, + 0x12, 0xa3, 0xc4, 0x8e, 0x62, 0x37, 0x85, 0x7f, 0xc1, 0xcf, 0xda, 0x8d, 0x1d, 0x39, 0x21, 0xd4, + 0xfe, 0x11, 0x94, 0x57, 0xa7, 0x30, 0xe8, 0xcd, 0x9f, 0xbf, 0xf7, 0xf9, 0x7d, 0xdf, 0x7b, 0x26, + 0x5e, 0xcd, 0xb9, 0x66, 0xb1, 0x92, 0x7a, 0x59, 0x40, 0xc5, 0xea, 0x29, 0x4b, 0x41, 0x82, 0x16, + 0x3a, 0x28, 0x2b, 0x65, 0x14, 0x1d, 0x36, 0x7c, 0xd0, 0xf2, 0x41, 0x3d, 0x1d, 0xbf, 0x44, 0x45, + 0x3d, 0x65, 0x3a, 0xe3, 0x15, 0x24, 0xe1, 0x8e, 0x43, 0xc1, 0x98, 0x89, 0x28, 0x66, 0xb9, 0x48, + 0x33, 0x13, 0xe7, 0x02, 0xa4, 0xd1, 0xcc, 0x80, 0x4c, 0xa0, 0x2a, 0x84, 0x34, 0x8d, 0xea, 0x0f, + 0xb2, 0x82, 0x67, 0xa9, 0x4a, 0x15, 0x1e, 0x59, 0x73, 0xb2, 0xb7, 0xb4, 0xed, 0xb2, 0x12, 0x15, + 0xd8, 0xbb, 0x93, 0x54, 0xa9, 0x34, 0x07, 0x86, 0x28, 0x5a, 0xde, 0x32, 0x23, 0x0a, 0xd0, 0x86, + 0x17, 0xa5, 0x2d, 0x38, 0xfe, 0xab, 0x15, 0x8f, 0x62, 0xc1, 0xcc, 0xd7, 0x12, 0x6c, 0x92, 0xd3, + 0xef, 0x5d, 0xf2, 0xe4, 0xfd, 0x36, 0xdb, 0x95, 0xe1, 0x06, 0xe8, 0x1b, 0xd2, 0x2f, 0x79, 0xc5, + 0x0b, 0xed, 0x3a, 0x13, 0xc7, 0x3f, 0x3a, 0x7b, 0x11, 0x60, 0xd6, 0x7a, 0x1a, 0xcc, 0x6c, 0xa4, + 0x4b, 0xa4, 0x2f, 0x7a, 0x77, 0x3f, 0x4f, 0x3a, 0x0b, 0x5b, 0x4c, 0x5f, 0x11, 0x5a, 0x56, 0xaa, + 0x16, 0x09, 0x54, 0xe1, 0x36, 0x62, 0x28, 0x12, 0xb7, 0x3b, 0x71, 0xfc, 0xc3, 0xc5, 0xb0, 0x65, + 0x66, 0x48, 0xcc, 0x13, 0x7a, 0x4c, 0x0e, 0x25, 0xac, 0xc2, 0x38, 0xe3, 0x42, 0xba, 0x07, 0x13, + 0xc7, 0x1f, 0x2c, 0x06, 0x12, 0x56, 0xb3, 0x06, 0xd3, 0xcf, 0x64, 0x9c, 0x41, 0x33, 0xaa, 0xd0, + 0xa8, 0xb0, 0xe6, 0xb9, 0x06, 0x13, 0x2e, 0xcb, 0x84, 0x1b, 0x68, 0x9e, 0xec, 0x4d, 0x0e, 0xfc, + 0xa3, 0x33, 0x3f, 0xf8, 0x77, 0x03, 0xc1, 0x07, 0xd4, 0x7c, 0x54, 0xd7, 0xa8, 0xf8, 0x84, 0x82, + 0xf9, 0x3b, 0x6b, 0x73, 0x94, 0xed, 0x63, 0x13, 0xea, 0x92, 0xc7, 0x65, 0x05, 0xd7, 0xe7, 0xe7, + 0x57, 0xee, 0x23, 0xb4, 0xd1, 0x42, 0xfa, 0x96, 0x0c, 0x5a, 0xdb, 0x6e, 0x1f, 0x27, 0xf1, 0x7c, + 0x37, 0x89, 0x4b, 0x4b, 0xcc, 0xe5, 0xad, 0xb2, 0x0d, 0x76, 0xc5, 0xa7, 0x37, 0x64, 0xb4, 0xdf, + 0x0a, 0x1d, 0x91, 0xfe, 0xd6, 0x06, 0x8e, 0xb6, 0xb7, 0xb0, 0x88, 0xfa, 0x64, 0xf8, 0x5f, 0xcc, + 0x2e, 0x56, 0x3c, 0xad, 0x1f, 0xd8, 0xbd, 0x98, 0xdf, 0xad, 0x3d, 0xe7, 0x7e, 0xed, 0x39, 0xbf, + 0xd6, 0x9e, 0xf3, 0x6d, 0xe3, 0x75, 0xee, 0x37, 0x5e, 0xe7, 0xc7, 0xc6, 0xeb, 0xdc, 0xb0, 0x54, + 0x98, 0x6c, 0x19, 0x05, 0xb1, 0x2a, 0x18, 0xcf, 0x73, 0x21, 0x23, 0x61, 0x34, 0xc3, 0xef, 0xf2, + 0x85, 0x3d, 0xfc, 0xcd, 0xb8, 0xfe, 0xa8, 0x8f, 0xfb, 0x7f, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, + 0x93, 0x27, 0x57, 0x0f, 0xeb, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -258,13 +234,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x5a - } { size, err := m.Provider.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -274,7 +243,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x52 + dAtA[i] = 0x32 if m.PreVAAS { i-- if m.PreVAAS { @@ -283,7 +252,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0 } i-- - dAtA[i] = 0x48 + dAtA[i] = 0x28 } if len(m.HeightToValsetUpdateId) > 0 { for iNdEx := len(m.HeightToValsetUpdateId) - 1; iNdEx >= 0; iNdEx-- { @@ -296,7 +265,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } } if m.NewChain { @@ -307,14 +276,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0 } i-- - dAtA[i] = 0x20 - } - if len(m.ProviderChannelId) > 0 { - i -= len(m.ProviderChannelId) - copy(dAtA[i:], m.ProviderChannelId) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ProviderChannelId))) - i-- - dAtA[i] = 0x1a + dAtA[i] = 0x18 } if len(m.ProviderClientId) > 0 { i -= len(m.ProviderClientId) @@ -392,10 +354,6 @@ func (m *GenesisState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - l = len(m.ProviderChannelId) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } if m.NewChain { n += 2 } @@ -410,10 +368,6 @@ func (m *GenesisState) Size() (n int) { } l = m.Provider.Size() n += 1 + l + sovGenesis(uint64(l)) - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } return n } @@ -533,38 +487,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { m.ProviderClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderChannelId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProviderChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field NewChain", wireType) } @@ -584,7 +506,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } } m.NewChain = bool(v != 0) - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field HeightToValsetUpdateId", wireType) } @@ -618,7 +540,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 9: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field PreVAAS", wireType) } @@ -638,7 +560,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } } m.PreVAAS = bool(v != 0) - case 10: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) } @@ -671,38 +593,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/vaas/consumer/types/genesis_test.go b/x/vaas/consumer/types/genesis_test.go index 4cf96ab..a18e2a6 100644 --- a/x/vaas/consumer/types/genesis_test.go +++ b/x/vaas/consumer/types/genesis_test.go @@ -28,14 +28,10 @@ var ( upgradePath = []string{"upgrade", "upgradedIBCState"} ) -// TestValidateInitialGenesisState tests a NewInitialGenesisState instantiation, -// and its Validate() method over different genesis scenarios func TestValidateInitialGenesisState(t *testing.T) { - // generate validator public key cId := crypto.NewCryptoIdentityFromIntSeed(238934) pubKey := cId.TMCryptoPubKey() - // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) valHash := valSet.Hash() @@ -80,36 +76,16 @@ func TestValidateInitialGenesisState(t *testing.T) { true, }, { - "invalid new consumer genesis state: client id not empty", + "invalid new consumer genesis state: provider client id not empty", &types.GenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "", - NewChain: true, + Params: params, + NewChain: true, Provider: vaastypes.ProviderInfo{ ClientState: cs, ConsensusState: consensusState, InitialValSet: valUpdates, }, - HeightToValsetUpdateId: nil, - PreVAAS: false, - }, - true, - }, - { - "invalid new consumer genesis state: channel id not empty", - &types.GenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "ccvchannel", - NewChain: true, - Provider: vaastypes.ProviderInfo{ - ClientState: cs, - ConsensusState: consensusState, - InitialValSet: valUpdates, - }, - HeightToValsetUpdateId: nil, - PreVAAS: false, + ProviderClientId: "ccvclient", }, true, }, @@ -147,84 +123,12 @@ func TestValidateInitialGenesisState(t *testing.T) { types.NewInitialGenesisState(cs, consensusState, valUpdates, vaastypes.NewParams( true, - 0, // CCV timeout period cannot be 0 + 0, vaastypes.DefaultHistoricalEntries, vaastypes.DefaultConsumerUnbondingPeriod, )), true, }, - { - "invalid new consumer genesis state: connection id is invalid", - &types.GenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - Provider: vaastypes.ProviderInfo{ - ClientState: nil, - ConsensusState: nil, - InitialValSet: valUpdates, - }, - HeightToValsetUpdateId: nil, - PreVAAS: false, - ConnectionId: "invalid_connection/", - }, - true, - }, - { - "invalid new consumer genesis state: client state provided with connection id", - &types.GenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - Provider: vaastypes.ProviderInfo{ - ClientState: cs, - ConsensusState: nil, - InitialValSet: valUpdates, - }, - HeightToValsetUpdateId: nil, - PreVAAS: false, - ConnectionId: "connection-1", - }, - true, - }, - { - "invalid new consumer genesis state: consensus state provided with connection id", - &types.GenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - Provider: vaastypes.ProviderInfo{ - ClientState: nil, - ConsensusState: consensusState, - InitialValSet: valUpdates, - }, - HeightToValsetUpdateId: nil, - PreVAAS: false, - ConnectionId: "connection-1", - }, - true, - }, - { - "valid new consumer genesis state: connection id", - &types.GenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - Provider: vaastypes.ProviderInfo{ - ClientState: nil, - ConsensusState: nil, - InitialValSet: valUpdates, - }, - HeightToValsetUpdateId: nil, - PreVAAS: false, - ConnectionId: "connection-1", - }, - false, - }, } for _, c := range cases { @@ -237,20 +141,15 @@ func TestValidateInitialGenesisState(t *testing.T) { } } -// TestValidateRestartConsumerGenesisState tests a NewRestartGenesisState instantiation, -// and its Validate() method over different genesis scenarios func TestValidateRestartConsumerGenesisState(t *testing.T) { - // generate validator private/public key cId := crypto.NewCryptoIdentityFromIntSeed(234234) pubKey := cId.TMCryptoPubKey() - // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) valHash := valSet.Hash() valUpdates := tmtypes.TM2PB.ValidatorUpdates(valSet) - // create default height to validator set update id mapping heightToValsetUpdateID := []types.HeightToValsetUpdateID{ {Height: 0, ValsetUpdateId: 0}, } @@ -268,59 +167,53 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { }{ { "valid restart consumer genesis state: handshake in progress", - types.NewRestartGenesisState("ccvclient", "", valUpdates, heightToValsetUpdateID, params), + types.NewRestartGenesisState("ccvclient", valUpdates, heightToValsetUpdateID, params), false, }, { "invalid restart consumer genesis state: provider id is empty", - types.NewRestartGenesisState("", "ccvchannel", valUpdates, heightToValsetUpdateID, params), + types.NewRestartGenesisState("", valUpdates, heightToValsetUpdateID, params), true, }, { "invalid restart consumer genesis: client state defined", &types.GenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "ccvchannel", - NewChain: false, + Params: params, + NewChain: false, Provider: vaastypes.ProviderInfo{ ClientState: cs, ConsensusState: nil, InitialValSet: valUpdates, }, - HeightToValsetUpdateId: nil, - PreVAAS: false, + ProviderClientId: "ccvclient", }, true, }, { "invalid restart consumer genesis: consensus state defined", &types.GenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "ccvchannel", - NewChain: false, + Params: params, + NewChain: false, Provider: vaastypes.ProviderInfo{ ClientState: nil, ConsensusState: consensusState, InitialValSet: valUpdates, }, - HeightToValsetUpdateId: nil, - PreVAAS: false, + ProviderClientId: "ccvclient", }, true, }, { "invalid restart consumer genesis state: nil initial validator set", - types.NewRestartGenesisState("ccvclient", "ccvchannel", nil, nil, params), + types.NewRestartGenesisState("ccvclient", nil, nil, params), true, }, { "invalid restart consumer genesis state: invalid params", - types.NewRestartGenesisState("ccvclient", "ccvchannel", valUpdates, nil, + types.NewRestartGenesisState("ccvclient", valUpdates, nil, vaastypes.NewParams( true, - 0, // CCV timeout period cannot be 0 + 0, vaastypes.DefaultHistoricalEntries, vaastypes.DefaultConsumerUnbondingPeriod, )), diff --git a/x/vaas/consumer/types/keys.go b/x/vaas/consumer/types/keys.go index 0f28601..0dd7d5d 100644 --- a/x/vaas/consumer/types/keys.go +++ b/x/vaas/consumer/types/keys.go @@ -20,17 +20,17 @@ const ( // Collection key prefixes for use with cosmossdk.io/collections var ( - PortPrefix = collections.NewPrefix(0) - UnbondingTimePrefix = collections.NewPrefix(2) - ProviderClientIDPrefix = collections.NewPrefix(3) - ProviderChannelIDPrefix = collections.NewPrefix(4) - PendingChangesPrefix = collections.NewPrefix(5) - PreVAASPrefix = collections.NewPrefix(7) - InitialValSetPrefix = collections.NewPrefix(8) - HistoricalInfoPrefix = collections.NewPrefix(11) - HeightValsetUpdateIDPrefix = collections.NewPrefix(13) - CrossChainValidatorPrefix = collections.NewPrefix(16) - InitGenesisHeightPrefix = collections.NewPrefix(17) - PrevStandaloneChainPrefix = collections.NewPrefix(19) - ParametersPrefix = collections.NewPrefix(22) + PortPrefix = collections.NewPrefix(0) + UnbondingTimePrefix = collections.NewPrefix(2) + ProviderClientIDPrefix = collections.NewPrefix(3) + PendingChangesPrefix = collections.NewPrefix(5) + PreVAASPrefix = collections.NewPrefix(7) + InitialValSetPrefix = collections.NewPrefix(8) + HistoricalInfoPrefix = collections.NewPrefix(11) + HeightValsetUpdateIDPrefix = collections.NewPrefix(13) + CrossChainValidatorPrefix = collections.NewPrefix(16) + InitGenesisHeightPrefix = collections.NewPrefix(17) + PrevStandaloneChainPrefix = collections.NewPrefix(19) + ParametersPrefix = collections.NewPrefix(22) + HighestValsetUpdateIDPrefix = collections.NewPrefix(23) ) diff --git a/x/vaas/consumer/types/query.pb.go b/x/vaas/consumer/types/query.pb.go index 69e851e..155791b 100644 --- a/x/vaas/consumer/types/query.pb.go +++ b/x/vaas/consumer/types/query.pb.go @@ -200,11 +200,11 @@ func (m *QueryProviderInfoResponse) GetProvider() ChainInfo { return ChainInfo{} } +// ChainInfo contains IBC connection information for a chain. type ChainInfo struct { - ChainID string `protobuf:"bytes,1,opt,name=chainID,proto3" json:"chainID,omitempty"` - ClientID string `protobuf:"bytes,2,opt,name=clientID,proto3" json:"clientID,omitempty"` - ConnectionID string `protobuf:"bytes,3,opt,name=connectionID,proto3" json:"connectionID,omitempty"` - ChannelID string `protobuf:"bytes,4,opt,name=channelID,proto3" json:"channelID,omitempty"` + ChainID string `protobuf:"bytes,1,opt,name=chainID,proto3" json:"chainID,omitempty"` + // clientID is the IBC client identifier. + ClientID string `protobuf:"bytes,2,opt,name=clientID,proto3" json:"clientID,omitempty"` } func (m *ChainInfo) Reset() { *m = ChainInfo{} } @@ -254,20 +254,6 @@ func (m *ChainInfo) GetClientID() string { return "" } -func (m *ChainInfo) GetConnectionID() string { - if m != nil { - return m.ConnectionID - } - return "" -} - -func (m *ChainInfo) GetChannelID() string { - if m != nil { - return m.ChannelID - } - return "" -} - func init() { proto.RegisterType((*QueryParamsRequest)(nil), "vaas.consumer.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "vaas.consumer.v1.QueryParamsResponse") @@ -279,36 +265,34 @@ func init() { func init() { proto.RegisterFile("vaas/consumer/v1/query.proto", fileDescriptor_e4bec0ed3ab6003b) } var fileDescriptor_e4bec0ed3ab6003b = []byte{ - // 457 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x31, 0x6f, 0xd4, 0x30, - 0x18, 0x3d, 0x1f, 0xa5, 0xf4, 0x5c, 0x06, 0x30, 0x45, 0x0d, 0xe1, 0x1a, 0x50, 0x54, 0x24, 0x04, - 0xc2, 0x56, 0x8a, 0x18, 0x59, 0x68, 0x96, 0x48, 0x0c, 0x90, 0x91, 0x05, 0xf9, 0x52, 0x93, 0x58, - 0xca, 0xd9, 0x69, 0xec, 0x44, 0xdc, 0x0a, 0x7f, 0x00, 0xc1, 0x80, 0xf8, 0x47, 0x1d, 0x2b, 0xb1, - 0x30, 0x21, 0x74, 0xc7, 0x0f, 0x41, 0x71, 0x9c, 0xc0, 0x5d, 0x40, 0x74, 0xb3, 0xbf, 0xf7, 0xbd, - 0xef, 0x3d, 0x7f, 0x2f, 0x81, 0xd3, 0x9a, 0x52, 0x45, 0x12, 0x29, 0x54, 0x35, 0x67, 0x25, 0xa9, - 0x03, 0x72, 0x5a, 0xb1, 0x72, 0x81, 0x8b, 0x52, 0x6a, 0x89, 0xae, 0x35, 0x28, 0xee, 0x50, 0x5c, - 0x07, 0xee, 0x81, 0xe9, 0xaf, 0x03, 0xa2, 0x32, 0x5a, 0xb2, 0x93, 0xd7, 0x3d, 0x66, 0x08, 0xee, - 0x5e, 0x2a, 0x53, 0x69, 0x8e, 0xa4, 0x39, 0xd9, 0xea, 0x34, 0x95, 0x32, 0xcd, 0x19, 0xa1, 0x05, - 0x27, 0x54, 0x08, 0xa9, 0xa9, 0xe6, 0x52, 0xa8, 0x16, 0xf5, 0xf7, 0x20, 0x7a, 0xd9, 0x68, 0xbe, - 0xa0, 0x25, 0x9d, 0xab, 0x98, 0x9d, 0x56, 0x4c, 0x69, 0xff, 0x39, 0xbc, 0xb1, 0x56, 0x55, 0x85, - 0x14, 0x8a, 0xa1, 0x27, 0x70, 0xbb, 0x30, 0x15, 0x07, 0xdc, 0x05, 0xf7, 0x77, 0x8f, 0xf6, 0xb1, - 0xb1, 0x58, 0x07, 0xf8, 0xd8, 0x3a, 0x69, 0x09, 0xcf, 0xb6, 0xce, 0xbe, 0xdf, 0x19, 0xc5, 0xb6, - 0xd9, 0x77, 0xa1, 0xd3, 0x4e, 0x2b, 0x65, 0xcd, 0x4f, 0x58, 0x19, 0x89, 0x37, 0xb2, 0x53, 0xfa, - 0x02, 0xe0, 0xad, 0xbf, 0x80, 0x56, 0xf0, 0x29, 0xdc, 0xe9, 0xde, 0x68, 0x25, 0x6f, 0xe3, 0xcd, - 0xad, 0xe0, 0xe3, 0x8c, 0x72, 0xd1, 0xd0, 0xac, 0x6c, 0x4f, 0x69, 0xe8, 0x85, 0x1d, 0xeb, 0x8c, - 0x2f, 0x4c, 0xef, 0x28, 0xfe, 0x7b, 0x00, 0x27, 0x3d, 0x8a, 0x1c, 0x78, 0x25, 0x31, 0x97, 0xd0, - 0x58, 0x99, 0xc4, 0xdd, 0x15, 0xb9, 0x70, 0x27, 0xc9, 0x39, 0x13, 0x3a, 0x0a, 0x8d, 0xcc, 0x24, - 0xee, 0xef, 0xc8, 0x87, 0x57, 0x13, 0x29, 0x04, 0x4b, 0x9a, 0xa5, 0x47, 0xa1, 0x73, 0xc9, 0xe0, - 0x6b, 0x35, 0x34, 0x85, 0x93, 0x24, 0xa3, 0x42, 0xb0, 0x3c, 0x0a, 0x9d, 0x2d, 0xd3, 0xf0, 0xbb, - 0x70, 0xf4, 0x79, 0x0c, 0x2f, 0x9b, 0x0d, 0xa1, 0x05, 0xdc, 0xfd, 0x23, 0x15, 0x74, 0x38, 0x7c, - 0xcb, 0x30, 0x4a, 0xf7, 0xde, 0x7f, 0xba, 0xda, 0x4d, 0xfb, 0x07, 0xef, 0xbe, 0xfe, 0xfc, 0x34, - 0xde, 0x47, 0x37, 0xc9, 0xfa, 0x37, 0xd9, 0x46, 0x88, 0x3e, 0x02, 0x78, 0x7d, 0x10, 0x13, 0x7a, - 0xf0, 0xaf, 0xd9, 0xc3, 0xa0, 0xdd, 0x87, 0x17, 0xea, 0xb5, 0x6e, 0x0e, 0x8d, 0x1b, 0x0f, 0x4d, - 0x37, 0xdd, 0xd8, 0xe6, 0x47, 0xbc, 0xc9, 0x2b, 0x3a, 0x5b, 0x7a, 0xe0, 0x7c, 0xe9, 0x81, 0x1f, - 0x4b, 0x0f, 0x7c, 0x58, 0x79, 0xa3, 0xf3, 0x95, 0x37, 0xfa, 0xb6, 0xf2, 0x46, 0xaf, 0x48, 0xca, - 0x75, 0x56, 0xcd, 0x70, 0x22, 0xe7, 0x84, 0xe6, 0x39, 0x17, 0x33, 0xae, 0x55, 0x3b, 0xeb, 0xed, - 0xc6, 0x48, 0xbd, 0x28, 0x98, 0x9a, 0x6d, 0x9b, 0xbf, 0xe1, 0xf1, 0xaf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xc4, 0x2d, 0x13, 0x48, 0x92, 0x03, 0x00, 0x00, + // 422 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xb1, 0xae, 0xd3, 0x30, + 0x14, 0x4d, 0x2a, 0x78, 0xbc, 0xfa, 0x2d, 0x60, 0x1e, 0x6a, 0x08, 0x6d, 0x40, 0x51, 0x91, 0x10, + 0x08, 0x5b, 0x29, 0x62, 0x64, 0x80, 0x76, 0xa9, 0xc4, 0x00, 0x19, 0x59, 0x90, 0x9b, 0x9a, 0xd4, + 0x52, 0x6a, 0xa7, 0xb1, 0x13, 0xd1, 0x95, 0x2f, 0x40, 0x30, 0x20, 0xfe, 0xa8, 0x63, 0x25, 0x16, + 0x26, 0x84, 0x5a, 0x3e, 0x04, 0xc5, 0x71, 0x22, 0xda, 0x80, 0xe8, 0xe6, 0x7b, 0xcf, 0x3d, 0xf7, + 0x1c, 0x1f, 0x1b, 0xf4, 0x0b, 0x42, 0x24, 0x8e, 0x04, 0x97, 0xf9, 0x92, 0x66, 0xb8, 0x08, 0xf0, + 0x2a, 0xa7, 0xd9, 0x1a, 0xa5, 0x99, 0x50, 0x02, 0x5e, 0x2f, 0x51, 0x54, 0xa3, 0xa8, 0x08, 0xdc, + 0x81, 0x9e, 0x2f, 0x02, 0x2c, 0x17, 0x24, 0xa3, 0xf3, 0xb7, 0x0d, 0xa6, 0x09, 0xee, 0x65, 0x2c, + 0x62, 0xa1, 0x8f, 0xb8, 0x3c, 0x99, 0x6e, 0x3f, 0x16, 0x22, 0x4e, 0x28, 0x26, 0x29, 0xc3, 0x84, + 0x73, 0xa1, 0x88, 0x62, 0x82, 0xcb, 0x0a, 0xf5, 0x2f, 0x01, 0x7c, 0x5d, 0x6a, 0xbe, 0x22, 0x19, + 0x59, 0xca, 0x90, 0xae, 0x72, 0x2a, 0x95, 0xff, 0x12, 0xdc, 0x3c, 0xe8, 0xca, 0x54, 0x70, 0x49, + 0xe1, 0x53, 0x70, 0x96, 0xea, 0x8e, 0x63, 0xdf, 0xb3, 0x1f, 0x5c, 0x8c, 0x7a, 0x48, 0x5b, 0x2c, + 0x02, 0x34, 0x36, 0x4e, 0x2a, 0xc2, 0x8b, 0x2b, 0x9b, 0x1f, 0x77, 0xad, 0xd0, 0x0c, 0xfb, 0x2e, + 0x70, 0xaa, 0x6d, 0x99, 0x28, 0xd8, 0x9c, 0x66, 0x53, 0xfe, 0x4e, 0xd4, 0x4a, 0x5f, 0x6d, 0x70, + 0xfb, 0x2f, 0xa0, 0x11, 0x7c, 0x06, 0xce, 0xeb, 0x3b, 0x1a, 0xc9, 0x3b, 0xe8, 0x38, 0x15, 0x34, + 0x5e, 0x10, 0xc6, 0x4b, 0x9a, 0x91, 0x6d, 0x28, 0x25, 0x3d, 0x35, 0x6b, 0x9d, 0xce, 0xc9, 0xf4, + 0x9a, 0xe2, 0x3f, 0x07, 0xdd, 0x06, 0x84, 0x0e, 0xb8, 0x16, 0xe9, 0x62, 0xa2, 0x9d, 0x74, 0xc3, + 0xba, 0x84, 0x2e, 0x38, 0x8f, 0x12, 0x46, 0xb9, 0x9a, 0x4e, 0xb4, 0x4a, 0x37, 0x6c, 0xea, 0xd1, + 0x97, 0x0e, 0xb8, 0xaa, 0xaf, 0x07, 0xd7, 0xe0, 0xe2, 0x8f, 0x48, 0xe1, 0xb0, 0x6d, 0xa4, 0xfd, + 0x0e, 0xee, 0xfd, 0xff, 0x4c, 0x55, 0x31, 0xf9, 0x83, 0x0f, 0xdf, 0x7e, 0x7d, 0xee, 0xf4, 0xe0, + 0x2d, 0x7c, 0xf8, 0xa1, 0xaa, 0xfc, 0xe1, 0x27, 0x1b, 0xdc, 0x68, 0x65, 0x0c, 0x1f, 0xfe, 0x6b, + 0x77, 0xfb, 0x95, 0xdc, 0x47, 0x27, 0xcd, 0x1a, 0x37, 0x43, 0xed, 0xc6, 0x83, 0xfd, 0x63, 0x37, + 0x66, 0xf8, 0x31, 0x2b, 0xc3, 0x9e, 0x6e, 0x76, 0x9e, 0xbd, 0xdd, 0x79, 0xf6, 0xcf, 0x9d, 0x67, + 0x7f, 0xdc, 0x7b, 0xd6, 0x76, 0xef, 0x59, 0xdf, 0xf7, 0x9e, 0xf5, 0x06, 0xc7, 0x4c, 0x2d, 0xf2, + 0x19, 0x8a, 0xc4, 0x12, 0x93, 0x24, 0x61, 0x7c, 0xc6, 0x94, 0xac, 0x76, 0xbd, 0x3f, 0x5a, 0xa9, + 0xd6, 0x29, 0x95, 0xb3, 0x33, 0xfd, 0x95, 0x9f, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x42, 0xb1, + 0xd8, 0x33, 0x4f, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -325,6 +309,7 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // QueryParams queries the vaas/consumer module parameters. QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // QueryProviderInfo returns information about the provider chain connection. QueryProviderInfo(ctx context.Context, in *QueryProviderInfoRequest, opts ...grpc.CallOption) (*QueryProviderInfoResponse, error) } @@ -358,6 +343,7 @@ func (c *queryClient) QueryProviderInfo(ctx context.Context, in *QueryProviderIn type QueryServer interface { // QueryParams queries the vaas/consumer module parameters. QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // QueryProviderInfo returns information about the provider chain connection. QueryProviderInfo(context.Context, *QueryProviderInfoRequest) (*QueryProviderInfoResponse, error) } @@ -571,20 +557,6 @@ func (m *ChainInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ChannelID) > 0 { - i -= len(m.ChannelID) - copy(dAtA[i:], m.ChannelID) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChannelID))) - i-- - dAtA[i] = 0x22 - } - if len(m.ConnectionID) > 0 { - i -= len(m.ConnectionID) - copy(dAtA[i:], m.ConnectionID) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ConnectionID))) - i-- - dAtA[i] = 0x1a - } if len(m.ClientID) > 0 { i -= len(m.ClientID) copy(dAtA[i:], m.ClientID) @@ -669,14 +641,6 @@ func (m *ChainInfo) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - l = len(m.ConnectionID) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.ChannelID) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } return n } @@ -1078,70 +1042,6 @@ func (m *ChainInfo) Unmarshal(dAtA []byte) error { } m.ClientID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChannelID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/vaas/provider/client/cli/tx.go b/x/vaas/provider/client/cli/tx.go index 767542d..f8ec061 100644 --- a/x/vaas/provider/client/cli/tx.go +++ b/x/vaas/provider/client/cli/tx.go @@ -236,8 +236,7 @@ where create_consumer.json has the following structure: "spawn_time": "2024-08-29T12:26:16.529913Z", "unbonding_period": 1728000000000000, "ccv_timeout_period": 2419200000000000, - "historical_entries": 10000, - "connection_id": "" + "historical_entries": 10000 }, "infraction_parameters":{ "double_sign":{ @@ -331,8 +330,7 @@ where update_consumer.json has the following structure: "spawn_time": "2024-08-29T12:26:16.529913Z", "unbonding_period": 1728000000000000, "ccv_timeout_period": 2419200000000000, - "historical_entries": 10000, - "connection_id": "" + "historical_entries": 10000 }, "infraction_parameters":{ "double_sign":{ diff --git a/x/vaas/provider/ibc_module.go b/x/vaas/provider/ibc_module.go index cf8f6f5..2ecc60e 100644 --- a/x/vaas/provider/ibc_module.go +++ b/x/vaas/provider/ibc_module.go @@ -1,13 +1,15 @@ package provider import ( + "bytes" + "strconv" + "github.com/allinbits/vaas/x/vaas/provider/keeper" providertypes "github.com/allinbits/vaas/x/vaas/provider/types" vaastypes "github.com/allinbits/vaas/x/vaas/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" - ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/ibc-go/v10/modules/core/api" errorsmod "cosmossdk.io/errors" @@ -15,213 +17,117 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// OnChanOpenInit implements the IBCModule interface -// -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-coinit1 -// Spec Tag: [CCV-PCF-COINIT.1] -func (am AppModule) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - return version, errorsmod.Wrap(vaastypes.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") -} +var _ api.IBCModule = (*IBCModule)(nil) -// OnChanOpenTry implements the IBCModule interface -// -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-cotry1 -// Spec tag: [CCV-PCF-COTRY.1] -func (am AppModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (metadata string, err error) { - // Validate parameters - if err := validateVAASChannelParams( - ctx, am.keeper, order, portID, - ); err != nil { - return "", err - } - - // ensure the counterparty port ID matches the expected consumer port ID - if counterparty.PortId != vaastypes.ConsumerPortID { - return "", errorsmod.Wrapf(porttypes.ErrInvalidPort, - "invalid counterparty port: %s, expected %s", counterparty.PortId, vaastypes.ConsumerPortID) - } - - // ensure the counter party version matches the expected version - if counterpartyVersion != vaastypes.Version { - return "", errorsmod.Wrapf( - vaastypes.ErrInvalidVersion, "invalid counterparty version: got: %s, expected %s", - counterpartyVersion, vaastypes.Version) - } - - if err := am.keeper.VerifyConsumerChain( - ctx, channelID, connectionHops, - ); err != nil { - return "", err - } +type IBCModule struct { + keeper *keeper.Keeper +} - md := vaastypes.HandshakeMetadata{ - Version: vaastypes.Version, - } - mdBz, err := (&md).Marshal() - if err != nil { - return "", errorsmod.Wrapf(vaastypes.ErrInvalidHandshakeMetadata, - "error marshalling ibc-try metadata: %v", err) - } - return string(mdBz), nil +func NewIBCModule(k *keeper.Keeper) IBCModule { + return IBCModule{keeper: k} } -// validateVAASChannelParams validates a VAAS channel -func validateVAASChannelParams( +func (im IBCModule) OnSendPacket( ctx sdk.Context, - keeper *keeper.Keeper, - order channeltypes.Order, - portID string, + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + signer sdk.AccAddress, ) error { - if order != channeltypes.ORDERED { - return errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.ORDERED, order) + if payload.SourcePort != vaastypes.ProviderAppID { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, + "invalid source port: expected %s, got %s", vaastypes.ProviderAppID, payload.SourcePort) } - - // the port ID must match the port ID the VAAS module is bounded to - boundPort := keeper.GetPort(ctx) - if boundPort != portID { - return errorsmod.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) + if payload.DestinationPort != vaastypes.ConsumerAppID { + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, + "invalid destination port: expected %s, got %s", vaastypes.ConsumerAppID, payload.DestinationPort) } - return nil -} - -// OnChanOpenAck implements the IBCModule interface -// -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-coack1 -// Spec tag: [CCV-PCF-COACK.1] -func (am AppModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyChannelID string, - counterpartyVersion string, -) error { - return errorsmod.Wrap(vaastypes.ErrInvalidChannelFlow, "channel handshake must be initiated by consumer chain") -} - -// OnChanOpenConfirm implements the IBCModule interface -// -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-coconfirm1 -// Spec tag: [CCV-PCF-COCONFIRM.1] -func (am AppModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - err := am.keeper.SetConsumerChain(ctx, channelID) - if err != nil { - return err + if signer.String() != im.keeper.GetAuthority() { + return errorsmod.Wrapf( + sdkerrors.ErrUnauthorized, + "signer %s is different from authority %s", + signer.String(), + im.keeper.GetAuthority(), + ) } - return nil -} -// OnChanCloseInit implements the IBCModule interface -func (am AppModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - // Disallow user-initiated channel closing for provider channels - return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") -} + im.keeper.Logger(ctx).Debug("OnSendPacket", + "sourceClient", sourceClient, + "destinationClient", destinationClient, + "sequence", sequence, + ) -// OnChanCloseConfirm implements the IBCModule interface -func (am AppModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { return nil } -// OnRecvPacket implements the IBCModule interface. -// The provider does not expect to receive any packets from consumers. -func (am AppModule) OnRecvPacket( +func (im IBCModule) OnRecvPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - _ sdk.AccAddress, -) ibcexported.Acknowledgement { - return channeltypes.NewErrorAcknowledgement( - errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "provider does not accept packets"), + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, +) channeltypesv2.RecvPacketResult { + im.keeper.Logger(ctx).Error("provider received unexpected packet", + "sourceClient", sourceClient, + "destinationClient", destinationClient, + "sequence", sequence, ) + + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } } -// OnAcknowledgementPacket implements the IBCModule interface -func (am AppModule) OnAcknowledgementPacket( +func (im IBCModule) OnTimeoutPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - acknowledgement []byte, - _ sdk.AccAddress, + sourceClient string, + destinationClient string, + sequence uint64, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, ) error { - var ack channeltypes.Acknowledgement - if err := vaastypes.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal provider packet acknowledgement: %v", err) - } - - if err := am.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { + if err := im.keeper.OnTimeoutPacketV2(ctx, sourceClient); err != nil { return err } ctx.EventManager().EmitEvent( sdk.NewEvent( - vaastypes.EventTypePacket, + vaastypes.EventTypeTimeout, sdk.NewAttribute(sdk.AttributeKeyModule, providertypes.ModuleName), - sdk.NewAttribute(vaastypes.AttributeKeyAck, ack.String()), + sdk.NewAttribute("source_client", sourceClient), + sdk.NewAttribute("sequence", strconv.FormatUint(sequence, 10)), ), ) - switch resp := ack.Response.(type) { - case *channeltypes.Acknowledgement_Result: - ctx.EventManager().EmitEvent( - sdk.NewEvent( - vaastypes.EventTypePacket, - sdk.NewAttribute(vaastypes.AttributeKeyAckSuccess, string(resp.Result)), - ), - ) - case *channeltypes.Acknowledgement_Error: - ctx.EventManager().EmitEvent( - sdk.NewEvent( - vaastypes.EventTypePacket, - sdk.NewAttribute(vaastypes.AttributeKeyAckError, resp.Error), - ), - ) - } - return nil } -// OnTimeoutPacket implements the IBCModule interface -func (am AppModule) OnTimeoutPacket( +func (im IBCModule) OnAcknowledgementPacket( ctx sdk.Context, - _ string, - packet channeltypes.Packet, - _ sdk.AccAddress, + sourceClient string, + destinationClient string, + sequence uint64, + acknowledgement []byte, + payload channeltypesv2.Payload, + relayer sdk.AccAddress, ) error { - if err := am.keeper.OnTimeoutPacket(ctx, packet); err != nil { + ackError := "" + if bytes.Equal(acknowledgement, channeltypesv2.ErrorAcknowledgement[:]) { + ackError = "error acknowledgement received" + } + + if err := im.keeper.OnAcknowledgementPacketV2(ctx, sourceClient, ackError); err != nil { return err } ctx.EventManager().EmitEvent( sdk.NewEvent( - vaastypes.EventTypeTimeout, + vaastypes.EventTypePacket, sdk.NewAttribute(sdk.AttributeKeyModule, providertypes.ModuleName), + sdk.NewAttribute("source_client", sourceClient), + sdk.NewAttribute("sequence", strconv.FormatUint(sequence, 10)), ), ) diff --git a/x/vaas/provider/ibc_module_test.go b/x/vaas/provider/ibc_module_test.go new file mode 100644 index 0000000..6a6b3ff --- /dev/null +++ b/x/vaas/provider/ibc_module_test.go @@ -0,0 +1,104 @@ +package provider_test + +import ( + "testing" + "time" + + testkeeper "github.com/allinbits/vaas/testutil/keeper" + "github.com/allinbits/vaas/x/vaas/provider" + providertypes "github.com/allinbits/vaas/x/vaas/provider/types" + vaastypes "github.com/allinbits/vaas/x/vaas/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" +) + +func TestIBCModuleOnSendPacketRequiresAuthority(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + module := provider.NewIBCModule(&providerKeeper) + payload := channeltypesv2.Payload{ + SourcePort: vaastypes.ProviderAppID, + DestinationPort: vaastypes.ConsumerAppID, + } + + authority, err := sdk.AccAddressFromBech32(providerKeeper.GetAuthority()) + require.NoError(t, err) + require.NoError(t, module.OnSendPacket(ctx, "07-tendermint-0", "07-tendermint-1", 7, payload, authority)) + + otherSigner := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) + err = module.OnSendPacket(ctx, "07-tendermint-0", "07-tendermint-1", 7, payload, otherSigner) + require.ErrorContains(t, err, "different from authority") +} + +func TestIBCModuleOnAcknowledgementPacketHandlesErrorSentinel(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerID := "0" + clientID := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerID, clientID) + providerKeeper.SetConsumerPhase(ctx, consumerID, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerID, "consumer-chain") + + mocks.MockStakingKeeper.EXPECT().UnbondingTime(ctx).Return(21*24*time.Hour, nil).Times(1) + + module := provider.NewIBCModule(&providerKeeper) + err := module.OnAcknowledgementPacket( + ctx, + clientID, + "07-tendermint-1", + 65, + channeltypesv2.ErrorAcknowledgement[:], + channeltypesv2.Payload{}, + sdk.AccAddress{}, + ) + require.NoError(t, err) + require.Equal(t, providertypes.CONSUMER_PHASE_STOPPED, providerKeeper.GetConsumerPhase(ctx, consumerID)) + require.Equal(t, "65", findEventAttributeValue(ctx.EventManager().Events(), vaastypes.EventTypePacket, "sequence")) +} + +func TestIBCModuleOnTimeoutPacketFormatsSequence(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerID := "0" + clientID := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerID, clientID) + providerKeeper.SetConsumerPhase(ctx, consumerID, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerID, "consumer-chain") + + mocks.MockStakingKeeper.EXPECT().UnbondingTime(ctx).Return(21*24*time.Hour, nil).Times(1) + + module := provider.NewIBCModule(&providerKeeper) + err := module.OnTimeoutPacket( + ctx, + clientID, + "07-tendermint-1", + 42, + channeltypesv2.Payload{}, + sdk.AccAddress{}, + ) + require.NoError(t, err) + require.Equal(t, "42", findEventAttributeValue(ctx.EventManager().Events(), vaastypes.EventTypeTimeout, "sequence")) +} + +func findEventAttributeValue(events sdk.Events, eventType, key string) string { + for i := len(events) - 1; i >= 0; i-- { + event := events[i] + if event.Type != eventType { + continue + } + for _, attr := range event.Attributes { + if attr.Key == key { + return attr.Value + } + } + } + return "" +} diff --git a/x/vaas/provider/keeper/consumer_lifecycle.go b/x/vaas/provider/keeper/consumer_lifecycle.go index d0ac18a..41f933f 100644 --- a/x/vaas/provider/keeper/consumer_lifecycle.go +++ b/x/vaas/provider/keeper/consumer_lifecycle.go @@ -12,8 +12,6 @@ import ( tmtypes "github.com/cometbft/cometbft/types" clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" @@ -223,9 +221,7 @@ func (k Keeper) HasActiveConsumerValidator(ctx sdk.Context, consumerId string, a } // LaunchConsumer launches the chain with the provided consumer id by creating the consumer client and the respective -// consumer genesis file -// -// TODO add unit test for LaunchConsumer +// consumer genesis file. func (k Keeper) LaunchConsumer( ctx sdk.Context, bondedValidators []stakingtypes.Validator, @@ -251,17 +247,15 @@ func (k Keeper) LaunchConsumer( return fmt.Errorf("setting consumer genesis state, consumerId(%s): %w", consumerId, err) } - // compute the hash of the consumer initial validator updates updatesAsValSet, err := tmtypes.PB2TM.ValidatorUpdates(initialValUpdates) if err != nil { return fmt.Errorf("unable to create initial validator set from initial validator updates: %w", err) } valsetHash := tmtypes.NewValidatorSet(updatesAsValSet).Hash() - // create the consumer client and the genesis err = k.CreateConsumerClient(ctx, consumerId, valsetHash) if err != nil { - return fmt.Errorf("crating consumer client, consumerId(%s): %w", consumerId, err) + return fmt.Errorf("creating consumer client, consumerId(%s): %w", consumerId, err) } k.SetConsumerPhase(ctx, consumerId, types.CONSUMER_PHASE_LAUNCHED) @@ -269,7 +263,6 @@ func (k Keeper) LaunchConsumer( k.Logger(ctx).Info("consumer successfully launched", "consumerId", consumerId, "valset size", len(initialValUpdates), - "valsetHash", string(valsetHash), ) return nil @@ -277,6 +270,27 @@ func (k Keeper) LaunchConsumer( // CreateConsumerClient will create the CCV client for the given consumer chain. The CCV channel must be built // on top of the CCV client to ensure connection with the right consumer chain. +// +// IMPORTANT - Timing Constraint (Option B: New Consumer Chain): +// The consensus state for the new client is created with the current provider block time +// (ctx.BlockTime()). This timestamp will be used by the consumer's IBC client to verify +// headers from the new consumer chain. +// +// For the IBC client to remain valid, the consumer chain's genesis_time must satisfy: +// +// genesis_time - client_creation_time < trusting_period +// +// Where: +// - client_creation_time = the block time when this function executes (LaunchConsumer is called) +// - genesis_time = the time at which the consumer chain starts producing blocks +// - trusting_period = calculated from unbonding_period * trusting_period_fraction +// +// If this constraint is violated, the client will appear expired before any blocks can be +// relayed, causing relayers to fail with "trusted state outside of trusting period" errors. +// +// Recommended approach: Set the consumer's genesis_time to be close to the expected +// client_creation_time (spawn_time on the provider), or query the actual client creation +// timestamp and use it directly as genesis_time. func (k Keeper) CreateConsumerClient( ctx sdk.Context, consumerId string, @@ -286,11 +300,6 @@ func (k Keeper) CreateConsumerClient( if err != nil { return err } - if initializationRecord.ConnectionId != "" { - // there is no need to create a client if the connection ID is provided - // as the CCV channel will be built on top of the existing client - return nil - } phase := k.GetConsumerPhase(ctx, consumerId) if phase != types.CONSUMER_PHASE_INITIALIZED { @@ -321,7 +330,13 @@ func (k Keeper) CreateConsumerClient( clientState.TrustingPeriod = trustPeriod clientState.UnbondingPeriod = consumerUnbondingPeriod - // Create consensus state + // Create consensus state for the new consumer chain. + // - Timestamp: Current block time. IMPORTANT: Consumer's genesis_time must be within + // trusting_period of this timestamp, otherwise the client will appear expired. + // - Root: SentinelRoot is used as a placeholder since the consumer hasn't produced + // blocks yet. The client will be updated with real app hashes once blocks are relayed. + // - NextValidatorsHash: Hash of the initial validator set. This binds the client to + // the expected validators, so the first consumer block must be signed by this set. consensusState := ibctmtypes.NewConsensusState( ctx.BlockTime(), commitmenttypes.NewMerkleRoot([]byte(ibctmtypes.SentinelRoot)), @@ -386,102 +401,32 @@ func (k Keeper) MakeConsumerGenesis( initializationRecord.UnbondingPeriod, ) - var clientState *ibctmtypes.ClientState = nil - var tmConsState *ibctmtypes.ConsensusState = nil - var preVAAS bool - var counterpartyConnectionId string - - if initializationRecord.ConnectionId == "" { - // no connection ID provided - preVAAS = false - counterpartyConnectionId = "" - - // create provider client state and consensus state for the consumer to be able - // to create a provider client - - providerUnbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) - if err != nil { - return gen, errorsmod.Wrapf(types.ErrNoUnbondingTime, "unbonding time not found: %s", err) - } - height := clienttypes.GetSelfHeight(ctx) - - clientState = k.GetTemplateClient(ctx) - // this is the counter party chain ID for the consumer - clientState.ChainId = ctx.ChainID() - // this is the latest height the client was updated at, i.e., - // the height of the latest consensus state (see below) - clientState.LatestHeight = height - trustPeriod, err := vaastypes.CalculateTrustPeriod(providerUnbondingPeriod, k.GetTrustingPeriodFraction(ctx)) - if err != nil { - return gen, errorsmod.Wrapf(sdkerrors.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) - } - clientState.TrustingPeriod = trustPeriod - clientState.UnbondingPeriod = providerUnbondingPeriod - - consState, err := k.getSelfConsensusState(ctx, height) - if err != nil { - return gen, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) - } - tmConsState = consState - } else { - // connection ID provided - preVAAS = true - - // get the connection end - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, initializationRecord.ConnectionId) - if !found { - return gen, errorsmod.Wrapf(conntypes.ErrConnectionNotFound, - "could not find connection(%s)", initializationRecord.ConnectionId) - } - clientId := connectionEnd.ClientId - - // check that the underlying client is a Tendermint client and that the chain ID matches - clientState, found := k.clientKeeper.GetClientState(ctx, clientId) - if !found { - return gen, errorsmod.Wrapf(clienttypes.ErrClientNotFound, - "could not find client(%s) associated with connection(%s)", - clientId, initializationRecord.ConnectionId, - ) - } - tmClient, ok := clientState.(*ibctmtypes.ClientState) - if !ok { - return gen, errorsmod.Wrapf(clienttypes.ErrInvalidClientType, - "invalid client type. expected %s, got %s", - ibchost.Tendermint, clientState.ClientType(), - ) - } - consumerChainId, err := k.GetConsumerChainId(ctx, consumerId) - if err != nil { - return gen, err - } - if tmClient.ChainId != consumerChainId { - return gen, errorsmod.Wrapf(conntypes.ErrInvalidConnectionIdentifier, - "invalid connection(%s): expected chain ID %s, got %s", - initializationRecord.ConnectionId, consumerChainId, tmClient.ChainId, - ) - } - - // set the counterparty connection ID - counterpartyConnectionId = connectionEnd.Counterparty.ConnectionId - - k.SetConsumerClientId(ctx, consumerId, clientId) + providerUnbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) + if err != nil { + return gen, errorsmod.Wrapf(types.ErrNoUnbondingTime, "unbonding time not found: %s", err) + } + height := clienttypes.GetSelfHeight(ctx) - // Set minimum height for equivocation evidence from this consumer chain - k.SetEquivocationEvidenceMinHeight(ctx, consumerId, tmClient.LatestHeight.RevisionHeight) + clientState := k.GetTemplateClient(ctx) + clientState.ChainId = ctx.ChainID() + clientState.LatestHeight = height + trustPeriod, err := vaastypes.CalculateTrustPeriod(providerUnbondingPeriod, k.GetTrustingPeriodFraction(ctx)) + if err != nil { + return gen, errorsmod.Wrapf(sdkerrors.ErrInvalidHeight, "error %s calculating trusting_period for: %s", err, height) + } + clientState.TrustingPeriod = trustPeriod + clientState.UnbondingPeriod = providerUnbondingPeriod - k.Logger(ctx).Info("use existing client and connection for consumer chain", - "consumer id", consumerId, - "client id", clientId, - "connection id", initializationRecord.ConnectionId, - ) + consState, err := k.getSelfConsensusState(ctx, height) + if err != nil { + return gen, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) } gen = *vaastypes.NewInitialConsumerGenesisState( clientState, - tmConsState, + consState, initialValidatorUpdates, - preVAAS, - counterpartyConnectionId, + false, consumerGenesisParams, ) @@ -561,7 +506,7 @@ func (k Keeper) BeginBlockRemoveConsumers(ctx sdk.Context) error { return nil } -// DeleteConsumerChain cleans up the state of the given consumer chain +// DeleteConsumerChain cleans up the state of the given consumer chain. func (k Keeper) DeleteConsumerChain(ctx sdk.Context, consumerId string) (err error) { phase := k.GetConsumerPhase(ctx, consumerId) if phase != types.CONSUMER_PHASE_STOPPED { @@ -575,25 +520,6 @@ func (k Keeper) DeleteConsumerChain(ctx sdk.Context, consumerId string) (err err k.DeleteKeyAssignments(ctx, consumerId) k.DeleteEquivocationEvidenceMinHeight(ctx, consumerId) - // close channel and delete the mappings between chain ID and channel ID - if channelID, found := k.GetConsumerIdToChannelId(ctx, consumerId); found { - // Close the channel for the given channel ID on the condition - // that the channel exists and isn't already in the CLOSED state - channel, found := k.channelKeeper.GetChannel(ctx, vaastypes.ProviderPortID, channelID) - if found && channel.State != channeltypes.CLOSED { - err := k.chanCloseInit(ctx, channelID) - if err != nil { - k.Logger(ctx).Error("channel to consumer chain could not be closed", - "consumerId", consumerId, - "channelID", channelID, - "error", err.Error(), - ) - } - } - k.DeleteConsumerIdToChannelId(ctx, consumerId) - k.DeleteChannelIdToConsumerId(ctx, channelID) - } - k.DeleteInitChainHeight(ctx, consumerId) k.DeletePendingVSCPackets(ctx, consumerId) diff --git a/x/vaas/provider/keeper/genesis.go b/x/vaas/provider/keeper/genesis.go index f982905..87d2584 100644 --- a/x/vaas/provider/keeper/genesis.go +++ b/x/vaas/provider/keeper/genesis.go @@ -4,17 +4,14 @@ import ( "fmt" "github.com/allinbits/vaas/x/vaas/provider/types" - vaastypes "github.com/allinbits/vaas/x/vaas/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" ) -// InitGenesis initializes the CCV provider state and binds to PortID. +// InitGenesis initializes the CCV provider state. func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) []abci.ValidatorUpdate { - k.SetPort(ctx, vaastypes.ProviderPortID) - k.SetValidatorSetUpdateId(ctx, genState.ValsetUpdateId) for _, v2h := range genState.ValsetUpdateIdToHeight { k.SetValsetUpdateBlockHeight(ctx, v2h.ValsetUpdateId, v2h.Height) @@ -30,14 +27,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) []abc // the ConsumerGenesis validated in ConsumerState.Validate(). panic(fmt.Errorf("consumer chain genesis could not be persisted: %w", err)) } - // check if the CCV channel was established - if cs.ChannelId != "" { - k.SetChannelToConsumerId(ctx, cs.ChannelId, chainID) - k.SetConsumerIdToChannelId(ctx, chainID, cs.ChannelId) - k.SetInitChainHeight(ctx, chainID, cs.InitialHeight) - } else { - k.AppendPendingVSCPackets(ctx, chainID, cs.PendingValsetChanges...) - } + k.AppendPendingVSCPackets(ctx, chainID, cs.PendingValsetChanges...) } // Import key assignment state @@ -124,23 +114,12 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { // initial consumer chain states cs := types.ConsumerState{ - ChainId: consumerId, - ClientId: clientId, - ConsumerGenesis: gen, - Phase: k.GetConsumerPhase(ctx, consumerId), + ChainId: consumerId, + ClientId: clientId, + ConsumerGenesis: gen, + Phase: k.GetConsumerPhase(ctx, consumerId), + PendingValsetChanges: k.GetPendingVSCPackets(ctx, consumerId), } - - // try to find channel id for the current consumer chain - channelId, found := k.GetConsumerIdToChannelId(ctx, consumerId) - if found { - cs.ChannelId = channelId - cs.InitialHeight, found = k.GetInitChainHeight(ctx, consumerId) - if !found { - panic(fmt.Errorf("cannot find init height for consumer chain %s", consumerId)) - } - } - - cs.PendingValsetChanges = k.GetPendingVSCPackets(ctx, consumerId) consumerStates = append(consumerStates, cs) } diff --git a/x/vaas/provider/keeper/ibc_v2_integration_test.go b/x/vaas/provider/keeper/ibc_v2_integration_test.go new file mode 100644 index 0000000..c2615ca --- /dev/null +++ b/x/vaas/provider/keeper/ibc_v2_integration_test.go @@ -0,0 +1,166 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + abci "github.com/cometbft/cometbft/abci/types" + + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + + testkeeper "github.com/allinbits/vaas/testutil/keeper" + providertypes "github.com/allinbits/vaas/x/vaas/provider/types" + vaastypes "github.com/allinbits/vaas/x/vaas/types" +) + +// TestIBCV2PacketQueueing tests that VSC packets are correctly queued +// and stored for later sending via IBC v2 client-based routing. +func TestIBCV2PacketQueueing(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-1") + + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + + valUpdates := []abci.ValidatorUpdate{ + {PubKey: pk1, Power: 100}, + {PubKey: pk2, Power: 50}, + } + + vscPacket := vaastypes.NewValidatorSetChangePacketData(valUpdates, 1) + providerKeeper.AppendPendingVSCPackets(ctx, consumerId, vscPacket) + + pending := providerKeeper.GetPendingVSCPackets(ctx, consumerId) + require.Len(t, pending, 1) + require.Equal(t, uint64(1), pending[0].ValsetUpdateId) + require.Len(t, pending[0].ValidatorUpdates, 2) + + err = providerKeeper.SendVSCPacketsToChain(ctx, consumerId, clientId) + require.NoError(t, err) + + pending = providerKeeper.GetPendingVSCPackets(ctx, consumerId) + require.Len(t, pending, 1) +} + +// TestIBCV2MultipleConsumers tests queuing VSC packets for multiple consumers. +func TestIBCV2MultipleConsumers(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumers := []struct { + id string + clientId string + chainId string + }{ + {"0", "07-tendermint-0", "consumer-1"}, + {"1", "07-tendermint-1", "consumer-2"}, + {"2", "07-tendermint-2", "consumer-3"}, + } + + for _, c := range consumers { + providerKeeper.SetConsumerClientId(ctx, c.id, c.clientId) + providerKeeper.SetConsumerPhase(ctx, c.id, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, c.id, c.chainId) + } + + pk, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) + require.NoError(t, err) + valUpdates := []abci.ValidatorUpdate{{PubKey: pk, Power: 100}} + + for _, c := range consumers { + vscPacket := vaastypes.NewValidatorSetChangePacketData(valUpdates, 1) + providerKeeper.AppendPendingVSCPackets(ctx, c.id, vscPacket) + } + + for _, c := range consumers { + pending := providerKeeper.GetPendingVSCPackets(ctx, c.id) + require.Len(t, pending, 1, "consumer %s should have 1 pending packet", c.id) + } +} + +// TestIBCV2ConsumerRemovalOnTimeout tests that a timeout triggers consumer removal. +func TestIBCV2ConsumerRemovalOnTimeout(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-1") + + phase := providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_LAUNCHED, phase) + + gotConsumerId, found := providerKeeper.GetClientIdToConsumerId(ctx, clientId) + require.True(t, found) + require.Equal(t, consumerId, gotConsumerId) + + mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(time.Hour*24*21, nil).Times(1) + + err := providerKeeper.OnTimeoutPacketV2(ctx, clientId) + require.NoError(t, err) + + phase = providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_STOPPED, phase) +} + +// TestIBCV2ConsumerRemovalOnErrorAck tests that an error acknowledgement triggers consumer removal. +func TestIBCV2ConsumerRemovalOnErrorAck(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-1") + + phase := providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_LAUNCHED, phase) + + mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(time.Hour*24*21, nil).Times(1) + + err := providerKeeper.OnAcknowledgementPacketV2(ctx, clientId, "packet decode error") + require.NoError(t, err) + + phase = providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_STOPPED, phase) +} + +// TestIBCV2DualModeRouting tests that the provider correctly selects v2 routing +// when no channel exists but a client does. +func TestIBCV2DualModeRouting(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-1") + + gotClientId, found := providerKeeper.GetConsumerClientId(ctx, consumerId) + require.True(t, found) + require.Equal(t, clientId, gotClientId) + + gotConsumerId, found := providerKeeper.GetClientIdToConsumerId(ctx, clientId) + require.True(t, found) + require.Equal(t, consumerId, gotConsumerId) +} diff --git a/x/vaas/provider/keeper/indexes.go b/x/vaas/provider/keeper/indexes.go index 0213661..fe80e04 100644 --- a/x/vaas/provider/keeper/indexes.go +++ b/x/vaas/provider/keeper/indexes.go @@ -5,18 +5,6 @@ import ( "cosmossdk.io/collections/indexes" ) -// ConsumerChannelIndexes defines the indexes for consumer-channel mappings -// Primary key: ConsumerId (string) -> Value: ChannelId (string) -// Index: ByChannelId allows reverse lookup from ChannelId -> ConsumerId -type ConsumerChannelIndexes struct { - // ByChannelId is a unique index that maps ChannelId -> ConsumerId - ByChannelId *indexes.Unique[string, string, string] -} - -func (i ConsumerChannelIndexes) IndexesList() []collections.Index[string, string] { - return []collections.Index[string, string]{i.ByChannelId} -} - // ConsumerClientIndexes defines the indexes for consumer-client mappings // Primary key: ConsumerId (string) -> Value: ClientId (string) // Index: ByClientId allows reverse lookup from ClientId -> ConsumerId diff --git a/x/vaas/provider/keeper/keeper.go b/x/vaas/provider/keeper/keeper.go index 502bfcf..67ef46b 100644 --- a/x/vaas/provider/keeper/keeper.go +++ b/x/vaas/provider/keeper/keeper.go @@ -5,23 +5,17 @@ import ( "fmt" "time" - consumertypes "github.com/allinbits/vaas/x/vaas/consumer/types" "github.com/allinbits/vaas/x/vaas/provider/types" vaastypes "github.com/allinbits/vaas/x/vaas/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" "cosmossdk.io/collections" "cosmossdk.io/collections/indexes" addresscodec "cosmossdk.io/core/address" corestoretypes "cosmossdk.io/core/store" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" @@ -38,10 +32,9 @@ type Keeper struct { storeService corestoretypes.KVStoreService cdc codec.BinaryCodec - channelKeeper vaastypes.ChannelKeeper - connectionKeeper vaastypes.ConnectionKeeper accountKeeper vaastypes.AccountKeeper clientKeeper vaastypes.ClientKeeper + clientV2Keeper vaastypes.ClientV2Keeper stakingKeeper vaastypes.StakingKeeper slashingKeeper vaastypes.SlashingKeeper bankKeeper vaastypes.BankKeeper @@ -51,15 +44,14 @@ type Keeper struct { validatorAddressCodec addresscodec.Codec consensusAddressCodec addresscodec.Codec + channelKeeperV2 vaastypes.ChannelV2Keeper // Collections schema Schema collections.Schema // State collections - Port collections.Item[string] Params collections.Item[types.Params] ValidatorSetUpdateId collections.Sequence ConsumerId collections.Sequence - ConsumerChannels *collections.IndexedMap[string, string, ConsumerChannelIndexes] ConsumerClients *collections.IndexedMap[string, string, ConsumerClientIndexes] ConsumerGenesis collections.Map[string, vaastypes.ConsumerGenesisState] ValsetUpdateBlockHeight collections.Map[uint64, uint64] @@ -88,8 +80,8 @@ type Keeper struct { // NewKeeper creates a new provider Keeper instance func NewKeeper( cdc codec.BinaryCodec, storeService corestoretypes.KVStoreService, - channelKeeper vaastypes.ChannelKeeper, - connectionKeeper vaastypes.ConnectionKeeper, clientKeeper vaastypes.ClientKeeper, + clientKeeper vaastypes.ClientKeeper, + clientV2Keeper vaastypes.ClientV2Keeper, stakingKeeper vaastypes.StakingKeeper, slashingKeeper vaastypes.SlashingKeeper, accountKeeper vaastypes.AccountKeeper, bankKeeper vaastypes.BankKeeper, @@ -104,9 +96,8 @@ func NewKeeper( cdc: cdc, storeService: storeService, authority: authority, - channelKeeper: channelKeeper, - connectionKeeper: connectionKeeper, clientKeeper: clientKeeper, + clientV2Keeper: clientV2Keeper, stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, accountKeeper: accountKeeper, @@ -117,29 +108,9 @@ func NewKeeper( govKeeper: govKeeper, // Initialize collections - Port: collections.NewItem(sb, types.PortPrefix, "port", collections.StringValue), Params: collections.NewItem(sb, types.ParametersPrefix, "params", codec.CollValue[types.Params](cdc)), ValidatorSetUpdateId: collections.NewSequence(sb, types.ValidatorSetUpdateIdPrefix, "validator_set_update_id"), ConsumerId: collections.NewSequence(sb, types.ConsumerIdPrefix, "consumer_id"), - ConsumerChannels: collections.NewIndexedMap( - sb, - types.ConsumerIdToChannelIdPrefix, - "consumer_channels", - collections.StringKey, - collections.StringValue, - ConsumerChannelIndexes{ - ByChannelId: indexes.NewUnique( - sb, - types.ChannelIdToConsumerIdPrefix, - "consumer_channels_by_channel_id", - collections.StringKey, - collections.StringKey, - func(_ string, channelId string) (string, error) { - return channelId, nil - }, - ), - }, - ), ConsumerClients: collections.NewIndexedMap( sb, types.ConsumerIdToClientIdPrefix, @@ -192,6 +163,11 @@ func NewKeeper( return k } +// SetChannelKeeperV2 sets the IBC v2 channel keeper for client-based packet sending. +func (k *Keeper) SetChannelKeeperV2(keeper vaastypes.ChannelV2Keeper) { + k.channelKeeperV2 = keeper +} + // GetAuthority returns the x/ccv/provider module's authority. func (k Keeper) GetAuthority() string { return k.authority @@ -217,45 +193,6 @@ func (k Keeper) Logger(ctx context.Context) log.Logger { return sdkCtx.Logger().With("module", "x/"+ibchost.ModuleName+"-"+types.ModuleName) } -// GetPort returns the portID for the CCV module. Used in ExportGenesis -func (k Keeper) GetPort(ctx context.Context) string { - port, err := k.Port.Get(ctx) - if err != nil { - return "" - } - return port -} - -// SetPort sets the portID for the CCV module. Used in InitGenesis -func (k Keeper) SetPort(ctx context.Context, portID string) { - if err := k.Port.Set(ctx, portID); err != nil { - panic(fmt.Errorf("failed to set port: %w", err)) - } -} - -// SetConsumerIdToChannelId sets the mapping from a consumer id to the CCV channel id for that consumer chain. -func (k Keeper) SetConsumerIdToChannelId(ctx context.Context, consumerId, channelId string) { - if err := k.ConsumerChannels.Set(ctx, consumerId, channelId); err != nil { - panic(fmt.Errorf("failed to set consumer id to channel id: %w", err)) - } -} - -// GetConsumerIdToChannelId gets the CCV channelId for the given consumer id -func (k Keeper) GetConsumerIdToChannelId(ctx context.Context, consumerId string) (string, bool) { - channelId, err := k.ConsumerChannels.Get(ctx, consumerId) - if err != nil { - return "", false - } - return channelId, true -} - -// DeleteConsumerIdToChannelId deletes the CCV channel id for the given consumer id -func (k Keeper) DeleteConsumerIdToChannelId(ctx context.Context, consumerId string) { - if err := k.ConsumerChannels.Remove(ctx, consumerId); err != nil { - panic(fmt.Errorf("failed to delete consumer id to channel id: %w", err)) - } -} - // GetAllConsumersWithIBCClients returns the ids of all consumer chains that with IBC clients created. func (k Keeper) GetAllConsumersWithIBCClients(ctx context.Context) []string { consumerIds := []string{} @@ -277,73 +214,6 @@ func (k Keeper) GetAllConsumersWithIBCClients(ctx context.Context) []string { return consumerIds } -// SetChannelToConsumerId sets the mapping from the CCV channel id to the consumer id. -// Note: This is now handled automatically by the ConsumerChannels indexed map. -// This method is kept for API compatibility but the index is maintained automatically. -func (k Keeper) SetChannelToConsumerId(ctx context.Context, channelId, consumerId string) { - // The reverse index is automatically maintained by ConsumerChannels IndexedMap - // This method exists for backwards compatibility - if err := k.ConsumerChannels.Set(ctx, consumerId, channelId); err != nil { - panic(fmt.Errorf("failed to set channel to consumer id: %w", err)) - } -} - -// GetChannelIdToConsumerId gets the consumer id for a given CCV channel id -func (k Keeper) GetChannelIdToConsumerId(ctx context.Context, channelID string) (string, bool) { - consumerId, err := k.ConsumerChannels.Indexes.ByChannelId.MatchExact(ctx, channelID) - if err != nil { - return "", false - } - return consumerId, true -} - -// DeleteChannelIdToConsumerId deletes the consumer id for a given CCV channel id -// Note: This is now handled automatically by the ConsumerChannels indexed map. -func (k Keeper) DeleteChannelIdToConsumerId(ctx context.Context, channelId string) { - // Look up the consumerId first, then remove from the indexed map - consumerId, err := k.ConsumerChannels.Indexes.ByChannelId.MatchExact(ctx, channelId) - if err != nil { - return // Not found, nothing to delete - } - if err := k.ConsumerChannels.Remove(ctx, consumerId); err != nil { - panic(fmt.Errorf("failed to delete channel id to consumer id: %w", err)) - } -} - -// GetAllChannelToConsumers gets all channel to chain mappings. -// The results are sorted by ChannelId. -func (k Keeper) GetAllChannelToConsumers(ctx context.Context) (channelsToConsumers []struct { - ChannelId string - ConsumerId string -}, -) { - // Iterate over the ByChannelId index to get results sorted by ChannelId - iter, err := k.ConsumerChannels.Indexes.ByChannelId.Iterate(ctx, nil) - if err != nil { - return channelsToConsumers - } - defer iter.Close() - - for ; iter.Valid(); iter.Next() { - // FullKey returns Pair[ReferenceKey, PrimaryKey] = Pair[ChannelId, ConsumerId] - fullKey, err := iter.FullKey() - if err != nil { - continue - } - channelId := fullKey.K1() - consumerId := fullKey.K2() - channelsToConsumers = append(channelsToConsumers, struct { - ChannelId string - ConsumerId string - }{ - ChannelId: channelId, - ConsumerId: consumerId, - }) - } - - return channelsToConsumers -} - func (k Keeper) SetConsumerGenesis(ctx context.Context, consumerId string, gen vaastypes.ConsumerGenesisState) error { return k.ConsumerGenesis.Set(ctx, consumerId, gen) } @@ -362,113 +232,6 @@ func (k Keeper) DeleteConsumerGenesis(ctx context.Context, consumerId string) { } } -// VerifyConsumerChain verifies that the chain trying to connect on the channel handshake -// is the expected consumer chain. -func (k Keeper) VerifyConsumerChain(ctx sdk.Context, channelID string, connectionHops []string) error { - if len(connectionHops) != 1 { - return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to provider chain") - } - connectionID := connectionHops[0] - clientId, _, err := k.getUnderlyingClient(ctx, connectionID) - if err != nil { - return err - } - - consumerId, found := k.GetClientIdToConsumerId(ctx, clientId) - if !found { - return errorsmod.Wrapf(vaastypes.ErrConsumerChainNotFound, "cannot find consumer id associated with client id: %s", clientId) - } - ccvClientId, found := k.GetConsumerClientId(ctx, consumerId) - if !found { - return errorsmod.Wrapf(vaastypes.ErrClientNotFound, "cannot find client for consumer chain %s", consumerId) - } - if ccvClientId != clientId { - return errorsmod.Wrapf(types.ErrInvalidConsumerClient, "CCV channel must be built on top of CCV client. expected %s, got %s", ccvClientId, clientId) - } - - // Verify that there isn't already a CCV channel for the consumer chain - if prevChannel, ok := k.GetConsumerIdToChannelId(ctx, consumerId); ok { - return errorsmod.Wrapf(vaastypes.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain %s", prevChannel, consumerId) - } - return nil -} - -// SetConsumerChain ensures that the consumer chain has not already been -// set by a different channel, and then sets the consumer chain mappings -// in keeper, and set the channel status to validating. -func (k Keeper) SetConsumerChain(ctx sdk.Context, channelID string) error { - channel, ok := k.channelKeeper.GetChannel(ctx, vaastypes.ProviderPortID, channelID) - if !ok { - return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", channelID) - } - if len(channel.ConnectionHops) != 1 { - return errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to consumer chain") - } - connectionID := channel.ConnectionHops[0] - clientID, tmClient, err := k.getUnderlyingClient(ctx, connectionID) - if err != nil { - return err - } - consumerId, found := k.GetClientIdToConsumerId(ctx, clientID) - if !found { - return errorsmod.Wrapf(types.ErrNoConsumerId, "cannot find a consumer chain associated for this client: %s", clientID) - } - // Verify that there isn't already a CCV channel for the consumer chain - chainID := tmClient.ChainId - if prevChannelID, ok := k.GetConsumerIdToChannelId(ctx, consumerId); ok { - return errorsmod.Wrapf(vaastypes.ErrDuplicateChannel, "CCV channel with ID: %s already created for consumer chain with id %s", prevChannelID, consumerId) - } - - // the CCV channel is established: - // - set channel mappings - k.SetConsumerIdToChannelId(ctx, consumerId, channelID) - k.SetChannelToConsumerId(ctx, channelID, consumerId) - // - set current block height for the consumer chain initialization - k.SetInitChainHeight(ctx, consumerId, uint64(ctx.BlockHeight())) - - // emit event on successful addition - ctx.EventManager().EmitEvent( - sdk.NewEvent( - vaastypes.EventTypeChannelEstablished, - sdk.NewAttribute(sdk.AttributeKeyModule, consumertypes.ModuleName), - sdk.NewAttribute(types.AttributeConsumerId, consumerId), - sdk.NewAttribute(types.AttributeConsumerChainId, chainID), - sdk.NewAttribute(conntypes.AttributeKeyClientID, clientID), - sdk.NewAttribute(channeltypes.AttributeKeyChannelID, channelID), - sdk.NewAttribute(conntypes.AttributeKeyConnectionID, connectionID), - ), - ) - return nil -} - -// Retrieves the underlying client state corresponding to a connection ID. -func (k Keeper) getUnderlyingClient(ctx sdk.Context, connectionID string) ( - clientID string, tmClient *ibctmtypes.ClientState, err error, -) { - conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) - if !ok { - return "", nil, errorsmod.Wrapf(conntypes.ErrConnectionNotFound, - "connection not found for connection ID: %s", connectionID) - } - clientID = conn.ClientId - clientState, ok := k.clientKeeper.GetClientState(ctx, clientID) - if !ok { - return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, - "client not found for client ID: %s", conn.ClientId) - } - tmClient, ok = clientState.(*ibctmtypes.ClientState) - if !ok { - return "", nil, errorsmod.Wrapf(clienttypes.ErrInvalidClientType, - "invalid client type. expected %s, got %s", ibchost.Tendermint, clientState.ClientType()) - } - return clientID, tmClient, nil -} - -// chanCloseInit defines a wrapper function for the channel Keeper's function -func (k Keeper) chanCloseInit(ctx sdk.Context, channelID string) error { - return k.channelKeeper.ChanCloseInit(ctx, vaastypes.ProviderPortID, channelID) -} - func (k Keeper) IncrementValidatorSetUpdateId(ctx context.Context) { validatorSetUpdateId := k.GetValidatorSetUpdateId(ctx) k.SetValidatorSetUpdateId(ctx, validatorSetUpdateId+1) @@ -629,7 +392,7 @@ func (k Keeper) GetAllConsumerIds(ctx context.Context) []string { } consumerIds := []string{} - for i := uint64(0); i < latestConsumerId; i++ { + for i := range latestConsumerId { consumerId := fmt.Sprintf("%d", i) consumerIds = append(consumerIds, consumerId) } diff --git a/x/vaas/provider/keeper/keeper_test.go b/x/vaas/provider/keeper/keeper_test.go index b96d4ea..c902432 100644 --- a/x/vaas/provider/keeper/keeper_test.go +++ b/x/vaas/provider/keeper/keeper_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "fmt" + "slices" "sort" "testing" @@ -181,44 +182,11 @@ func TestGetAllConsumersWithIBCClients(t *testing.T) { require.Len(t, actualConsumerIds, len(consumerIds)) // sort the consumer ids before comparing they are equal - sort.Slice(consumerIds, func(i, j int) bool { - return consumerIds[i] < consumerIds[j] - }) - sort.Slice(actualConsumerIds, func(i, j int) bool { - return actualConsumerIds[i] < actualConsumerIds[j] - }) + slices.Sort(consumerIds) + slices.Sort(actualConsumerIds) require.Equal(t, consumerIds, actualConsumerIds) } -// TestGetAllChannelToChains tests GetAllChannelToConsumers behaviour correctness -func TestGetAllChannelToChains(t *testing.T) { - pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - consumerIds := []string{"2", "1", "4", "3"} - var expectedGetAllOrder []struct { - ChannelId string - ConsumerId string - } - - for i, consumerId := range consumerIds { - channelID := fmt.Sprintf("client-%d", len(consumerIds)-i) - pk.SetChannelToConsumerId(ctx, channelID, consumerId) - expectedGetAllOrder = append(expectedGetAllOrder, struct { - ChannelId string - ConsumerId string - }{ConsumerId: consumerId, ChannelId: channelID}) - } - // sorting by channelID - sort.Slice(expectedGetAllOrder, func(i, j int) bool { - return expectedGetAllOrder[i].ChannelId < expectedGetAllOrder[j].ChannelId - }) - - result := pk.GetAllChannelToConsumers(ctx) - require.Len(t, result, len(consumerIds)) - require.Equal(t, expectedGetAllOrder, result) -} - // TestConsumerClientId tests the getter, setter, and deletion of the client id <> consumer id mappings func TestConsumerClientId(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) diff --git a/x/vaas/provider/keeper/key_assignment_test.go b/x/vaas/provider/keeper/key_assignment_test.go index 631d4c8..7e82066 100644 --- a/x/vaas/provider/keeper/key_assignment_test.go +++ b/x/vaas/provider/keeper/key_assignment_test.go @@ -56,7 +56,7 @@ func TestGetAllValidatorConsumerPubKey(t *testing.T) { chainIDs := []string{"consumer-1", "consumer-2", "consumer-3"} numAssignments := 10 testAssignments := []types.ValidatorConsumerPubKey{} - for i := 0; i < numAssignments; i++ { + for i := range numAssignments { consumerKey := cryptotestutil.NewCryptoIdentityFromIntSeed(i).TMProtoCryptoPublicKey() providerAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(numAssignments + i).ProviderConsAddress() testAssignments = append(testAssignments, @@ -136,7 +136,7 @@ func TestGetAllValidatorsByConsumerAddr(t *testing.T) { chainIDs := []string{"consumer-1", "consumer-2", "consumer-3"} numAssignments := 10 testAssignments := []types.ValidatorByConsumerAddr{} - for i := 0; i < numAssignments; i++ { + for i := range numAssignments { consumerAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(i).ConsumerConsAddress() providerAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(numAssignments + i).ProviderConsAddress() testAssignments = append(testAssignments, @@ -245,7 +245,7 @@ func TestGetAllConsumerAddrsToPrune(t *testing.T) { chainIDs := []string{"consumer-1", "consumer-2", "consumer-3"} numAssignments := 10 testAssignments := []types.ConsumerAddrsToPrune{} - for i := 0; i < numAssignments; i++ { + for i := range numAssignments { consumerAddresses := types.AddressList{} for j := 0; j < 2*(i+1); j++ { addr := cryptotestutil.NewCryptoIdentityFromIntSeed(i * j).SDKValConsAddress() @@ -313,7 +313,6 @@ func checkCorrectPruningProperty(ctx sdk.Context, k providerkeeper.Keeper, chain good := true for _, valByConsAddr := range k.GetAllValidatorsByConsumerAddr(ctx, nil) { - valByConsAddr := valByConsAddr // Fix linter error G601 if _, ok := willBePruned[string(valByConsAddr.ConsumerAddr)]; ok { // Address will be pruned, everything is fine. continue @@ -685,7 +684,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { providerIDS := []*cryptotestutil.CryptoIdentity{} // Create some identities which the provider validators can assign to the consumer chain assignableIDS := []*cryptotestutil.CryptoIdentity{} - for i := 0; i < NUM_VALIDATORS; i++ { + for i := range NUM_VALIDATORS { providerIDS = append(providerIDS, cryptotestutil.NewCryptoIdentityFromIntSeed(i)) } // Notice that the assignable identities include the provider identities @@ -746,7 +745,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( gomock.Any(), gomock.Any(), - ).DoAndReturn(func(_ interface{}, valAddr sdk.ValAddress) (int64, error) { + ).DoAndReturn(func(_ any, valAddr sdk.ValAddress) (int64, error) { // When the mocked method is called, locate the appropriate validator // in the provider valset and return its power. for i, id := range providerIDS { @@ -764,7 +763,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( gomock.Any(), gomock.Any(), - ).DoAndReturn(func(_ interface{}, consP sdk.ConsAddress) (stakingtypes.Validator, bool) { + ).DoAndReturn(func(_ any, consP sdk.ConsAddress) (stakingtypes.Validator, bool) { for _, id := range providerIDS { if id.SDKValConsAddress().Equals(consP) { return id.SDKStakingValidator(), true @@ -838,7 +837,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { // Simulate a number of 'blocks' // Each block consists of a number of random key assignment tx's // and a random set of validator power updates - for block := 0; block < NUM_BLOCKS_PER_EXECUTION; block++ { + for range NUM_BLOCKS_PER_EXECUTION { stakingUpdates = getStakingUpdates() assignments = getAssignments() @@ -961,7 +960,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { ctrl.Finish() } - for i := 0; i < NUM_EXECUTIONS; i++ { + for range NUM_EXECUTIONS { runRandomExecution() } } diff --git a/x/vaas/provider/keeper/params.go b/x/vaas/provider/keeper/params.go index 0564b4f..7f79d0d 100644 --- a/x/vaas/provider/keeper/params.go +++ b/x/vaas/provider/keeper/params.go @@ -7,13 +7,25 @@ import ( "github.com/allinbits/vaas/x/vaas/provider/types" + clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" ) -// GetTemplateClient returns the template consumer client +// GetTemplateClient returns a template Tendermint client state with default values. +// The returned client state is a starting point that gets customized per-consumer +// (chain ID, heights, trusting/unbonding periods) before client creation. func (k Keeper) GetTemplateClient(ctx context.Context) *ibctmtypes.ClientState { - params := k.GetParams(ctx) - return params.TemplateClient + return ibctmtypes.NewClientState( + "", + ibctmtypes.DefaultTrustLevel, + 0, + 0, + types.DefaultMaxClockDrift, + clienttypes.Height{}, + commitmenttypes.GetSDKSpecs(), + []string{"upgrade", "upgradedIBCState"}, + ) } // GetTrustingPeriodFraction returns a TrustingPeriodFraction diff --git a/x/vaas/provider/keeper/params_test.go b/x/vaas/provider/keeper/params_test.go index a1f935e..53d3670 100644 --- a/x/vaas/provider/keeper/params_test.go +++ b/x/vaas/provider/keeper/params_test.go @@ -4,9 +4,6 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" testkeeper "github.com/allinbits/vaas/testutil/keeper" @@ -26,16 +23,6 @@ func TestParams(t *testing.T) { require.Equal(t, defaultParams, params) newParams := providertypes.NewParams( - ibctmtypes.NewClientState( - "", - ibctmtypes.DefaultTrustLevel, - 0, - 0, - time.Second*40, - clienttypes.Height{}, - commitmenttypes.GetSDKSpecs(), - []string{"ibc", "upgradedIBCState"}, - ), "0.25", 7*24*time.Hour, 600, diff --git a/x/vaas/provider/keeper/permissionless.go b/x/vaas/provider/keeper/permissionless.go index fcee000..efb0c6f 100644 --- a/x/vaas/provider/keeper/permissionless.go +++ b/x/vaas/provider/keeper/permissionless.go @@ -142,12 +142,14 @@ func (k Keeper) SetConsumerInitializationParameters(ctx context.Context, consume if err := types.ValidateInitialHeight(parameters.InitialHeight, chainId); err != nil { return fmt.Errorf("invalid initial height for consumer id (%s): %w", consumerId, err) } + if err := k.ConsumerInitParams.Set(ctx, consumerId, parameters); err != nil { return fmt.Errorf("failed to set initialization parameters for consumer id (%s): %w", consumerId, err) } return nil } +// validateExistingIBCLink validates that an existing IBC connection is fully functional. // DeleteConsumerInitializationParameters deletes the initialization parameters associated with this consumer id func (k Keeper) DeleteConsumerInitializationParameters(ctx context.Context, consumerId string) { if err := k.ConsumerInitParams.Remove(ctx, consumerId); err != nil { diff --git a/x/vaas/provider/keeper/relay.go b/x/vaas/provider/keeper/relay.go index b72ba02..f3f54d9 100644 --- a/x/vaas/provider/keeper/relay.go +++ b/x/vaas/provider/keeper/relay.go @@ -10,60 +10,52 @@ import ( abci "github.com/cometbft/cometbft/abci/types" clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" ) -// OnAcknowledgementPacket handles acknowledgments for sent VSC packets -func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, ack channeltypes.Acknowledgement) error { - if err := ack.GetError(); err != "" { - // The VSC packet data could not be successfully decoded. - // This should never happen. +func (k Keeper) OnAcknowledgementPacketV2(ctx sdk.Context, sourceClientID string, ackError string) error { + if ackError != "" { k.Logger(ctx).Error( "recv ErrorAcknowledgement", - "channelID", packet.SourceChannel, - "error", err, + "clientID", sourceClientID, + "error", ackError, ) - if consumerId, ok := k.GetChannelIdToConsumerId(ctx, packet.SourceChannel); ok { + if consumerId, found := k.GetClientIdToConsumerId(ctx, sourceClientID); found { return k.StopAndPrepareForConsumerRemoval(ctx, consumerId) } - return errorsmod.Wrapf(providertypes.ErrUnknownConsumerChannelId, "recv ErrorAcknowledgement on unknown channel %s", packet.SourceChannel) + return errorsmod.Wrapf(providertypes.ErrInvalidConsumerClient, "recv ErrorAcknowledgement on unknown client %s", sourceClientID) } return nil } -// OnTimeoutPacket aborts the transaction if no chain exists for the destination channel, -// otherwise it stops the chain -func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet) error { - consumerId, found := k.GetChannelIdToConsumerId(ctx, packet.SourceChannel) +func (k Keeper) OnTimeoutPacketV2(ctx sdk.Context, sourceClientID string) error { + consumerId, found := k.GetClientIdToConsumerId(ctx, sourceClientID) if !found { - k.Logger(ctx).Error("packet timeout, unknown channel:", "channelID", packet.SourceChannel) - // abort transaction - return errorsmod.Wrap( - channeltypes.ErrInvalidChannelState, - packet.SourceChannel, + k.Logger(ctx).Error("packet timeout, unknown client:", "clientID", sourceClientID) + return errorsmod.Wrapf( + providertypes.ErrInvalidConsumerClient, + "timeout on unknown client %s", sourceClientID, ) } - k.Logger(ctx).Info("packet timeout, deleting the consumer:", "consumerId", consumerId) + k.Logger(ctx).Info("packet timeout, deleting the consumer:", "consumerId", consumerId, "clientId", sourceClientID) return k.StopAndPrepareForConsumerRemoval(ctx, consumerId) } // EndBlockVSU contains the EndBlock logic needed for // the Validator Set Update sub-protocol func (k Keeper) EndBlockVSU(ctx sdk.Context) ([]abci.ValidatorUpdate, error) { - // logic to update the provider consensus validator set. valUpdates, err := k.ProviderValidatorUpdates(ctx) if err != nil { return []abci.ValidatorUpdate{}, fmt.Errorf("computing the provider consensus validator set: %w", err) } if k.BlocksUntilNextEpoch(ctx) == 0 { - // only queue and send VSCPackets at the boundaries of an epoch - - // collect validator updates if err := k.QueueVSCPackets(ctx); err != nil { return []abci.ValidatorUpdate{}, fmt.Errorf("queueing consumer validator updates: %w", err) } @@ -98,11 +90,9 @@ func (k Keeper) ProviderValidatorUpdates(ctx sdk.Context) ([]abci.ValidatorUpdat } nextValidators := []providertypes.ConsensusValidator{} - maxValidators := k.GetMaxProviderConsensusValidators(ctx) - // avoid out of range errors by bounding the max validators to the number of bonded validators - if maxValidators > int64(len(bondedValidators)) { - maxValidators = int64(len(bondedValidators)) - } + maxValidators := min( + // avoid out of range errors by bounding the max validators to the number of bonded validators + k.GetMaxProviderConsensusValidators(ctx), int64(len(bondedValidators))) for _, val := range bondedValidators[:maxValidators] { nextValidator, err := k.CreateProviderConsensusValidator(ctx, val) if err != nil { @@ -136,63 +126,139 @@ func (k Keeper) BlocksUntilNextEpoch(ctx sdk.Context) int64 { } } -// SendVSCPackets iterates over all consumers chains with created IBC clients -// and sends pending VSC packets to the chains with established CCV channels. -// If the CCV channel is not established for a consumer chain, -// the updates will remain queued until the channel is established -// -// TODO (mpoke): iterate only over consumers with established channel -- GetAllChannelToConsumers func (k Keeper) SendVSCPackets(ctx sdk.Context) error { for _, consumerId := range k.GetAllConsumersWithIBCClients(ctx) { if k.GetConsumerPhase(ctx, consumerId) != providertypes.CONSUMER_PHASE_LAUNCHED { - // only send VSCPackets to launched chains continue } - // check if CCV channel is established and send - if channelID, found := k.GetConsumerIdToChannelId(ctx, consumerId); found { - if err := k.SendVSCPacketsToChain(ctx, consumerId, channelID); err != nil { - return fmt.Errorf("sending VSCPacket to consumer, consumerId(%s): %w", consumerId, err) - } + clientID, found := k.GetConsumerClientId(ctx, consumerId) + if !found { + continue + } + + clientID = k.discoverActiveConsumerClient(ctx, consumerId, clientID) + + if err := k.SendVSCPacketsToChain(ctx, consumerId, clientID); err != nil { + return fmt.Errorf("sending VSCPacket to consumer, consumerId(%s): %w", consumerId, err) } } return nil } -// SendVSCPacketsToChain sends all queued VSC packets to the specified chain -func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, consumerId, channelId string) error { +// discoverActiveConsumerClient scans for IBC clients pointing to the consumer chain +// and returns the one with the highest latest height that has a counterparty registered. +// This allows the provider to use a client being actively updated by a relayer. +// The current client is only replaced if it is expired or frozen. +func (k Keeper) discoverActiveConsumerClient(ctx sdk.Context, consumerId, currentClientID string) string { + currentStatus := k.clientKeeper.GetClientStatus(ctx, currentClientID) + if currentStatus == ibcexported.Active { + cp, found := k.clientV2Keeper.GetClientCounterparty(ctx, currentClientID) + if found && cp.ClientId != "" { + return currentClientID + } + } + + chainID, err := k.GetConsumerChainId(ctx, consumerId) + if err != nil { + return currentClientID + } + + var bestClient string + var bestHeight uint64 + + k.clientKeeper.IterateClientStates(ctx, nil, func(clientID string, cs ibcexported.ClientState) bool { + tmCS, ok := cs.(*ibctmtypes.ClientState) + if !ok || tmCS.ChainId != chainID { + return false + } + if k.clientKeeper.GetClientStatus(ctx, clientID) != ibcexported.Active { + return false + } + cp, found := k.clientV2Keeper.GetClientCounterparty(ctx, clientID) + if !found || cp.ClientId == "" { + return false + } + height := tmCS.LatestHeight.RevisionHeight + if height > bestHeight { + bestHeight = height + bestClient = clientID + } + return false + }) + + if bestClient != "" { + k.Logger(ctx).Info("current client not active, switching to best active client", + "consumerId", consumerId, + "oldClient", currentClientID, + "oldStatus", string(currentStatus), + "newClient", bestClient, + ) + k.SetConsumerClientId(ctx, consumerId, bestClient) + return bestClient + } + return currentClientID +} + +func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, consumerId, clientId string) error { + if k.channelKeeperV2 == nil { + k.Logger(ctx).Debug("IBC v2 channel keeper not configured, skipping send", + "consumerId", consumerId, + ) + return nil + } + + timeoutPeriod := min(k.GetVAASTimeoutPeriod(ctx), channeltypesv2.MaxTimeoutDelta) + timeoutTimestamp := uint64(ctx.BlockTime().Add(timeoutPeriod).Unix()) + pendingPackets := k.GetPendingVSCPackets(ctx, consumerId) for _, data := range pendingPackets { - // send packet over IBC - err := vaastypes.SendIBCPacket( - ctx, - k.channelKeeper, - channelId, // source channel id - vaastypes.ProviderPortID, // source port id + payload := channeltypesv2.NewPayload( + vaastypes.ProviderAppID, + vaastypes.ConsumerAppID, + "vaas-v1", + "application/json", data.GetBytes(), - k.GetVAASTimeoutPeriod(ctx), ) + + msg := channeltypesv2.NewMsgSendPacket( + clientId, + timeoutTimestamp, + k.authority, + payload, + ) + + resp, err := k.channelKeeperV2.SendPacket(ctx, msg) if err != nil { if errors.Is(err, clienttypes.ErrClientNotActive) { - // IBC client is expired! - // leave the packet data stored to be sent once the client is upgraded - // the client cannot expire during iteration (in the middle of a block) - k.Logger(ctx).Info("IBC client is expired, cannot send VSC, leaving packet data stored:", + k.Logger(ctx).Info("IBC client expired, cannot send VSC, leaving packet data stored:", "consumerId", consumerId, + "clientId", clientId, "vscid", data.ValsetUpdateId, ) return nil } - // Not able to send packet over IBC! - k.Logger(ctx).Error("cannot send VSC, removing consumer:", "consumerId", consumerId, "vscid", data.ValsetUpdateId, "err", err.Error()) + + k.Logger(ctx).Error("cannot send VSC, removing consumer:", + "consumerId", consumerId, + "clientId", clientId, + "vscid", data.ValsetUpdateId, + "err", err.Error(), + ) err := k.StopAndPrepareForConsumerRemoval(ctx, consumerId) if err != nil { k.Logger(ctx).Info("consumer chain failed to stop:", "consumerId", consumerId, "error", err.Error()) - // return fmt.Errorf("stopping consumer, consumerId(%s): %w", consumerId, err) } return nil } + + k.Logger(ctx).Info("VSCPacket sent:", + "consumerId", consumerId, + "clientId", clientId, + "vscid", data.ValsetUpdateId, + "sequence", resp.Sequence, + ) } k.DeletePendingVSCPackets(ctx, consumerId) @@ -201,8 +267,6 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, consumerId, channelId str // QueueVSCPackets queues latest validator updates for every consumer chain // with the IBC client created. -// -// TODO (mpoke): iterate only over consumers with established channel -- GetAllChannelToConsumers func (k Keeper) QueueVSCPackets(ctx sdk.Context) error { valUpdateID := k.GetValidatorSetUpdateId(ctx) // current valset update ID diff --git a/x/vaas/provider/keeper/relay_test.go b/x/vaas/provider/keeper/relay_test.go new file mode 100644 index 0000000..a9631cf --- /dev/null +++ b/x/vaas/provider/keeper/relay_test.go @@ -0,0 +1,167 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + abci "github.com/cometbft/cometbft/abci/types" + + testkeeper "github.com/allinbits/vaas/testutil/keeper" + providertypes "github.com/allinbits/vaas/x/vaas/provider/types" + vaastypes "github.com/allinbits/vaas/x/vaas/types" +) + +// TestOnAcknowledgementPacketV2 tests the IBC v2 acknowledgement handler. +func TestOnAcknowledgementPacketV2(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + // Setup consumer with client mapping + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-chain") + + // Test 1: Success acknowledgement (empty error) - no action needed + err := providerKeeper.OnAcknowledgementPacketV2(ctx, clientId, "") + require.NoError(t, err) + + // Consumer should still be launched + phase := providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_LAUNCHED, phase) + + // Setup mock expectation for StopAndPrepareForConsumerRemoval + // which calls UnbondingTime + mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(time.Hour*24*21, nil).Times(1) + + // Test 2: Error acknowledgement - should trigger consumer removal + err = providerKeeper.OnAcknowledgementPacketV2(ctx, clientId, "packet data could not be decoded") + require.NoError(t, err) + + // Consumer should now be stopped + phase = providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_STOPPED, phase) +} + +// TestOnAcknowledgementPacketV2UnknownClient tests error handling for unknown clients. +func TestOnAcknowledgementPacketV2UnknownClient(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + unknownClientId := "07-tendermint-999" + + // Error ack with unknown client should return error + err := providerKeeper.OnAcknowledgementPacketV2(ctx, unknownClientId, "some error") + require.Error(t, err) + require.Contains(t, err.Error(), "unknown client") +} + +// TestOnTimeoutPacketV2 tests the IBC v2 timeout handler. +func TestOnTimeoutPacketV2(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + // Setup consumer with client mapping + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerChainId(ctx, consumerId, "consumer-chain") + + // Verify consumer is launched + phase := providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_LAUNCHED, phase) + + // Setup mock expectation for StopAndPrepareForConsumerRemoval + mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(time.Hour*24*21, nil).Times(1) + + // Timeout should trigger consumer removal + err := providerKeeper.OnTimeoutPacketV2(ctx, clientId) + require.NoError(t, err) + + // Consumer should now be stopped + phase = providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.CONSUMER_PHASE_STOPPED, phase) +} + +// TestOnTimeoutPacketV2UnknownClient tests error handling for unknown clients. +func TestOnTimeoutPacketV2UnknownClient(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + unknownClientId := "07-tendermint-999" + + // Timeout with unknown client should return error + err := providerKeeper.OnTimeoutPacketV2(ctx, unknownClientId) + require.Error(t, err) + require.Contains(t, err.Error(), "unknown client") +} + +// TestClientIdToConsumerIdMapping tests the client ID to consumer ID mapping used in IBC v2. +func TestClientIdToConsumerIdMapping(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "consumer-1" + clientId := "07-tendermint-0" + + // Initially no mapping + _, found := providerKeeper.GetClientIdToConsumerId(ctx, clientId) + require.False(t, found) + + // Set the mapping via SetConsumerClientId (which sets both directions) + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + + // Verify forward mapping + gotClientId, found := providerKeeper.GetConsumerClientId(ctx, consumerId) + require.True(t, found) + require.Equal(t, clientId, gotClientId) + + // Verify reverse mapping + gotConsumerId, found := providerKeeper.GetClientIdToConsumerId(ctx, clientId) + require.True(t, found) + require.Equal(t, consumerId, gotConsumerId) + + // Delete and verify both mappings are removed + providerKeeper.DeleteConsumerClientId(ctx, consumerId) + + _, found = providerKeeper.GetConsumerClientId(ctx, consumerId) + require.False(t, found) + _, found = providerKeeper.GetClientIdToConsumerId(ctx, clientId) + require.False(t, found) +} + +// TestSendVSCPacketsToChainNoHandler tests that SendVSCPacketsToChain gracefully +// handles the case when no IBC v2 channel keeper is configured. +func TestSendVSCPacketsToChainNoHandler(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + clientId := "07-tendermint-0" + + // Setup consumer with pending packets + providerKeeper.SetConsumerClientId(ctx, consumerId, clientId) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + + // Add a pending VSC packet + providerKeeper.AppendPendingVSCPackets(ctx, consumerId, vaastypes.ValidatorSetChangePacketData{ + ValidatorUpdates: []abci.ValidatorUpdate{}, + ValsetUpdateId: 1, + }) + + // Without setting ChannelKeeperV2, SendVSCPacketsToChain should return nil + // and not send any packets (graceful no-op) + err := providerKeeper.SendVSCPacketsToChain(ctx, consumerId, clientId) + require.NoError(t, err) + + // Pending packets should still be there since no keeper was configured + pending := providerKeeper.GetPendingVSCPackets(ctx, consumerId) + require.Len(t, pending, 1) +} diff --git a/x/vaas/provider/module.go b/x/vaas/provider/module.go index 5ed1bf5..73664a7 100644 --- a/x/vaas/provider/module.go +++ b/x/vaas/provider/module.go @@ -162,7 +162,8 @@ func (am AppModule) BeginBlock(ctx context.Context) error { func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) - // EndBlock logic needed for the Validator Set Update sub-protocol + am.keeper.EndBlockCIS(sdkCtx) + return am.keeper.EndBlockVSU(sdkCtx) } diff --git a/x/vaas/provider/types/consumer.go b/x/vaas/provider/types/consumer.go index fdfca77..0514174 100644 --- a/x/vaas/provider/types/consumer.go +++ b/x/vaas/provider/types/consumer.go @@ -6,8 +6,7 @@ import ( func NewConsumerStates( chainID, - clientID, - channelID string, + clientID string, initialHeight uint64, genesis vaastypes.ConsumerGenesisState, pendingValsetChanges []vaastypes.ValidatorSetChangePacketData, @@ -17,7 +16,6 @@ func NewConsumerStates( return ConsumerState{ ChainId: chainID, ClientId: clientID, - ChannelId: channelID, InitialHeight: initialHeight, PendingValsetChanges: pendingValsetChanges, ConsumerGenesis: genesis, diff --git a/x/vaas/provider/types/errors.go b/x/vaas/provider/types/errors.go index c7d826f..0123b8a 100644 --- a/x/vaas/provider/types/errors.go +++ b/x/vaas/provider/types/errors.go @@ -7,7 +7,6 @@ import ( // Provider sentinel errors var ( ErrUnknownConsumerId = errorsmod.Register(ModuleName, 3, "no consumer chain with this consumer id") - ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id") ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator") ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment") ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "VAAS channel is not built on correct client") diff --git a/x/vaas/provider/types/genesis.go b/x/vaas/provider/types/genesis.go index 454d528..4686f7d 100644 --- a/x/vaas/provider/types/genesis.go +++ b/x/vaas/provider/types/genesis.go @@ -6,8 +6,6 @@ import ( vaastypes "github.com/allinbits/vaas/x/vaas/types" - host "github.com/cosmos/ibc-go/v10/modules/core/24-host" - errorsmod "cosmossdk.io/errors" ) @@ -74,11 +72,11 @@ func (gs GenesisState) Validate() error { // Validate performs a consumer state validation returning an error upon any failure. // It ensures that the chain id, client id and consumer genesis states are valid and non-empty. func (cs ConsumerState) Validate() error { - if err := host.ChannelIdentifierValidator(cs.ChannelId); err != nil { - return err + if cs.ChainId == "" { + return errors.New("chain id cannot be empty") } - if err := host.ClientIdentifierValidator(cs.ClientId); err != nil { - return err + if cs.ClientId == "" { + return errors.New("client id cannot be empty") } // validate a new chain genesis if err := cs.ConsumerGenesis.Validate(); err != nil { diff --git a/x/vaas/provider/types/genesis.pb.go b/x/vaas/provider/types/genesis.pb.go index 52c5ac1..f0e4d4a 100644 --- a/x/vaas/provider/types/genesis.pb.go +++ b/x/vaas/provider/types/genesis.pb.go @@ -129,20 +129,18 @@ func (m *GenesisState) GetConsumerAddrsToPrune() []ConsumerAddrsToPrune { type ConsumerState struct { // ChainID defines the chain ID for the consumer chain ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - // ChannelID defines the IBC channel ID for the consumer chain - ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` - // ClientID defines the IBC client ID for the consumer chain - ClientId string `protobuf:"bytes,3,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // ClientID defines the IBC client ID for the consumer chain. + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` // InitalHeight defines the initial block height for the consumer chain - InitialHeight uint64 `protobuf:"varint,4,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height,omitempty"` + InitialHeight uint64 `protobuf:"varint,3,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height,omitempty"` // ConsumerGenesis defines the initial consumer chain genesis states - ConsumerGenesis types.ConsumerGenesisState `protobuf:"bytes,5,opt,name=consumer_genesis,json=consumerGenesis,proto3" json:"consumer_genesis"` + ConsumerGenesis types.ConsumerGenesisState `protobuf:"bytes,4,opt,name=consumer_genesis,json=consumerGenesis,proto3" json:"consumer_genesis"` // PendingValsetChanges defines the pending validator set changes for the // consumer chain - PendingValsetChanges []types.ValidatorSetChangePacketData `protobuf:"bytes,6,rep,name=pending_valset_changes,json=pendingValsetChanges,proto3" json:"pending_valset_changes"` - SlashDowntimeAck []string `protobuf:"bytes,7,rep,name=slash_downtime_ack,json=slashDowntimeAck,proto3" json:"slash_downtime_ack,omitempty"` + PendingValsetChanges []types.ValidatorSetChangePacketData `protobuf:"bytes,5,rep,name=pending_valset_changes,json=pendingValsetChanges,proto3" json:"pending_valset_changes"` + SlashDowntimeAck []string `protobuf:"bytes,6,rep,name=slash_downtime_ack,json=slashDowntimeAck,proto3" json:"slash_downtime_ack,omitempty"` // the phase of the consumer chain - Phase ConsumerPhase `protobuf:"varint,8,opt,name=phase,proto3,enum=vaas.provider.v1.ConsumerPhase" json:"phase,omitempty"` + Phase ConsumerPhase `protobuf:"varint,7,opt,name=phase,proto3,enum=vaas.provider.v1.ConsumerPhase" json:"phase,omitempty"` } func (m *ConsumerState) Reset() { *m = ConsumerState{} } @@ -185,13 +183,6 @@ func (m *ConsumerState) GetChainId() string { return "" } -func (m *ConsumerState) GetChannelId() string { - if m != nil { - return m.ChannelId - } - return "" -} - func (m *ConsumerState) GetClientId() string { if m != nil { return m.ClientId @@ -297,49 +288,48 @@ func init() { func init() { proto.RegisterFile("vaas/provider/v1/genesis.proto", fileDescriptor_c9071b84cde652f9) } var fileDescriptor_c9071b84cde652f9 = []byte{ - // 668 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0x8d, 0x9b, 0x9f, 0x36, 0xd3, 0xaf, 0xf9, 0xa2, 0x51, 0x15, 0x4c, 0xab, 0x3a, 0x51, 0xa4, - 0xa2, 0x20, 0xa1, 0x58, 0x2d, 0x82, 0x05, 0xbb, 0xa6, 0x95, 0x20, 0x42, 0x42, 0x51, 0x5a, 0x58, - 0x74, 0x63, 0x4d, 0x3c, 0x23, 0x7b, 0x88, 0x33, 0xb6, 0x3c, 0x13, 0x17, 0xbf, 0x02, 0x2b, 0x5e, - 0x82, 0x77, 0xe9, 0xb2, 0x4b, 0x56, 0x15, 0x6a, 0xdf, 0x80, 0x27, 0x40, 0x33, 0x1e, 0x9b, 0xe6, - 0x07, 0x10, 0x3b, 0xfb, 0x9e, 0x33, 0xe7, 0xdc, 0x3b, 0xf7, 0xde, 0x01, 0x56, 0x82, 0x10, 0xb7, - 0xa3, 0x38, 0x4c, 0x28, 0x26, 0xb1, 0x9d, 0x1c, 0xd9, 0x1e, 0x61, 0x84, 0x53, 0xde, 0x8f, 0xe2, - 0x50, 0x84, 0xb0, 0x29, 0xf1, 0x7e, 0x8e, 0xf7, 0x93, 0xa3, 0xbd, 0x5d, 0x2f, 0xf4, 0x42, 0x05, - 0xda, 0xf2, 0x2b, 0xe3, 0xed, 0x1d, 0x28, 0x9d, 0xe4, 0xc8, 0xe6, 0x3e, 0x8a, 0x09, 0x76, 0xdc, - 0x90, 0xf1, 0xf9, 0x8c, 0xc4, 0x1a, 0x86, 0x39, 0x7c, 0x45, 0x63, 0xa2, 0x63, 0xed, 0x15, 0xeb, - 0xc2, 0x46, 0x11, 0xba, 0x9f, 0xab, 0xe0, 0xbf, 0xd7, 0x59, 0x36, 0xe7, 0x02, 0x09, 0x02, 0x7b, - 0xa0, 0x99, 0xa0, 0x80, 0x13, 0xe1, 0xcc, 0x23, 0x8c, 0x04, 0x71, 0x28, 0x36, 0x8d, 0x8e, 0xd1, - 0xab, 0x8c, 0x1b, 0x59, 0xfc, 0xbd, 0x0a, 0x0f, 0x31, 0xf4, 0xc1, 0xff, 0x79, 0x06, 0x0e, 0x97, - 0x67, 0xb9, 0xb9, 0xd1, 0x29, 0xf7, 0xb6, 0x8f, 0xdb, 0xfd, 0xe5, 0x82, 0xfa, 0xa7, 0x9a, 0xa8, - 0x3c, 0x06, 0xd6, 0xf5, 0x6d, 0xbb, 0xf4, 0xe3, 0xb6, 0xdd, 0x4a, 0xd1, 0x2c, 0x78, 0xd5, 0x5d, - 0x52, 0xe9, 0x8e, 0x1b, 0xee, 0x43, 0x3a, 0x87, 0x1f, 0xc1, 0xde, 0x72, 0x4e, 0x8e, 0x08, 0x1d, - 0x9f, 0x50, 0xcf, 0x17, 0x66, 0x59, 0x99, 0xf6, 0x56, 0x4d, 0x3f, 0x2c, 0xe4, 0x7b, 0x11, 0xbe, - 0x51, 0xfc, 0x41, 0x45, 0xba, 0x8f, 0x5b, 0xc9, 0x5a, 0x14, 0xbe, 0x04, 0xb5, 0x08, 0xc5, 0x68, - 0xc6, 0xcd, 0x4a, 0xc7, 0xe8, 0x6d, 0x1f, 0x9b, 0xab, 0xba, 0x23, 0x85, 0x6b, 0x1d, 0xcd, 0x86, - 0x33, 0x95, 0x23, 0xc5, 0x48, 0x84, 0x71, 0xd1, 0x19, 0x27, 0x9a, 0x4f, 0xa6, 0x24, 0xe5, 0x66, - 0x55, 0xe5, 0xf8, 0x74, 0x6d, 0x8e, 0xd9, 0x99, 0xfc, 0x86, 0x46, 0xf3, 0xc9, 0x5b, 0x92, 0x6a, - 0x71, 0x33, 0x59, 0x03, 0x4b, 0x41, 0xc8, 0xc0, 0x7e, 0x81, 0x71, 0x67, 0x92, 0xfe, 0xb2, 0x44, - 0x18, 0xc7, 0x66, 0xed, 0xaf, 0x7e, 0x83, 0x34, 0x97, 0x3c, 0xc1, 0x38, 0x5e, 0xf1, 0xe3, 0x8b, - 0x38, 0x74, 0xc1, 0xa3, 0x05, 0x07, 0x2e, 0x1b, 0x10, 0xc5, 0x73, 0x46, 0xcc, 0x4d, 0xe5, 0xf5, - 0xe4, 0xf7, 0x4d, 0x97, 0x02, 0xfc, 0x22, 0x1c, 0x49, 0xb6, 0x36, 0xda, 0x75, 0xd7, 0x60, 0xdd, - 0xaf, 0x65, 0xb0, 0xb3, 0x30, 0x29, 0xf0, 0x31, 0xd8, 0x72, 0x7d, 0x44, 0x59, 0x3e, 0x85, 0xf5, - 0xf1, 0xa6, 0xfa, 0x1f, 0x62, 0x78, 0x00, 0x80, 0xeb, 0x23, 0xc6, 0x48, 0x20, 0xc1, 0x0d, 0x05, - 0xd6, 0x75, 0x64, 0x88, 0xe1, 0x3e, 0xa8, 0xbb, 0x01, 0x25, 0x4c, 0x48, 0xb4, 0xac, 0xd0, 0xad, - 0x2c, 0x30, 0xc4, 0xf0, 0x10, 0x34, 0x28, 0xa3, 0x82, 0xa2, 0x20, 0x1f, 0xa2, 0x8a, 0x1a, 0xf1, - 0x1d, 0x1d, 0xd5, 0xb3, 0xf0, 0x0e, 0x34, 0x8b, 0xa2, 0xf5, 0xca, 0x9a, 0x55, 0x35, 0x15, 0x07, - 0x59, 0xb5, 0x0f, 0x8a, 0x7c, 0xb8, 0x44, 0xba, 0xc8, 0x62, 0x3d, 0x34, 0x06, 0x11, 0x68, 0x45, - 0x84, 0x61, 0xca, 0x3c, 0x47, 0xcf, 0xb3, 0xcc, 0xd7, 0x23, 0x5c, 0xf7, 0xeb, 0xb0, 0x50, 0x2d, - 0xda, 0x74, 0x4e, 0xc4, 0xa9, 0xe2, 0x8c, 0x90, 0x3b, 0x25, 0xe2, 0x0c, 0x09, 0x94, 0x5f, 0xa1, - 0x96, 0xca, 0xa6, 0x3c, 0x23, 0x71, 0xf8, 0x0c, 0x40, 0x1e, 0x20, 0xee, 0x3b, 0x38, 0xbc, 0x62, - 0x82, 0xce, 0x88, 0x83, 0xdc, 0xa9, 0x6a, 0x51, 0x7d, 0xdc, 0x54, 0xc8, 0x99, 0x06, 0x4e, 0xdc, - 0x29, 0x7c, 0x01, 0xaa, 0x91, 0x8f, 0x38, 0x31, 0xb7, 0x3a, 0x46, 0xaf, 0xf1, 0xa7, 0xc5, 0x1d, - 0x49, 0xda, 0x38, 0x63, 0x77, 0x2f, 0x41, 0x6b, 0xfd, 0x6e, 0xfd, 0xc3, 0xeb, 0xd1, 0x02, 0x35, - 0x7d, 0xf5, 0x1b, 0x0a, 0xd7, 0x7f, 0x83, 0xe1, 0xf5, 0x9d, 0x65, 0xdc, 0xdc, 0x59, 0xc6, 0xf7, - 0x3b, 0xcb, 0xf8, 0x72, 0x6f, 0x95, 0x6e, 0xee, 0xad, 0xd2, 0xb7, 0x7b, 0xab, 0x74, 0x69, 0x7b, - 0x54, 0xf8, 0xf3, 0x49, 0xdf, 0x0d, 0x67, 0x36, 0x0a, 0x02, 0xca, 0x26, 0x54, 0x70, 0x5b, 0x3d, - 0x70, 0x9f, 0xec, 0xc5, 0x77, 0x4e, 0xa4, 0x11, 0xe1, 0x93, 0x9a, 0x7a, 0xe2, 0x9e, 0xff, 0x0c, - 0x00, 0x00, 0xff, 0xff, 0xd5, 0xdb, 0x0e, 0x1c, 0x80, 0x05, 0x00, 0x00, + // 648 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4f, 0x6f, 0xd3, 0x30, + 0x14, 0x6f, 0xf6, 0xa7, 0xdb, 0x3c, 0x56, 0x2a, 0x6b, 0x2a, 0x61, 0xd3, 0xd2, 0xa9, 0xd2, 0x50, + 0x91, 0x50, 0xa3, 0x0d, 0xc1, 0x81, 0xdb, 0xba, 0x49, 0x50, 0x21, 0xa1, 0xaa, 0x1b, 0x1c, 0x76, + 0x89, 0xdc, 0xd8, 0x4a, 0x4c, 0x53, 0x3b, 0x8a, 0xdd, 0x8c, 0x7c, 0x01, 0x0e, 0x9c, 0xf8, 0x58, + 0x3b, 0xee, 0xc8, 0x69, 0x42, 0xdb, 0x37, 0xe0, 0x13, 0x20, 0x3b, 0x4e, 0xb6, 0xfe, 0x01, 0xc4, + 0x2d, 0x79, 0xbf, 0x9f, 0x7f, 0xbf, 0xf7, 0xfc, 0x9e, 0x1f, 0x70, 0x52, 0x84, 0x84, 0x1b, 0x27, + 0x3c, 0xa5, 0x98, 0x24, 0x6e, 0x7a, 0xe8, 0x06, 0x84, 0x11, 0x41, 0x45, 0x27, 0x4e, 0xb8, 0xe4, + 0xb0, 0xae, 0xf0, 0x4e, 0x81, 0x77, 0xd2, 0xc3, 0x9d, 0xed, 0x80, 0x07, 0x5c, 0x83, 0xae, 0xfa, + 0xca, 0x79, 0x3b, 0x7b, 0x5a, 0x27, 0x3d, 0x74, 0x45, 0x88, 0x12, 0x82, 0x3d, 0x9f, 0x33, 0x31, + 0x19, 0x93, 0xc4, 0xc0, 0xb0, 0x80, 0x2f, 0x69, 0x42, 0x4c, 0xac, 0x39, 0x67, 0x5d, 0xda, 0x68, + 0x42, 0xeb, 0xdb, 0x2a, 0x78, 0xf4, 0x36, 0xcf, 0xe6, 0x4c, 0x22, 0x49, 0x60, 0x1b, 0xd4, 0x53, + 0x14, 0x09, 0x22, 0xbd, 0x49, 0x8c, 0x91, 0x24, 0x1e, 0xc5, 0xb6, 0xb5, 0x6f, 0xb5, 0x57, 0x06, + 0xb5, 0x3c, 0xfe, 0x51, 0x87, 0x7b, 0x18, 0x86, 0xe0, 0x71, 0x91, 0x81, 0x27, 0xd4, 0x59, 0x61, + 0x2f, 0xed, 0x2f, 0xb7, 0x37, 0x8f, 0x9a, 0x9d, 0xd9, 0x82, 0x3a, 0x27, 0x86, 0xa8, 0x3d, 0xba, + 0xce, 0xd5, 0x4d, 0xb3, 0xf2, 0xeb, 0xa6, 0xd9, 0xc8, 0xd0, 0x38, 0x7a, 0xd3, 0x9a, 0x51, 0x69, + 0x0d, 0x6a, 0xfe, 0x43, 0xba, 0x80, 0x9f, 0xc1, 0xce, 0x6c, 0x4e, 0x9e, 0xe4, 0x5e, 0x48, 0x68, + 0x10, 0x4a, 0x7b, 0x59, 0x9b, 0xb6, 0xe7, 0x4d, 0x3f, 0x4d, 0xe5, 0x7b, 0xce, 0xdf, 0x69, 0x7e, + 0x77, 0x45, 0xb9, 0x0f, 0x1a, 0xe9, 0x42, 0x14, 0xbe, 0x06, 0xd5, 0x18, 0x25, 0x68, 0x2c, 0xec, + 0x95, 0x7d, 0xab, 0xbd, 0x79, 0x64, 0xcf, 0xeb, 0xf6, 0x35, 0x6e, 0x74, 0x0c, 0x1b, 0x8e, 0x75, + 0x8e, 0x14, 0x23, 0xc9, 0x93, 0xb2, 0x33, 0x5e, 0x3c, 0x19, 0x8e, 0x48, 0x26, 0xec, 0x55, 0x9d, + 0xe3, 0xf3, 0x85, 0x39, 0xe6, 0x67, 0x8a, 0x1b, 0xea, 0x4f, 0x86, 0xef, 0x49, 0x66, 0xc4, 0xed, + 0x74, 0x01, 0xac, 0x04, 0x21, 0x03, 0xbb, 0x25, 0x26, 0xbc, 0x61, 0x76, 0x6f, 0x89, 0x30, 0x4e, + 0xec, 0xea, 0x3f, 0xfd, 0xba, 0x59, 0x21, 0x79, 0x8c, 0x71, 0x32, 0xe7, 0x27, 0xa6, 0x71, 0xe8, + 0x83, 0x27, 0x53, 0x0e, 0x42, 0x35, 0x20, 0x4e, 0x26, 0x8c, 0xd8, 0x6b, 0xda, 0xeb, 0xd9, 0x9f, + 0x9b, 0xae, 0x04, 0xc4, 0x39, 0xef, 0x2b, 0xb6, 0x31, 0xda, 0xf6, 0x17, 0x60, 0xad, 0xaf, 0xcb, + 0x60, 0x6b, 0x6a, 0x52, 0xe0, 0x53, 0xb0, 0xee, 0x87, 0x88, 0xb2, 0x62, 0x0a, 0x37, 0x06, 0x6b, + 0xfa, 0xbf, 0x87, 0xe1, 0x2e, 0xd8, 0xf0, 0x23, 0x4a, 0x98, 0x54, 0xd8, 0x92, 0xc6, 0xd6, 0xf3, + 0x40, 0x0f, 0xc3, 0x03, 0x50, 0xa3, 0x8c, 0x4a, 0x8a, 0xa2, 0xfb, 0x29, 0x51, 0x33, 0xbc, 0x65, + 0xa2, 0xa6, 0xd9, 0x1f, 0x40, 0xbd, 0xac, 0xca, 0xbc, 0x49, 0xd3, 0xf6, 0xbd, 0xbc, 0x9c, 0x07, + 0x55, 0x3c, 0x7c, 0x25, 0xa6, 0x8a, 0x72, 0xfe, 0x0d, 0x06, 0x11, 0x68, 0xc4, 0x84, 0x61, 0xca, + 0x02, 0xcf, 0x0c, 0xac, 0x1f, 0x22, 0x16, 0x90, 0x62, 0x00, 0x0e, 0x4a, 0xd5, 0xb2, 0x0f, 0x67, + 0x44, 0x9e, 0x68, 0x4e, 0x1f, 0xf9, 0x23, 0x22, 0x4f, 0x91, 0x44, 0xc5, 0x1d, 0x19, 0xa9, 0x7c, + 0x8c, 0x73, 0x92, 0x80, 0x2f, 0x00, 0x14, 0x11, 0x12, 0xa1, 0x87, 0xf9, 0x25, 0x93, 0x74, 0x4c, + 0x3c, 0xe4, 0x8f, 0x74, 0xbf, 0x37, 0x06, 0x75, 0x8d, 0x9c, 0x1a, 0xe0, 0xd8, 0x1f, 0xc1, 0x57, + 0x60, 0x35, 0x0e, 0x91, 0x50, 0x4d, 0xb2, 0xda, 0xb5, 0xbf, 0xbd, 0xcc, 0xbe, 0xa2, 0x0d, 0x72, + 0x76, 0xeb, 0x02, 0x34, 0x16, 0x3f, 0x9e, 0xff, 0x58, 0x0f, 0x0d, 0x50, 0x35, 0x57, 0xbf, 0xa4, + 0x71, 0xf3, 0xd7, 0xed, 0x5d, 0xdd, 0x3a, 0xd6, 0xf5, 0xad, 0x63, 0xfd, 0xbc, 0x75, 0xac, 0xef, + 0x77, 0x4e, 0xe5, 0xfa, 0xce, 0xa9, 0xfc, 0xb8, 0x73, 0x2a, 0x17, 0x6e, 0x40, 0x65, 0x38, 0x19, + 0x76, 0x7c, 0x3e, 0x76, 0x51, 0x14, 0x51, 0x36, 0xa4, 0x52, 0xb8, 0x7a, 0x83, 0x7d, 0x71, 0xa7, + 0x17, 0x99, 0xcc, 0x62, 0x22, 0x86, 0x55, 0xbd, 0xc3, 0x5e, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, + 0xd7, 0x85, 0xc9, 0x36, 0x61, 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -473,7 +463,7 @@ func (m *ConsumerState) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.Phase != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.Phase)) i-- - dAtA[i] = 0x40 + dAtA[i] = 0x38 } if len(m.SlashDowntimeAck) > 0 { for iNdEx := len(m.SlashDowntimeAck) - 1; iNdEx >= 0; iNdEx-- { @@ -481,7 +471,7 @@ func (m *ConsumerState) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.SlashDowntimeAck[iNdEx]) i = encodeVarintGenesis(dAtA, i, uint64(len(m.SlashDowntimeAck[iNdEx]))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 } } if len(m.PendingValsetChanges) > 0 { @@ -495,7 +485,7 @@ func (m *ConsumerState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } } { @@ -507,24 +497,17 @@ func (m *ConsumerState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 if m.InitialHeight != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.InitialHeight)) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x18 } if len(m.ClientId) > 0 { i -= len(m.ClientId) copy(dAtA[i:], m.ClientId) i = encodeVarintGenesis(dAtA, i, uint64(len(m.ClientId))) i-- - dAtA[i] = 0x1a - } - if len(m.ChannelId) > 0 { - i -= len(m.ChannelId) - copy(dAtA[i:], m.ChannelId) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.ChannelId))) - i-- dAtA[i] = 0x12 } if len(m.ChainId) > 0 { @@ -635,10 +618,6 @@ func (m *ConsumerState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) - } l = len(m.ClientId) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) @@ -1021,38 +1000,6 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) } @@ -1084,7 +1031,7 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { } m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType) } @@ -1103,7 +1050,7 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { break } } - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsumerGenesis", wireType) } @@ -1136,7 +1083,7 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field PendingValsetChanges", wireType) } @@ -1170,7 +1117,7 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SlashDowntimeAck", wireType) } @@ -1202,7 +1149,7 @@ func (m *ConsumerState) Unmarshal(dAtA []byte) error { } m.SlashDowntimeAck = append(m.SlashDowntimeAck, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 8: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Phase", wireType) } diff --git a/x/vaas/provider/types/genesis_test.go b/x/vaas/provider/types/genesis_test.go index cd06f97..a4ad515 100644 --- a/x/vaas/provider/types/genesis_test.go +++ b/x/vaas/provider/types/genesis_test.go @@ -16,7 +16,6 @@ import ( vaastypes "github.com/allinbits/vaas/x/vaas/types" ) -// Tests validation of consumer states and params within a provider genesis state func TestValidateGenesisState(t *testing.T) { testCases := []struct { name string @@ -28,7 +27,7 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, + []types.ConsumerState{{ChainId: "chainid-1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, types.DefaultParams(), nil, nil, @@ -42,10 +41,10 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{ - {ChainId: "chainid-1", ChannelId: "channelid1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}, - {ChainId: "chainid-2", ChannelId: "channelid2", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-2", true)}, - {ChainId: "chainid-3", ChannelId: "channelid3", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-3", false)}, - {ChainId: "chainid-4", ChannelId: "channelid4", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-4", true)}, + {ChainId: "chainid-1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}, + {ChainId: "chainid-2", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-2", true)}, + {ChainId: "chainid-3", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-3", false)}, + {ChainId: "chainid-4", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-4", true)}, }, types.DefaultParams(), nil, @@ -59,8 +58,8 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, - types.NewParams(types.DefaultTemplateClient(), + []types.ConsumerState{{ChainId: "chainid-1", ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid-1", false)}}, + types.NewParams( types.DefaultTrustingPeriodFraction, time.Hour, 600, 180), nil, nil, @@ -99,9 +98,9 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(types.DefaultTemplateClient(), - "0.0", // 0 trusting period fraction here + []types.ConsumerState{{ChainId: "chainid-1", ClientId: "client-id"}}, + types.NewParams( + "0.0", vaastypes.DefaultVAASTimeoutPeriod, 600, 180), nil, nil, @@ -114,10 +113,10 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - types.NewParams(types.DefaultTemplateClient(), + []types.ConsumerState{{ChainId: "chainid-1", ClientId: "client-id"}}, + types.NewParams( types.DefaultTrustingPeriodFraction, - 0, // 0 ccv timeout here + 0, 600, 180), nil, nil, @@ -126,11 +125,11 @@ func TestValidateGenesisState(t *testing.T) { false, }, { - "invalid consumer state channel id", + "empty consumer state chain id", types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid", ChannelId: "invalidChannel{}", ClientId: "client-id"}}, + []types.ConsumerState{{ChainId: "", ClientId: "client-id"}}, types.DefaultParams(), nil, nil, @@ -143,7 +142,7 @@ func TestValidateGenesisState(t *testing.T) { types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid", ChannelId: "channel-0", ClientId: ""}}, + []types.ConsumerState{{ChainId: "chainid", ClientId: ""}}, types.DefaultParams(), nil, nil, @@ -152,17 +151,17 @@ func TestValidateGenesisState(t *testing.T) { false, }, { - "invalid consumer state client id 2", + "valid consumer state with client id", types.NewGenesisState( types.DefaultValsetUpdateID, nil, - []types.ConsumerState{{ChainId: "chainid", ChannelId: "channel-0", ClientId: "abc", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false)}}, + []types.ConsumerState{{ChainId: "chainid", ClientId: "abc", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false)}}, types.DefaultParams(), nil, nil, nil, ), - false, + true, }, { "invalid consumer state pending VSC packets", @@ -170,7 +169,8 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultValsetUpdateID, nil, []types.ConsumerState{{ - ChainId: "chainid", ChannelId: "channel-0", ClientId: "client-id", + ChainId: "chainid", + ClientId: "client-id", ConsumerGenesis: getInitialConsumerGenesis(t, "chainid", false), PendingValsetChanges: []vaastypes.ValidatorSetChangePacketData{{}}, }}, @@ -198,11 +198,9 @@ func TestValidateGenesisState(t *testing.T) { func getInitialConsumerGenesis(t *testing.T, chainID string, preVAAS bool) vaastypes.ConsumerGenesisState { t.Helper() - // generate validator public key cId := crypto.NewCryptoIdentityFromIntSeed(239668) pubKey := cId.TMCryptoPubKey() - // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) valHash := valSet.Hash() @@ -210,10 +208,9 @@ func getInitialConsumerGenesis(t *testing.T, chainID string, preVAAS bool) vaast var clientState *ibctmtypes.ClientState = nil var consensusState *ibctmtypes.ConsensusState = nil - connectionId := "" if preVAAS { - connectionId = "connection-1" + // no client state needed for pre-VAAS } else { clientState = ibctmtypes.NewClientState( chainID, @@ -230,5 +227,5 @@ func getInitialConsumerGenesis(t *testing.T, chainID string, preVAAS bool) vaast params := vaastypes.DefaultParams() params.Enabled = true - return *vaastypes.NewInitialConsumerGenesisState(clientState, consensusState, valUpdates, preVAAS, connectionId, params) + return *vaastypes.NewInitialConsumerGenesisState(clientState, consensusState, valUpdates, preVAAS, params) } diff --git a/x/vaas/provider/types/keys.go b/x/vaas/provider/types/keys.go index a5972eb..4226d03 100644 --- a/x/vaas/provider/types/keys.go +++ b/x/vaas/provider/types/keys.go @@ -25,14 +25,10 @@ const ( ParametersKeyName = "ParametersKey" - PortKeyName = "PortKey" - ValidatorSetUpdateIdKeyName = "ValidatorSetUpdateIdKey" - ConsumerIdToChannelIdKeyName = "ConsumerIdToChannelIdKey" - - ChannelIdToConsumerIdKeyName = "ChannelToConsumerIdKey" - + // ConsumerIdToClientIdKeyName stores the mapping from consumer ID to client ID. + // This is the primary lookup mechanism for IBC v2 client-based communication. ConsumerIdToClientIdKeyName = "ConsumerIdToClientIdKey" ValsetUpdateBlockHeightKeyName = "ValsetUpdateBlockHeightKey" @@ -75,6 +71,8 @@ const ( RemovalTimeToConsumerIdsKeyName = "RemovalTimeToConsumerIdsKeyName" + // ClientIdToConsumerIdKeyName stores the reverse mapping from client ID to consumer ID. + // This is the reverse lookup mechanism for IBC v2 client-based communication. ClientIdToConsumerIdKeyName = "ClientIdToConsumerIdKey" PrioritylistKeyName = "PrioritylistKey" @@ -88,10 +86,7 @@ const ( // Collection key prefixes for use with cosmossdk.io/collections var ( - PortPrefix = collections.NewPrefix(0) ValidatorSetUpdateIdPrefix = collections.NewPrefix(1) - ConsumerIdToChannelIdPrefix = collections.NewPrefix(2) - ChannelIdToConsumerIdPrefix = collections.NewPrefix(3) ConsumerIdToClientIdPrefix = collections.NewPrefix(4) ValsetUpdateBlockHeightPrefix = collections.NewPrefix(5) ConsumerGenesisPrefix = collections.NewPrefix(6) diff --git a/x/vaas/provider/types/msg.go b/x/vaas/provider/types/msg.go index 8461b15..08a6f55 100644 --- a/x/vaas/provider/types/msg.go +++ b/x/vaas/provider/types/msg.go @@ -326,16 +326,16 @@ func TruncateString(str string, maxLength int) string { return "" } - truncated := "" + var truncated strings.Builder count := 0 for _, char := range str { - truncated += string(char) + truncated.WriteString(string(char)) count++ if count >= maxLength { break } } - return truncated + return truncated.String() } // ValidateConsumerMetadata validates that all the provided metadata are in the expected range @@ -381,10 +381,6 @@ func ValidateInitializationParameters(initializationParameters ConsumerInitializ return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "UnbondingPeriod: %s", err.Error()) } - if err := vaastypes.ValidateConnectionIdentifier(initializationParameters.ConnectionId); err != nil { - return errorsmod.Wrapf(ErrInvalidConsumerInitializationParameters, "ConnectionId: %s", err.Error()) - } - return nil } diff --git a/x/vaas/provider/types/msg_test.go b/x/vaas/provider/types/msg_test.go index e15412c..e1f5762 100644 --- a/x/vaas/provider/types/msg_test.go +++ b/x/vaas/provider/types/msg_test.go @@ -163,9 +163,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: now, UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 10000, - ConnectionId: "", }, valid: true, }, @@ -177,9 +176,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: now, UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 10000, - ConnectionId: "", }, valid: false, }, @@ -191,9 +189,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: now, UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 10000, - ConnectionId: "", }, valid: false, }, @@ -205,9 +202,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: time.Time{}, UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 10000, - ConnectionId: "", }, valid: true, }, @@ -219,9 +215,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: now, UnbondingPeriod: 0, - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 10000, - ConnectionId: "", }, valid: false, }, @@ -233,23 +228,8 @@ func TestValidateInitializationParameters(t *testing.T) { BinaryHash: []byte{0x01}, SpawnTime: now, UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), + VaasTimeoutPeriod: time.Duration(100000000000), HistoricalEntries: 0, - ConnectionId: "", - }, - valid: false, - }, - { - name: "invalid - ConnectionId too long", - params: types.ConsumerInitializationParameters{ - InitialHeight: clienttypes.NewHeight(3, 4), - GenesisHash: []byte{0x01}, - BinaryHash: []byte{0x01}, - SpawnTime: now, - UnbondingPeriod: time.Duration(100000000000), - VaasTimeoutPeriod: time.Duration(100000000000), - HistoricalEntries: 10000, - ConnectionId: coolStr, }, valid: false, }, @@ -265,7 +245,6 @@ func TestValidateInitializationParameters(t *testing.T) { } } - func TestValidateByteSlice(t *testing.T) { testCases := []struct { name string diff --git a/x/vaas/provider/types/params.go b/x/vaas/provider/types/params.go index 124c080..9701fdc 100644 --- a/x/vaas/provider/types/params.go +++ b/x/vaas/provider/types/params.go @@ -5,10 +5,6 @@ import ( "time" vaastypes "github.com/allinbits/vaas/x/vaas/types" - - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" ) const ( @@ -32,14 +28,12 @@ const ( // NewParams creates new provider parameters with provided arguments func NewParams( - cs *ibctmtypes.ClientState, trustingPeriodFraction string, vaasTimeoutPeriod time.Duration, blocksPerEpoch int64, maxProviderConsensusValidators int64, ) Params { return Params{ - TemplateClient: cs, TrustingPeriodFraction: trustingPeriodFraction, VaasTimeoutPeriod: vaasTimeoutPeriod, BlocksPerEpoch: blocksPerEpoch, @@ -47,26 +41,8 @@ func NewParams( } } -// DefaultTemplateClient is the default template client -func DefaultTemplateClient() *ibctmtypes.ClientState { - return ibctmtypes.NewClientState( - "", // chainID - ibctmtypes.DefaultTrustLevel, - 0, // trusting period - 0, // unbonding period - DefaultMaxClockDrift, - clienttypes.Height{}, // latest(initial) height - commitmenttypes.GetSDKSpecs(), - []string{"upgrade", "upgradedIBCState"}, - ) -} - -// DefaultParams is the default params for the provider module func DefaultParams() Params { - // create default client state with chainID, trusting period, unbonding period, and initial height zeroed out. - // these fields will be populated during proposal handler. return NewParams( - DefaultTemplateClient(), DefaultTrustingPeriodFraction, vaastypes.DefaultVAASTimeoutPeriod, DefaultBlocksPerEpoch, @@ -76,12 +52,6 @@ func DefaultParams() Params { // Validate all VAAS-provider module parameters func (p Params) Validate() error { - if p.TemplateClient == nil { - return fmt.Errorf("template client is nil") - } - if err := ValidateTemplateClient(*p.TemplateClient); err != nil { - return err - } if err := vaastypes.ValidateStringFractionNonZero(p.TrustingPeriodFraction); err != nil { return fmt.Errorf("trusting period fraction is invalid: %s", err) } @@ -96,30 +66,3 @@ func (p Params) Validate() error { } return nil } - -func ValidateTemplateClient(i interface{}) error { - cs, ok := i.(ibctmtypes.ClientState) - if !ok { - return fmt.Errorf("invalid parameter type: %T, expected: %T", i, ibctmtypes.ClientState{}) - } - - // copy clientstate to prevent changing original pointer - copiedClient := cs - - // populate zeroed fields with valid fields - copiedClient.ChainId = "chainid" - - trustPeriod, err := vaastypes.CalculateTrustPeriod(vaastypes.DefaultConsumerUnbondingPeriod, DefaultTrustingPeriodFraction) - if err != nil { - return fmt.Errorf("invalid TrustPeriodFraction: %T", err) - } - copiedClient.TrustingPeriod = trustPeriod - - copiedClient.UnbondingPeriod = vaastypes.DefaultConsumerUnbondingPeriod - copiedClient.LatestHeight = clienttypes.NewHeight(0, 1) - - if err := copiedClient.Validate(); err != nil { - return err - } - return nil -} diff --git a/x/vaas/provider/types/params_test.go b/x/vaas/provider/types/params_test.go index 606efda..2b43238 100644 --- a/x/vaas/provider/types/params_test.go +++ b/x/vaas/provider/types/params_test.go @@ -4,9 +4,6 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v10/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" "github.com/allinbits/vaas/x/vaas/provider/types" @@ -20,21 +17,10 @@ func TestValidateParams(t *testing.T) { }{ {"default params", types.DefaultParams(), true}, {"custom valid params", types.NewParams( - ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), "0.33", time.Hour, 1000, 180), true}, - {"custom invalid params", types.NewParams( - ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, 1000, 180), false}, - {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, 1000, 180), false}, - {"nil client", types.NewParams(nil, "0.33", time.Hour, 1000, 180), false}, - {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + {"0 trusting period fraction", types.NewParams( "0.00", time.Hour, 1000, 180), false}, - {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + {"0 ccv timeout period", types.NewParams( "0.33", 0, 1000, 180), false}, } diff --git a/x/vaas/provider/types/provider.pb.go b/x/vaas/provider/types/provider.pb.go index 66cfaaf..05ebe28 100644 --- a/x/vaas/provider/types/provider.pb.go +++ b/x/vaas/provider/types/provider.pb.go @@ -15,7 +15,7 @@ import ( proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" types1 "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - _07_tendermint "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" + _ "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" _ "google.golang.org/protobuf/types/known/durationpb" _ "google.golang.org/protobuf/types/known/timestamppb" io "io" @@ -87,17 +87,16 @@ func (ConsumerPhase) EnumDescriptor() ([]byte, []int) { // Params defines the parameters for VAAS Provider module type Params struct { - TemplateClient *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=template_client,json=templateClient,proto3" json:"template_client,omitempty"` // TrustingPeriodFraction is used to compute the consumer and provider IBC // client's TrustingPeriod from the chain defined UnbondingPeriod - TrustingPeriodFraction string `protobuf:"bytes,2,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"` + TrustingPeriodFraction string `protobuf:"bytes,1,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"` // Sent IBC packets will timeout after this duration - VaasTimeoutPeriod time.Duration `protobuf:"bytes,3,opt,name=vaas_timeout_period,json=vaasTimeoutPeriod,proto3,stdduration" json:"vaas_timeout_period"` + VaasTimeoutPeriod time.Duration `protobuf:"bytes,2,opt,name=vaas_timeout_period,json=vaasTimeoutPeriod,proto3,stdduration" json:"vaas_timeout_period"` // The number of blocks that comprise an epoch. - BlocksPerEpoch int64 `protobuf:"varint,4,opt,name=blocks_per_epoch,json=blocksPerEpoch,proto3" json:"blocks_per_epoch,omitempty"` + BlocksPerEpoch int64 `protobuf:"varint,3,opt,name=blocks_per_epoch,json=blocksPerEpoch,proto3" json:"blocks_per_epoch,omitempty"` // The maximal number of validators that will be passed // to the consensus engine on the provider. - MaxProviderConsensusValidators int64 `protobuf:"varint,5,opt,name=max_provider_consensus_validators,json=maxProviderConsensusValidators,proto3" json:"max_provider_consensus_validators,omitempty"` + MaxProviderConsensusValidators int64 `protobuf:"varint,4,opt,name=max_provider_consensus_validators,json=maxProviderConsensusValidators,proto3" json:"max_provider_consensus_validators,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -133,13 +132,6 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo -func (m *Params) GetTemplateClient() *_07_tendermint.ClientState { - if m != nil { - return m.TemplateClient - } - return nil -} - func (m *Params) GetTrustingPeriodFraction() string { if m != nil { return m.TrustingPeriodFraction @@ -667,7 +659,7 @@ type ConsumerInitializationParameters struct { // chain initialization. It is used for off-chain confirmation of binary // validity by validators and other parties. BinaryHash []byte `protobuf:"bytes,3,opt,name=binary_hash,json=binaryHash,proto3" json:"binary_hash,omitempty"` - // spawn time is the time on the provider chain at which the consumer chain + // spawn_time is the time on the provider chain at which the consumer chain // genesis is finalized and all validators will be responsible for starting // their consumer chain validator node. SpawnTime time.Time `protobuf:"bytes,4,opt,name=spawn_time,json=spawnTime,proto3,stdtime" json:"spawn_time"` @@ -680,13 +672,6 @@ type ConsumerInitializationParameters struct { // This param is a part of the cosmos sdk staking module. In the case of // a VAAS enabled consumer chain, the VAAS module acts as the staking module. HistoricalEntries int64 `protobuf:"varint,7,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` - // The ID of the connection end on the provider chain on top of which the VAAS - // channel will be established. If connection_id == "", a new client of the - // consumer chain and a new connection on top of this client are created. - // Note that a standalone chain can transition to a consumer chain while - // maintaining existing IBC channels to other chains by providing a valid - // connection_id. - ConnectionId string `protobuf:"bytes,8,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` } func (m *ConsumerInitializationParameters) Reset() { *m = ConsumerInitializationParameters{} } @@ -771,13 +756,6 @@ func (m *ConsumerInitializationParameters) GetHistoricalEntries() int64 { return 0 } -func (m *ConsumerInitializationParameters) GetConnectionId() string { - if m != nil { - return m.ConnectionId - } - return "" -} - // ConsumerIds contains consumer ids of chains // Used so we can easily (de)serialize slices of strings type ConsumerIds struct { @@ -952,93 +930,90 @@ func init() { func init() { proto.RegisterFile("vaas/provider/v1/provider.proto", fileDescriptor_6404dd5d21545279) } var fileDescriptor_6404dd5d21545279 = []byte{ - // 1376 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcf, 0x6f, 0xdb, 0xb6, - 0x1e, 0x8f, 0xe2, 0xb4, 0x75, 0xe8, 0x24, 0x75, 0xd9, 0xa0, 0x75, 0xd2, 0xd6, 0x49, 0xfd, 0xd0, - 0x87, 0xa0, 0x7d, 0x95, 0xe0, 0x3e, 0xe0, 0xe1, 0x61, 0x3b, 0x14, 0x89, 0xad, 0x36, 0x5e, 0xd2, + // 1317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0xdb, 0x36, + 0x1b, 0x8f, 0xe2, 0xb4, 0x75, 0x68, 0x27, 0xaf, 0xcb, 0x06, 0xad, 0xe3, 0xb6, 0x76, 0xea, 0x17, + 0x7d, 0x11, 0xf4, 0x5d, 0x25, 0xb8, 0x03, 0x86, 0x61, 0x3b, 0x14, 0x89, 0xad, 0x36, 0x5e, 0xd2, 0xd4, 0x90, 0xdd, 0x1d, 0x8a, 0x0d, 0x02, 0x25, 0xb1, 0x36, 0x1b, 0x89, 0x14, 0x44, 0xda, 0xa9, - 0x77, 0xd8, 0x79, 0xc7, 0xee, 0x36, 0xec, 0x36, 0xec, 0xb2, 0xe3, 0x0e, 0xc3, 0xb0, 0x3f, 0xa1, - 0xbb, 0x15, 0x3b, 0x0d, 0xc3, 0xd0, 0x0d, 0xe9, 0x61, 0xa7, 0xfd, 0x0f, 0x03, 0x29, 0x4a, 0x56, - 0x93, 0xb4, 0xc8, 0xb0, 0x8b, 0x40, 0x7e, 0xbe, 0xdf, 0x0f, 0xf5, 0xe5, 0xf7, 0x27, 0xc1, 0xda, - 0x18, 0x21, 0x6e, 0xc5, 0x09, 0x1b, 0x93, 0x00, 0x27, 0xd6, 0xb8, 0x99, 0xaf, 0xcd, 0x38, 0x61, - 0x82, 0xc1, 0xaa, 0x54, 0x30, 0x73, 0x70, 0xdc, 0x5c, 0xbd, 0x80, 0x22, 0x42, 0x99, 0xa5, 0xbe, - 0xa9, 0xd2, 0xea, 0xbf, 0x7d, 0xc6, 0x23, 0xc6, 0x2d, 0x2c, 0x95, 0xa8, 0x8f, 0xad, 0x71, 0xd3, - 0xc3, 0x02, 0x35, 0x73, 0x40, 0xeb, 0xad, 0xa4, 0x7a, 0xae, 0xda, 0x59, 0xe9, 0x46, 0x8b, 0x96, - 0x07, 0x6c, 0xc0, 0x52, 0x5c, 0xae, 0x34, 0x5a, 0x1f, 0x30, 0x36, 0x08, 0xb1, 0xa5, 0x76, 0xde, - 0xe8, 0x89, 0x15, 0x8c, 0x12, 0x24, 0x08, 0xa3, 0x5a, 0xbe, 0x76, 0x54, 0x2e, 0x48, 0x84, 0xb9, - 0x40, 0x51, 0x9c, 0x29, 0x10, 0xcf, 0xb7, 0x7c, 0x96, 0x60, 0xcb, 0x0f, 0x09, 0xa6, 0x42, 0xde, - 0x30, 0x5d, 0x69, 0x05, 0x4b, 0x2a, 0x84, 0x64, 0x30, 0x14, 0x29, 0xcc, 0x2d, 0x81, 0x69, 0x80, - 0x93, 0x88, 0xa4, 0xca, 0xd3, 0x9d, 0x26, 0x40, 0xe5, 0xb1, 0x71, 0xd3, 0x3a, 0x20, 0x49, 0x76, - 0xaf, 0xab, 0x05, 0x8e, 0x9f, 0x4c, 0x62, 0xc1, 0xac, 0x7d, 0x3c, 0xd1, 0x57, 0x6b, 0x1c, 0xce, - 0x82, 0xb3, 0x5d, 0x94, 0xa0, 0x88, 0xc3, 0x3e, 0x38, 0x2f, 0x70, 0x14, 0x87, 0x48, 0x60, 0x37, - 0xfd, 0x5f, 0xcd, 0x58, 0x37, 0x36, 0x2a, 0x77, 0x6e, 0x99, 0xc4, 0xf3, 0xcd, 0xa2, 0x1d, 0x66, - 0xe1, 0xcf, 0xe3, 0xa6, 0xd9, 0x52, 0x68, 0x4f, 0x20, 0x81, 0x9d, 0xa5, 0xec, 0x8c, 0x14, 0x84, - 0xff, 0x07, 0x35, 0x91, 0x8c, 0xb8, 0x20, 0x74, 0xe0, 0xc6, 0x38, 0x21, 0x2c, 0x70, 0x9f, 0x24, - 0xc8, 0x97, 0x7e, 0xaa, 0xcd, 0xae, 0x1b, 0x1b, 0xf3, 0xce, 0xa5, 0x4c, 0xde, 0x55, 0xe2, 0x7b, - 0x5a, 0x0a, 0x7b, 0xe0, 0xa2, 0xbc, 0x8e, 0x2b, 0xdd, 0xc6, 0x46, 0x42, 0xb3, 0x6b, 0x25, 0x65, - 0xd3, 0x8a, 0x99, 0x7a, 0xd7, 0xcc, 0xbc, 0x6b, 0xb6, 0xb5, 0xf7, 0xb7, 0xca, 0x2f, 0x5e, 0xad, - 0xcd, 0x7c, 0xf1, 0xdb, 0x9a, 0xe1, 0x5c, 0x90, 0xfc, 0x7e, 0x4a, 0x4f, 0x0f, 0x87, 0x1b, 0xa0, - 0xea, 0x85, 0xcc, 0xdf, 0xe7, 0xf2, 0x38, 0x17, 0xc7, 0xcc, 0x1f, 0xd6, 0xe6, 0xd6, 0x8d, 0x8d, - 0x92, 0xb3, 0x94, 0xe2, 0x5d, 0x9c, 0xd8, 0x12, 0x85, 0x1d, 0x70, 0x3d, 0x42, 0xcf, 0xdc, 0x2c, - 0xbb, 0x5c, 0x9f, 0x51, 0x8e, 0x29, 0x1f, 0x71, 0x77, 0x8c, 0x42, 0x12, 0x20, 0xc1, 0x12, 0x5e, - 0x3b, 0xa3, 0xa8, 0xf5, 0x08, 0x3d, 0xeb, 0x6a, 0xbd, 0x56, 0xa6, 0xf6, 0x61, 0xae, 0xd5, 0xb8, - 0x05, 0x2a, 0x9b, 0x41, 0x90, 0x60, 0xce, 0x77, 0x09, 0x17, 0xf0, 0x2a, 0x98, 0x47, 0xe9, 0x16, - 0xf3, 0x9a, 0xb1, 0x5e, 0xda, 0x58, 0x70, 0xa6, 0x40, 0xe3, 0x23, 0xb0, 0x92, 0x53, 0x7b, 0x58, - 0xb4, 0x86, 0x88, 0x0e, 0x70, 0x17, 0xf9, 0xfb, 0x58, 0x70, 0x78, 0x17, 0xcc, 0x85, 0x84, 0x0b, - 0xc5, 0xaa, 0xdc, 0xb9, 0x61, 0xaa, 0x02, 0x18, 0x37, 0xcd, 0xb7, 0x31, 0xda, 0x48, 0xa0, 0xad, - 0x39, 0xe9, 0x10, 0x47, 0x11, 0x1b, 0x9f, 0x1b, 0xa0, 0xb6, 0x83, 0x27, 0x9b, 0x9c, 0x93, 0x01, - 0x8d, 0x30, 0x15, 0x0e, 0x8e, 0x43, 0xe4, 0x63, 0xb9, 0x84, 0xff, 0x02, 0x8b, 0xf9, 0x75, 0xa5, - 0x41, 0x2a, 0xfe, 0x0b, 0xce, 0x42, 0x06, 0xca, 0x4b, 0xc0, 0xf7, 0x00, 0x88, 0x13, 0x3c, 0x76, - 0x7d, 0x77, 0x1f, 0x4f, 0x54, 0x08, 0x2b, 0x77, 0xae, 0x16, 0x13, 0x22, 0x4d, 0x32, 0xb3, 0x3b, - 0xf2, 0x42, 0xe2, 0xef, 0xe0, 0x89, 0x53, 0x96, 0xfa, 0xad, 0x1d, 0x3c, 0x81, 0xcb, 0xe0, 0x4c, - 0xcc, 0x0e, 0x70, 0xa2, 0x82, 0x58, 0x72, 0xd2, 0x4d, 0xe3, 0x4b, 0x03, 0x5c, 0xce, 0x2f, 0x20, - 0xfd, 0x37, 0x8a, 0x70, 0xd2, 0x1d, 0x79, 0x92, 0xb1, 0x02, 0xca, 0xfe, 0x10, 0x11, 0xea, 0x92, - 0x40, 0x59, 0x33, 0xef, 0x9c, 0x53, 0xfb, 0x4e, 0x70, 0xdc, 0xda, 0xd9, 0x13, 0xac, 0xbd, 0x0b, - 0x16, 0x7c, 0x7d, 0xa2, 0xb2, 0xb7, 0x74, 0x0a, 0x7b, 0x2b, 0x19, 0x63, 0x07, 0x4f, 0x1a, 0x9f, - 0x16, 0x6c, 0xdb, 0x9a, 0x64, 0xd6, 0xa9, 0xb3, 0xdf, 0x6d, 0x5b, 0xfe, 0xdb, 0xa2, 0x6d, 0x7e, - 0x91, 0x7f, 0xec, 0x02, 0xa5, 0xe3, 0x17, 0x68, 0xfc, 0x60, 0x80, 0xe5, 0xe2, 0x5f, 0x79, 0x9f, - 0x75, 0x93, 0x11, 0xc5, 0xef, 0xfa, 0xfb, 0x5d, 0x50, 0x8e, 0xa5, 0x8e, 0x2b, 0xb8, 0x0e, 0xd0, - 0xea, 0xb1, 0x72, 0xe9, 0x67, 0xcd, 0x28, 0xad, 0x97, 0xe7, 0xb2, 0x5e, 0xce, 0x29, 0x56, 0x9f, - 0xc3, 0x36, 0x58, 0x7a, 0xc3, 0x7c, 0xae, 0xfd, 0x76, 0xcd, 0x3c, 0xda, 0x71, 0xcd, 0x42, 0x62, - 0x3b, 0x8b, 0xc5, 0xeb, 0xf1, 0xc6, 0xf7, 0x06, 0x80, 0xc7, 0xcb, 0x01, 0xfe, 0x07, 0xc0, 0x37, - 0x8a, 0xaa, 0x98, 0x6a, 0xd5, 0xb8, 0x50, 0x46, 0xca, 0x49, 0x79, 0xca, 0xcc, 0x16, 0x52, 0x06, - 0xbe, 0x0f, 0x40, 0xac, 0xe2, 0x75, 0xea, 0xa0, 0xce, 0xc7, 0xd9, 0x12, 0xae, 0x81, 0xca, 0x53, - 0x46, 0xa8, 0x3b, 0xc4, 0xb2, 0xa5, 0xe9, 0xf2, 0x07, 0x12, 0xda, 0x56, 0x48, 0x23, 0x00, 0xd5, - 0xcc, 0xe5, 0x0f, 0xb0, 0x40, 0x01, 0x12, 0x08, 0x42, 0x30, 0x47, 0x51, 0x84, 0xb5, 0xab, 0xd5, - 0x1a, 0xae, 0x83, 0x4a, 0x80, 0xb9, 0x9f, 0x90, 0xb8, 0xd0, 0xce, 0x8a, 0x10, 0x5c, 0x05, 0xe5, - 0x48, 0x9f, 0xa0, 0xac, 0x9c, 0x77, 0xf2, 0x7d, 0xe3, 0xcf, 0x12, 0x58, 0xcf, 0x7e, 0xd3, 0xa1, - 0x44, 0x10, 0x14, 0x92, 0x4f, 0x54, 0x0b, 0x53, 0x0d, 0x19, 0x0b, 0x9c, 0x70, 0x78, 0x1f, 0x2c, - 0x91, 0x54, 0x96, 0x99, 0x6b, 0xe8, 0x80, 0xca, 0x9e, 0x2c, 0x87, 0x87, 0xa9, 0x47, 0xc6, 0xb8, - 0x69, 0xa6, 0xe6, 0xeb, 0x7a, 0x5f, 0xd4, 0xbc, 0x14, 0x84, 0xd7, 0xc1, 0xc2, 0x00, 0x53, 0xcc, - 0x09, 0x77, 0x87, 0x88, 0x0f, 0x75, 0x42, 0x56, 0x34, 0xb6, 0x8d, 0xf8, 0x50, 0xfa, 0xc5, 0x23, - 0x14, 0x25, 0x93, 0x54, 0x23, 0xcd, 0x46, 0x90, 0x42, 0x4a, 0xa1, 0x05, 0x00, 0x8f, 0xd1, 0x01, - 0x55, 0x2d, 0x59, 0xf9, 0xed, 0xb4, 0x99, 0x35, 0xaf, 0x78, 0x52, 0x02, 0xf7, 0x40, 0x75, 0x44, - 0x3d, 0x46, 0x83, 0xe9, 0x44, 0x50, 0x6d, 0xf4, 0x94, 0x3d, 0xfd, 0x7c, 0x4e, 0xd6, 0x1d, 0xfd, - 0x2d, 0x63, 0xe2, 0xec, 0x3f, 0x1a, 0x13, 0xb7, 0x01, 0x1c, 0x12, 0x2e, 0x58, 0x42, 0x7c, 0x14, - 0xba, 0x98, 0x8a, 0x84, 0x60, 0x5e, 0x3b, 0xa7, 0x32, 0xe5, 0xc2, 0x54, 0x62, 0xa7, 0x02, 0x5d, - 0xee, 0x14, 0xab, 0xc1, 0x25, 0x0b, 0xb2, 0xac, 0x62, 0xbd, 0x30, 0x05, 0x3b, 0x41, 0x63, 0x0d, - 0x54, 0xf2, 0x70, 0x07, 0x1c, 0x56, 0x41, 0x89, 0x04, 0x69, 0xff, 0x9f, 0x77, 0xe4, 0xb2, 0xf1, - 0x95, 0x01, 0x96, 0x3b, 0x34, 0x9b, 0x8e, 0x85, 0x24, 0xb8, 0x07, 0x2a, 0x01, 0x1b, 0x79, 0x21, - 0x76, 0x65, 0xd7, 0xd6, 0x19, 0x70, 0xe3, 0x78, 0x2d, 0xf6, 0x42, 0xc4, 0x87, 0x1f, 0x20, 0x12, - 0x4e, 0xb9, 0x0e, 0x48, 0x99, 0x3d, 0x32, 0xa0, 0x70, 0x13, 0x94, 0x03, 0x76, 0x40, 0x55, 0xf4, - 0x66, 0xff, 0xce, 0x21, 0x39, 0xad, 0xf1, 0xab, 0x01, 0x2e, 0x9e, 0xa0, 0x01, 0x3f, 0x06, 0x4b, - 0x5c, 0xc2, 0xd3, 0xe1, 0xae, 0x0a, 0x7a, 0xeb, 0x7f, 0xd2, 0xcb, 0xbf, 0xbc, 0x5a, 0xbb, 0x92, - 0x3e, 0xa8, 0x78, 0xb0, 0x6f, 0x12, 0x66, 0x45, 0x48, 0x0c, 0xcd, 0x5d, 0x3c, 0x40, 0xfe, 0xa4, - 0x8d, 0xfd, 0x9f, 0xbe, 0xbb, 0x0d, 0xf4, 0x7b, 0xab, 0x8d, 0xfd, 0x6f, 0xfe, 0xf8, 0xf6, 0xa6, - 0xe1, 0x2c, 0xaa, 0xd3, 0xf2, 0xb7, 0xc0, 0x36, 0x58, 0x7c, 0x8a, 0x48, 0xe8, 0x66, 0x4f, 0x2c, - 0x6d, 0xfe, 0xa9, 0xc2, 0xbb, 0x20, 0x99, 0x19, 0x2e, 0x87, 0xaf, 0x60, 0x91, 0xc7, 0x05, 0xa3, - 0x58, 0xa5, 0x78, 0xd9, 0x99, 0x02, 0x37, 0x7f, 0x34, 0xc0, 0x62, 0x3e, 0x81, 0x86, 0x88, 0x63, - 0x58, 0x07, 0xab, 0xad, 0x87, 0x7b, 0xbd, 0x47, 0x0f, 0x6c, 0xc7, 0xed, 0x6e, 0x6f, 0xf6, 0x6c, - 0xf7, 0xd1, 0x5e, 0xaf, 0x6b, 0xb7, 0x3a, 0xf7, 0x3a, 0x76, 0xbb, 0x3a, 0x03, 0xaf, 0x81, 0x95, - 0x23, 0x72, 0xc7, 0xbe, 0xdf, 0xe9, 0xf5, 0x6d, 0xc7, 0x6e, 0x57, 0x8d, 0x13, 0xe8, 0x9d, 0xbd, - 0x4e, 0xbf, 0xb3, 0xb9, 0xdb, 0x79, 0x6c, 0xb7, 0xab, 0xb3, 0xf0, 0x0a, 0xb8, 0x7c, 0x44, 0xbe, - 0xbb, 0xf9, 0x68, 0xaf, 0xb5, 0x6d, 0xb7, 0xab, 0x25, 0xb8, 0x0a, 0x2e, 0x1d, 0x11, 0xf6, 0xfa, - 0x0f, 0xbb, 0x5d, 0xbb, 0x5d, 0x9d, 0x3b, 0x41, 0xd6, 0xb6, 0x77, 0xed, 0xbe, 0xdd, 0xae, 0x9e, - 0x59, 0x9d, 0xfb, 0xec, 0xeb, 0xfa, 0xcc, 0x56, 0xe7, 0xc5, 0x61, 0xdd, 0x78, 0x79, 0x58, 0x37, - 0x7e, 0x3f, 0xac, 0x1b, 0xcf, 0x5f, 0xd7, 0x67, 0x5e, 0xbe, 0xae, 0xcf, 0xfc, 0xfc, 0xba, 0x3e, - 0xf3, 0xd8, 0x1a, 0x10, 0x31, 0x1c, 0x79, 0xa6, 0xcf, 0x22, 0x0b, 0x85, 0x21, 0xa1, 0x1e, 0x11, - 0xdc, 0x52, 0x6f, 0xc7, 0x67, 0xd6, 0x9b, 0x8f, 0x6e, 0x31, 0x89, 0x31, 0xf7, 0xce, 0x2a, 0xff, - 0xfe, 0xf7, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa7, 0xa1, 0x45, 0x46, 0x92, 0x0b, 0x00, 0x00, + 0x77, 0xd8, 0x79, 0x87, 0x1d, 0xba, 0xdb, 0xb0, 0xdb, 0xb0, 0xcb, 0x8e, 0x3b, 0x0c, 0xc3, 0x3e, + 0x42, 0x77, 0x2b, 0x76, 0x1a, 0x86, 0xa1, 0x1b, 0xda, 0xc3, 0xbe, 0xc6, 0x40, 0x8a, 0x52, 0x9c, + 0x3f, 0x2d, 0x52, 0xec, 0x22, 0x90, 0xbf, 0xe7, 0xf9, 0x51, 0xcf, 0x3f, 0x3e, 0x0f, 0x41, 0x63, + 0x82, 0x10, 0xb7, 0xe2, 0x84, 0x4d, 0x48, 0x80, 0x13, 0x6b, 0xd2, 0xca, 0xd7, 0x66, 0x9c, 0x30, + 0xc1, 0x60, 0x45, 0x2a, 0x98, 0x39, 0x38, 0x69, 0xd5, 0xce, 0xa3, 0x88, 0x50, 0x66, 0xa9, 0x6f, + 0xaa, 0x54, 0xfb, 0x9f, 0xcf, 0x78, 0xc4, 0xb8, 0x85, 0xa5, 0x12, 0xf5, 0xb1, 0x35, 0x69, 0x79, + 0x58, 0xa0, 0x56, 0x0e, 0x68, 0xbd, 0xd5, 0x54, 0xcf, 0x55, 0x3b, 0x2b, 0xdd, 0x68, 0xd1, 0xca, + 0x90, 0x0d, 0x59, 0x8a, 0xcb, 0x95, 0x46, 0xeb, 0x43, 0xc6, 0x86, 0x21, 0xb6, 0xd4, 0xce, 0x1b, + 0x3f, 0xb2, 0x82, 0x71, 0x82, 0x04, 0x61, 0x54, 0xcb, 0x1b, 0x47, 0xe5, 0x82, 0x44, 0x98, 0x0b, + 0x14, 0xc5, 0x99, 0x02, 0xf1, 0x7c, 0xcb, 0x67, 0x09, 0xb6, 0xfc, 0x90, 0x60, 0x2a, 0xa4, 0x87, + 0xe9, 0x4a, 0x2b, 0x58, 0x52, 0x21, 0x24, 0xc3, 0x91, 0x48, 0x61, 0x6e, 0x09, 0x4c, 0x03, 0x9c, + 0x44, 0x24, 0x55, 0x3e, 0xd8, 0x69, 0x02, 0x54, 0x11, 0x9b, 0xb4, 0xac, 0x7d, 0x92, 0x64, 0x7e, + 0x5d, 0x99, 0xe1, 0xf8, 0xc9, 0x34, 0x16, 0xcc, 0xda, 0xc3, 0x53, 0xed, 0x5a, 0xf3, 0xcb, 0x79, + 0x70, 0xb6, 0x87, 0x12, 0x14, 0x71, 0xf8, 0x3e, 0xa8, 0x8a, 0x64, 0xcc, 0x05, 0xa1, 0x43, 0x37, + 0xc6, 0x09, 0x61, 0x81, 0xfb, 0x28, 0x41, 0xbe, 0xf4, 0xa8, 0x6a, 0xac, 0x19, 0xeb, 0x8b, 0xce, + 0xc5, 0x4c, 0xde, 0x53, 0xe2, 0x3b, 0x5a, 0x0a, 0xfb, 0xe0, 0x82, 0xfc, 0xb1, 0x2b, 0x1d, 0x64, + 0x63, 0xa1, 0xd9, 0xd5, 0xf9, 0x35, 0x63, 0xbd, 0x74, 0x6b, 0xd5, 0x4c, 0xe3, 0x60, 0x66, 0x71, + 0x30, 0x3b, 0x3a, 0x4e, 0x9b, 0xc5, 0x67, 0x2f, 0x1a, 0x73, 0x5f, 0xff, 0xd9, 0x30, 0x9c, 0xf3, + 0x92, 0x3f, 0x48, 0xe9, 0xe9, 0xe1, 0x70, 0x1d, 0x54, 0xbc, 0x90, 0xf9, 0x7b, 0x5c, 0x1e, 0xe7, + 0xe2, 0x98, 0xf9, 0xa3, 0x6a, 0x61, 0xcd, 0x58, 0x2f, 0x38, 0xcb, 0x29, 0xde, 0xc3, 0x89, 0x2d, + 0x51, 0xd8, 0x05, 0xd7, 0x22, 0xf4, 0xc4, 0xcd, 0xea, 0xc0, 0xf5, 0x19, 0xe5, 0x98, 0xf2, 0x31, + 0x77, 0x27, 0x28, 0x24, 0x01, 0x12, 0x2c, 0xe1, 0xd5, 0x05, 0x45, 0xad, 0x47, 0xe8, 0x49, 0x4f, + 0xeb, 0xb5, 0x33, 0xb5, 0x8f, 0x73, 0xad, 0xe6, 0xff, 0x41, 0x69, 0x23, 0x08, 0x12, 0xcc, 0xf9, + 0x0e, 0xe1, 0x02, 0x5e, 0x01, 0x8b, 0x28, 0xdd, 0x62, 0x5e, 0x35, 0xd6, 0x0a, 0xeb, 0x65, 0xe7, + 0x00, 0x68, 0x7e, 0x02, 0x56, 0x73, 0x6a, 0x1f, 0x8b, 0xf6, 0x08, 0xd1, 0x21, 0xee, 0x21, 0x7f, + 0x0f, 0x0b, 0x0e, 0x6f, 0x83, 0x85, 0x90, 0x70, 0xa1, 0x58, 0xa5, 0x5b, 0xd7, 0x4d, 0x55, 0xaa, + 0x93, 0x96, 0xf9, 0x3a, 0x46, 0x07, 0x09, 0xb4, 0xb9, 0x20, 0x03, 0xe2, 0x28, 0x62, 0xf3, 0x2b, + 0x03, 0x54, 0xb7, 0xf1, 0x74, 0x83, 0x73, 0x32, 0xa4, 0x11, 0xa6, 0xc2, 0xc1, 0x71, 0x88, 0x7c, + 0x2c, 0x97, 0xf0, 0xbf, 0x60, 0x29, 0x77, 0x57, 0x1a, 0xa4, 0x12, 0x54, 0x76, 0xca, 0x19, 0x28, + 0x9d, 0x80, 0x1f, 0x00, 0x10, 0x27, 0x78, 0xe2, 0xfa, 0xee, 0x1e, 0x9e, 0xea, 0x6c, 0x5c, 0x31, + 0x67, 0x8a, 0x26, 0x2d, 0x07, 0xb3, 0x37, 0xf6, 0x42, 0xe2, 0x6f, 0xe3, 0xa9, 0x53, 0x94, 0xfa, + 0xed, 0x6d, 0x3c, 0x85, 0x2b, 0xe0, 0x4c, 0xcc, 0xf6, 0x71, 0xa2, 0x43, 0x9e, 0x6e, 0x9a, 0xdf, + 0x18, 0xe0, 0x52, 0xee, 0x80, 0x8c, 0xdf, 0x38, 0xc2, 0x49, 0x6f, 0xec, 0x49, 0xc6, 0x2a, 0x28, + 0xfa, 0x23, 0x44, 0xa8, 0x4b, 0x02, 0x5d, 0x2e, 0xe7, 0xd4, 0xbe, 0x1b, 0x1c, 0xb7, 0x76, 0xfe, + 0x04, 0x6b, 0x6f, 0x83, 0xb2, 0xaf, 0x4f, 0x54, 0xf6, 0x16, 0x4e, 0x61, 0x6f, 0x29, 0x63, 0x6c, + 0xe3, 0x69, 0xf3, 0xf3, 0x19, 0xdb, 0x36, 0xa7, 0x99, 0x75, 0xea, 0xec, 0x37, 0xdb, 0x96, 0xff, + 0x76, 0xd6, 0x36, 0x7f, 0x96, 0x7f, 0xcc, 0x81, 0xc2, 0x71, 0x07, 0x9a, 0x3f, 0x1b, 0x60, 0x65, + 0xf6, 0xaf, 0x7c, 0xc0, 0x7a, 0xc9, 0x98, 0xe2, 0x37, 0xfd, 0xfd, 0x36, 0x28, 0xc6, 0x52, 0xc7, + 0x15, 0x5c, 0x27, 0xa8, 0x76, 0xec, 0xba, 0x0c, 0xb2, 0xb6, 0x91, 0xde, 0x97, 0xa7, 0xf2, 0xbe, + 0x9c, 0x53, 0xac, 0x01, 0x87, 0x1d, 0xb0, 0x7c, 0xc8, 0x7c, 0xae, 0xe3, 0x76, 0xd5, 0x3c, 0xda, + 0x1b, 0xcd, 0x99, 0xc2, 0x76, 0x96, 0x66, 0xdd, 0xe3, 0xcd, 0x9f, 0x0c, 0x00, 0x8f, 0x5f, 0x07, + 0xf8, 0x0e, 0x80, 0x87, 0x2e, 0xd5, 0x6c, 0xa9, 0x55, 0xe2, 0x99, 0x6b, 0xa4, 0x82, 0x94, 0x97, + 0xcc, 0xfc, 0x4c, 0xc9, 0xc0, 0x0f, 0x01, 0x88, 0x55, 0xbe, 0x4e, 0x9d, 0xd4, 0xc5, 0x38, 0x5b, + 0xc2, 0x06, 0x28, 0x3d, 0x66, 0x84, 0xba, 0x23, 0x2c, 0x9b, 0xa0, 0xbe, 0xc3, 0x40, 0x42, 0x5b, + 0x0a, 0x69, 0x06, 0xa0, 0x92, 0x85, 0xfc, 0x1e, 0x16, 0x28, 0x40, 0x02, 0x41, 0x08, 0x16, 0x28, + 0x8a, 0xb0, 0x0e, 0xb5, 0x5a, 0xc3, 0x35, 0x50, 0x0a, 0x30, 0xf7, 0x13, 0x12, 0xab, 0x76, 0x36, + 0xaf, 0x44, 0xb3, 0x10, 0xac, 0x81, 0x62, 0xa4, 0x4f, 0x50, 0x56, 0x2e, 0x3a, 0xf9, 0xbe, 0xf9, + 0xac, 0x00, 0xd6, 0xb2, 0xdf, 0x74, 0x29, 0x11, 0x04, 0x85, 0xe4, 0x33, 0xd5, 0xc2, 0x54, 0xeb, + 0xc4, 0x02, 0x27, 0x1c, 0xde, 0x05, 0xcb, 0x24, 0x95, 0x65, 0xe6, 0x1a, 0x3a, 0xa1, 0xc4, 0xf3, + 0x4d, 0xd9, 0xe6, 0x4d, 0xdd, 0xdc, 0x27, 0x2d, 0x33, 0x35, 0x5f, 0xdf, 0xf7, 0x25, 0xcd, 0x4b, + 0x41, 0x78, 0x0d, 0x94, 0x87, 0x98, 0x62, 0x4e, 0xb8, 0x3b, 0x42, 0x7c, 0xa4, 0x0b, 0xb2, 0xa4, + 0xb1, 0x2d, 0xc4, 0x47, 0x32, 0x2e, 0x1e, 0xa1, 0x28, 0x99, 0xa6, 0x1a, 0x69, 0x35, 0x82, 0x14, + 0x52, 0x0a, 0x6d, 0x00, 0x78, 0x8c, 0xf6, 0xa9, 0x6a, 0xc9, 0x2a, 0x6e, 0xa7, 0xad, 0xac, 0x45, + 0xc5, 0x93, 0x12, 0xb8, 0x0b, 0x2a, 0x63, 0xea, 0x31, 0x1a, 0x1c, 0x4c, 0x84, 0xea, 0x99, 0xd3, + 0xf7, 0xf4, 0xff, 0xe4, 0x64, 0xdd, 0xd1, 0x5f, 0x33, 0x26, 0xce, 0xfe, 0xab, 0x31, 0x71, 0x13, + 0xc0, 0x11, 0xe1, 0x82, 0x25, 0xc4, 0x47, 0xa1, 0x8b, 0xa9, 0x48, 0x08, 0xe6, 0xd5, 0x73, 0xaa, + 0x52, 0xce, 0x1f, 0x48, 0xec, 0x54, 0xd0, 0x6c, 0x80, 0x52, 0x9e, 0xc9, 0x80, 0xc3, 0x0a, 0x28, + 0x90, 0x20, 0x6d, 0xed, 0x8b, 0x8e, 0x5c, 0x36, 0xbf, 0x35, 0xc0, 0x4a, 0x97, 0x66, 0x83, 0x6f, + 0x26, 0xbf, 0x77, 0x40, 0x29, 0x60, 0x63, 0x2f, 0xc4, 0xae, 0x6c, 0xc8, 0x3a, 0xb9, 0xd7, 0x8f, + 0x5f, 0xb3, 0x7e, 0x88, 0xf8, 0xe8, 0x23, 0x44, 0xc2, 0x03, 0xae, 0x03, 0x52, 0x66, 0x9f, 0x0c, + 0x29, 0xdc, 0x00, 0xc5, 0x80, 0xed, 0x53, 0x95, 0x98, 0xf9, 0xb7, 0x39, 0x24, 0xa7, 0x35, 0xff, + 0x30, 0xc0, 0x85, 0x13, 0x34, 0xe0, 0xa7, 0x60, 0x99, 0x4b, 0xf8, 0xf0, 0xdc, 0x2e, 0x6f, 0xbe, + 0x27, 0x03, 0xf8, 0xfb, 0x8b, 0xc6, 0xe5, 0xf4, 0x55, 0xc3, 0x83, 0x3d, 0x93, 0x30, 0x2b, 0x42, + 0x62, 0x64, 0xee, 0xe0, 0x21, 0xf2, 0xa7, 0x1d, 0xec, 0xff, 0xfa, 0xe3, 0x4d, 0xa0, 0x1f, 0x3d, + 0x1d, 0xec, 0x7f, 0xff, 0xf7, 0x0f, 0x37, 0x0c, 0x67, 0x49, 0x9d, 0x96, 0x8f, 0xf9, 0x2d, 0xb0, + 0xf4, 0x18, 0x91, 0xd0, 0xcd, 0xde, 0x39, 0x6f, 0x33, 0xe0, 0xcb, 0x92, 0x99, 0xe1, 0x72, 0xae, + 0x0a, 0x16, 0x79, 0x5c, 0x30, 0x8a, 0x55, 0xf5, 0x16, 0x9d, 0x03, 0xe0, 0xc6, 0x2f, 0x06, 0x58, + 0xca, 0x87, 0xcb, 0x08, 0x71, 0x0c, 0xeb, 0xa0, 0xd6, 0xbe, 0xbf, 0xdb, 0x7f, 0x70, 0xcf, 0x76, + 0xdc, 0xde, 0xd6, 0x46, 0xdf, 0x76, 0x1f, 0xec, 0xf6, 0x7b, 0x76, 0xbb, 0x7b, 0xa7, 0x6b, 0x77, + 0x2a, 0x73, 0xf0, 0x2a, 0x58, 0x3d, 0x22, 0x77, 0xec, 0xbb, 0xdd, 0xfe, 0xc0, 0x76, 0xec, 0x4e, + 0xc5, 0x38, 0x81, 0xde, 0xdd, 0xed, 0x0e, 0xba, 0x1b, 0x3b, 0xdd, 0x87, 0x76, 0xa7, 0x32, 0x0f, + 0x2f, 0x83, 0x4b, 0x47, 0xe4, 0x3b, 0x1b, 0x0f, 0x76, 0xdb, 0x5b, 0x76, 0xa7, 0x52, 0x80, 0x35, + 0x70, 0xf1, 0x88, 0xb0, 0x3f, 0xb8, 0xdf, 0xeb, 0xd9, 0x9d, 0xca, 0xc2, 0x09, 0xb2, 0x8e, 0xbd, + 0x63, 0x0f, 0xec, 0x4e, 0xe5, 0x4c, 0x6d, 0xe1, 0x8b, 0xef, 0xea, 0x73, 0x9b, 0xdd, 0x67, 0x2f, + 0xeb, 0xc6, 0xf3, 0x97, 0x75, 0xe3, 0xaf, 0x97, 0x75, 0xe3, 0xe9, 0xab, 0xfa, 0xdc, 0xf3, 0x57, + 0xf5, 0xb9, 0xdf, 0x5e, 0xd5, 0xe7, 0x1e, 0x5a, 0x43, 0x22, 0x46, 0x63, 0xcf, 0xf4, 0x59, 0x64, + 0xa1, 0x30, 0x24, 0xd4, 0x23, 0x82, 0x5b, 0xea, 0x01, 0xf7, 0xc4, 0x3a, 0xfc, 0xf2, 0x15, 0xd3, + 0x18, 0x73, 0xef, 0xac, 0x8a, 0xef, 0xbb, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa4, 0xcb, 0x13, + 0x60, 0x17, 0x0b, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -1064,12 +1039,12 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.MaxProviderConsensusValidators != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.MaxProviderConsensusValidators)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x20 } if m.BlocksPerEpoch != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.BlocksPerEpoch)) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x18 } n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.VaasTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.VaasTimeoutPeriod):]) if err1 != nil { @@ -1078,24 +1053,12 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n1 i = encodeVarintProvider(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 if len(m.TrustingPeriodFraction) > 0 { i -= len(m.TrustingPeriodFraction) copy(dAtA[i:], m.TrustingPeriodFraction) i = encodeVarintProvider(dAtA, i, uint64(len(m.TrustingPeriodFraction))) i-- - dAtA[i] = 0x12 - } - if m.TemplateClient != nil { - { - size, err := m.TemplateClient.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintProvider(dAtA, i, uint64(size)) - } - i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -1342,12 +1305,12 @@ func (m *ConsumerAddrsToPrune) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - n6, err6 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.PruneTs, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.PruneTs):]) - if err6 != nil { - return 0, err6 + n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.PruneTs, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.PruneTs):]) + if err5 != nil { + return 0, err5 } - i -= n6 - i = encodeVarintProvider(dAtA, i, uint64(n6)) + i -= n5 + i = encodeVarintProvider(dAtA, i, uint64(n5)) i-- dAtA[i] = 0x12 if len(m.ChainId) > 0 { @@ -1476,41 +1439,34 @@ func (m *ConsumerInitializationParameters) MarshalToSizedBuffer(dAtA []byte) (in _ = i var l int _ = l - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintProvider(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x42 - } if m.HistoricalEntries != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.HistoricalEntries)) i-- dAtA[i] = 0x38 } - n8, err8 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.VaasTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.VaasTimeoutPeriod):]) + n7, err7 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.VaasTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.VaasTimeoutPeriod):]) + if err7 != nil { + return 0, err7 + } + i -= n7 + i = encodeVarintProvider(dAtA, i, uint64(n7)) + i-- + dAtA[i] = 0x32 + n8, err8 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) if err8 != nil { return 0, err8 } i -= n8 i = encodeVarintProvider(dAtA, i, uint64(n8)) i-- - dAtA[i] = 0x32 - n9, err9 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) + dAtA[i] = 0x2a + n9, err9 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.SpawnTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.SpawnTime):]) if err9 != nil { return 0, err9 } i -= n9 i = encodeVarintProvider(dAtA, i, uint64(n9)) i-- - dAtA[i] = 0x2a - n10, err10 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.SpawnTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.SpawnTime):]) - if err10 != nil { - return 0, err10 - } - i -= n10 - i = encodeVarintProvider(dAtA, i, uint64(n10)) - i-- dAtA[i] = 0x22 if len(m.BinaryHash) > 0 { i -= len(m.BinaryHash) @@ -1648,12 +1604,12 @@ func (m *SlashJailParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - n14, err14 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.JailDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.JailDuration):]) - if err14 != nil { - return 0, err14 + n13, err13 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.JailDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.JailDuration):]) + if err13 != nil { + return 0, err13 } - i -= n14 - i = encodeVarintProvider(dAtA, i, uint64(n14)) + i -= n13 + i = encodeVarintProvider(dAtA, i, uint64(n13)) i-- dAtA[i] = 0x12 { @@ -1686,10 +1642,6 @@ func (m *Params) Size() (n int) { } var l int _ = l - if m.TemplateClient != nil { - l = m.TemplateClient.Size() - n += 1 + l + sovProvider(uint64(l)) - } l = len(m.TrustingPeriodFraction) if l > 0 { n += 1 + l + sovProvider(uint64(l)) @@ -1885,10 +1837,6 @@ func (m *ConsumerInitializationParameters) Size() (n int) { if m.HistoricalEntries != 0 { n += 1 + sovProvider(uint64(m.HistoricalEntries)) } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovProvider(uint64(l)) - } return n } @@ -1976,42 +1924,6 @@ func (m *Params) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TemplateClient", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthProvider - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthProvider - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.TemplateClient == nil { - m.TemplateClient = &_07_tendermint.ClientState{} - } - if err := m.TemplateClient.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TrustingPeriodFraction", wireType) } @@ -2043,7 +1955,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.TrustingPeriodFraction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field VaasTimeoutPeriod", wireType) } @@ -2076,7 +1988,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field BlocksPerEpoch", wireType) } @@ -2095,7 +2007,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } - case 5: + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field MaxProviderConsensusValidators", wireType) } @@ -3445,38 +3357,6 @@ func (m *ConsumerInitializationParameters) Unmarshal(dAtA []byte) error { break } } - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthProvider - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthProvider - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) diff --git a/x/vaas/provider/types/tx.pb.go b/x/vaas/provider/types/tx.pb.go index 354b985..9dadc4e 100644 --- a/x/vaas/provider/types/tx.pb.go +++ b/x/vaas/provider/types/tx.pb.go @@ -465,7 +465,7 @@ func (m *MsgRemoveConsumerResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRemoveConsumerResponse proto.InternalMessageInfo -// MsgCreateConsumer defines the message that creates a consumer chain +// MsgCreateConsumer defines the message that creates a consumer chain. type MsgCreateConsumer struct { // Submitter address. If the message is successfully handled, the ownership of // the consumer chain will given to this address. @@ -750,76 +750,76 @@ func init() { func init() { proto.RegisterFile("vaas/provider/v1/tx.proto", fileDescriptor_a07778b1d094765c) } var fileDescriptor_a07778b1d094765c = []byte{ - // 1102 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4d, 0x6f, 0xdc, 0x44, - 0x18, 0x5e, 0xe7, 0xab, 0xed, 0x24, 0xa4, 0xc4, 0xa4, 0x64, 0x77, 0x29, 0xbb, 0xed, 0x22, 0x28, - 0x14, 0xb0, 0x49, 0x90, 0x5a, 0x29, 0x42, 0x48, 0xf9, 0x40, 0x22, 0x42, 0x2b, 0x22, 0x57, 0xf4, - 0x00, 0x08, 0x6b, 0x6c, 0x4f, 0xbd, 0xa3, 0xd8, 0x33, 0x96, 0x67, 0x76, 0xd3, 0xe5, 0x84, 0x38, - 0x20, 0xc4, 0x09, 0x0e, 0xdc, 0xfb, 0x13, 0x7a, 0xe0, 0x47, 0xf4, 0x58, 0x38, 0x21, 0x0e, 0x15, - 0x4a, 0x24, 0xca, 0x99, 0x5f, 0x80, 0x3c, 0x33, 0xf6, 0xda, 0x5e, 0xef, 0x07, 0x05, 0x2e, 0x2b, - 0xcf, 0xbc, 0xcf, 0x3c, 0xef, 0x3b, 0xcf, 0xfb, 0x8c, 0x67, 0x0d, 0x1a, 0x03, 0x08, 0x99, 0x19, - 0xc5, 0x74, 0x80, 0x3d, 0x14, 0x9b, 0x83, 0x6d, 0x93, 0xdf, 0x37, 0xa2, 0x98, 0x72, 0xaa, 0x3f, - 0x9f, 0x84, 0x8c, 0x34, 0x64, 0x0c, 0xb6, 0x9b, 0x1b, 0x30, 0xc4, 0x84, 0x9a, 0xe2, 0x57, 0x82, - 0x9a, 0x57, 0x7d, 0x4a, 0xfd, 0x00, 0x99, 0x30, 0xc2, 0x26, 0x24, 0x84, 0x72, 0xc8, 0x31, 0x25, - 0x4c, 0x45, 0xdb, 0x2a, 0x2a, 0x46, 0x4e, 0xff, 0x9e, 0xc9, 0x71, 0x88, 0x18, 0x87, 0x61, 0xa4, - 0x00, 0xad, 0x32, 0xc0, 0xeb, 0xc7, 0x82, 0x41, 0xc5, 0x1b, 0xe5, 0x38, 0x24, 0x43, 0x15, 0xda, - 0xf4, 0xa9, 0x4f, 0xc5, 0xa3, 0x99, 0x3c, 0xa5, 0x0b, 0x5c, 0xca, 0x42, 0xca, 0x6c, 0x19, 0x90, - 0x03, 0x15, 0xda, 0x92, 0x23, 0x33, 0x64, 0x7e, 0xb2, 0xcf, 0x90, 0xf9, 0x69, 0x95, 0xd8, 0x71, - 0x4d, 0x97, 0xc6, 0xc8, 0x74, 0x03, 0x8c, 0x08, 0x4f, 0xa2, 0xf2, 0x29, 0x05, 0x8c, 0x89, 0x94, - 0xa9, 0x22, 0x01, 0x66, 0xc2, 0x10, 0x60, 0xbf, 0xc7, 0xe5, 0x3a, 0x66, 0x72, 0x44, 0x3c, 0x14, - 0x87, 0x58, 0xb2, 0x8d, 0x46, 0x29, 0x63, 0x2e, 0xce, 0x87, 0x11, 0x62, 0x26, 0x4a, 0xf8, 0x88, - 0x8b, 0x24, 0xa0, 0xf3, 0x9b, 0x06, 0x36, 0xbb, 0xcc, 0xdf, 0x63, 0x0c, 0xfb, 0xe4, 0x80, 0x12, - 0xd6, 0x0f, 0x51, 0xfc, 0x11, 0x1a, 0xea, 0x6d, 0xb0, 0xea, 0xaa, 0xa1, 0x8d, 0xbd, 0xba, 0x76, - 0x4d, 0x7b, 0xfd, 0x92, 0x05, 0xd2, 0xa9, 0x23, 0x4f, 0xbf, 0x0d, 0x9e, 0x4b, 0xab, 0xb3, 0xa1, - 0xe7, 0xc5, 0xf5, 0x85, 0x04, 0xb2, 0xaf, 0xff, 0xf5, 0xa4, 0xbd, 0x3e, 0x84, 0x61, 0xb0, 0xdb, - 0x49, 0x66, 0x11, 0x63, 0x1d, 0x6b, 0x2d, 0x05, 0xee, 0x79, 0x5e, 0xac, 0x5f, 0x07, 0x6b, 0x19, - 0xf3, 0x09, 0x1a, 0xd6, 0x17, 0x05, 0x75, 0x96, 0x2d, 0x49, 0xfe, 0x0e, 0x58, 0x49, 0xea, 0x41, - 0x71, 0x7d, 0x49, 0x90, 0xd6, 0x7f, 0xf9, 0xe9, 0xed, 0x4d, 0x25, 0xf2, 0x9e, 0x64, 0xbd, 0xc3, - 0x63, 0x4c, 0x7c, 0x4b, 0xe1, 0x76, 0x5f, 0xf8, 0xf6, 0x41, 0xbb, 0xf6, 0xe7, 0x83, 0x76, 0xed, - 0xeb, 0xa7, 0x0f, 0x6f, 0xaa, 0xc9, 0x4e, 0x0b, 0x5c, 0xad, 0xda, 0x9b, 0x85, 0x58, 0x44, 0x09, - 0x43, 0x9d, 0x33, 0x0d, 0xbc, 0xdc, 0x65, 0xfe, 0x9d, 0xbe, 0x13, 0x62, 0x9e, 0x02, 0xba, 0x98, - 0x39, 0xa8, 0x07, 0x07, 0x98, 0xf6, 0x63, 0xfd, 0x16, 0xb8, 0xc4, 0x44, 0x94, 0xa3, 0x58, 0x6a, - 0x30, 0xa5, 0x96, 0x11, 0x54, 0x3f, 0x06, 0x6b, 0x61, 0x8e, 0x47, 0x68, 0xb3, 0xba, 0xf3, 0x96, - 0x81, 0x1d, 0xd7, 0xc8, 0xf7, 0xcf, 0xc8, 0x75, 0x6c, 0xb0, 0x6d, 0xe4, 0x73, 0x5b, 0x05, 0x86, - 0x72, 0x3f, 0x16, 0xcb, 0xfd, 0xd8, 0x7d, 0x31, 0xaf, 0xc0, 0xa8, 0x94, 0xce, 0x0d, 0xf0, 0xea, - 0xd4, 0x3d, 0x66, 0x6a, 0xfc, 0xbc, 0x50, 0xa1, 0xc6, 0x21, 0xed, 0x3b, 0x01, 0xba, 0x4b, 0x39, - 0x26, 0xfe, 0x33, 0xab, 0x61, 0x83, 0x2d, 0xaf, 0x1f, 0x05, 0xd8, 0x85, 0x1c, 0xd9, 0x03, 0xca, - 0x91, 0x9d, 0xba, 0x50, 0x09, 0x73, 0x23, 0xaf, 0x83, 0xf0, 0xa9, 0x71, 0x98, 0x2e, 0xb8, 0x4b, - 0x39, 0xfa, 0x40, 0xc1, 0xad, 0x2b, 0x5e, 0xd5, 0xb4, 0xfe, 0x05, 0xd8, 0xc2, 0xe4, 0x5e, 0x0c, - 0xdd, 0xe4, 0x48, 0xdb, 0x4e, 0x40, 0xdd, 0x13, 0xbb, 0x87, 0xa0, 0x87, 0x62, 0x21, 0xd4, 0xea, - 0xce, 0x6b, 0xb3, 0x94, 0xff, 0x50, 0xa0, 0xad, 0x2b, 0x23, 0x9a, 0xfd, 0x84, 0x45, 0x4e, 0x97, - 0xc5, 0x5f, 0xfa, 0x57, 0xe2, 0xe7, 0x25, 0xcd, 0xc4, 0xff, 0x41, 0x03, 0x97, 0xbb, 0xcc, 0xff, - 0x24, 0xf2, 0x20, 0x47, 0xc7, 0x30, 0x86, 0x21, 0x4b, 0xe4, 0x86, 0x7d, 0xde, 0xa3, 0x31, 0xe6, - 0xc3, 0xd9, 0x72, 0x67, 0x50, 0xfd, 0x16, 0x58, 0x89, 0x04, 0x83, 0x52, 0xb7, 0x6e, 0x94, 0xdf, - 0xb0, 0x86, 0xcc, 0xb0, 0xbf, 0xf4, 0xe8, 0x49, 0xbb, 0x66, 0x29, 0xf4, 0xee, 0xba, 0x28, 0x3e, - 0xe3, 0xe9, 0x34, 0xc0, 0x56, 0xa9, 0xa4, 0xac, 0xdc, 0x08, 0x6c, 0x74, 0x99, 0x6f, 0xa1, 0x90, - 0x0e, 0x50, 0xba, 0xaf, 0xd9, 0xaf, 0x0c, 0x03, 0x2c, 0xd3, 0xd3, 0xe4, 0x54, 0x2f, 0xcc, 0xd8, - 0x8c, 0x84, 0xed, 0x82, 0xa4, 0x20, 0xf9, 0xdc, 0x79, 0x09, 0x34, 0xc6, 0x32, 0x66, 0xe5, 0x7c, - 0xb7, 0x28, 0xea, 0x39, 0x88, 0x11, 0xe4, 0xa3, 0x7a, 0x9e, 0xd5, 0xae, 0x0d, 0x70, 0xd1, 0xed, - 0x41, 0x4c, 0x92, 0x4d, 0x88, 0x4a, 0xad, 0x0b, 0x62, 0x7c, 0xe4, 0xe9, 0x87, 0xe0, 0x62, 0x88, - 0x38, 0xf4, 0x20, 0x87, 0xca, 0x59, 0x9d, 0x71, 0x71, 0xb3, 0x53, 0xa6, 0x90, 0x4a, 0xe6, 0x6c, - 0xa5, 0x4e, 0x41, 0x03, 0x13, 0xcc, 0x31, 0x0c, 0xf0, 0x97, 0xe2, 0x16, 0xb2, 0x45, 0x07, 0x10, - 0x47, 0x31, 0x13, 0xe6, 0x5a, 0xdd, 0xd9, 0x99, 0x4c, 0x7b, 0x54, 0x58, 0x7a, 0x9c, 0xad, 0xb4, - 0xea, 0x78, 0x42, 0x44, 0xff, 0x0c, 0xe4, 0x8c, 0x9d, 0x4f, 0xb6, 0xac, 0x4e, 0xc7, 0x58, 0xb2, - 0xa3, 0x0c, 0x9e, 0x4b, 0xb0, 0x89, 0x2b, 0x66, 0x95, 0x6d, 0x46, 0x9e, 0x7f, 0x4f, 0x74, 0xaa, - 0xd8, 0x8b, 0xb4, 0x53, 0x33, 0x3d, 0xd2, 0xf9, 0x43, 0xb6, 0x52, 0xba, 0x2e, 0x6b, 0x65, 0xe6, - 0x1c, 0x6d, 0x2e, 0xe7, 0x94, 0xd3, 0x2c, 0x8c, 0x59, 0xf1, 0x10, 0x6c, 0x10, 0x74, 0x6a, 0x0b, - 0xb4, 0xad, 0x2e, 0x2a, 0xf9, 0x52, 0x9d, 0x42, 0x7e, 0x99, 0xa0, 0xd3, 0x8f, 0x93, 0x15, 0x6a, - 0x5a, 0x7f, 0x3f, 0x67, 0x87, 0xa5, 0x79, 0xed, 0x30, 0xaf, 0x11, 0x96, 0xff, 0x07, 0x23, 0x5c, - 0x03, 0x6b, 0xc9, 0xb6, 0x33, 0x7b, 0xaf, 0x48, 0x61, 0x08, 0x3a, 0x3d, 0x50, 0x0e, 0x9f, 0x68, - 0x95, 0x0b, 0xff, 0x81, 0x55, 0xc6, 0x0f, 0x74, 0xb1, 0xcf, 0xa9, 0x4d, 0x76, 0x7e, 0x5c, 0x01, - 0x8b, 0x5d, 0xe6, 0xeb, 0x27, 0x60, 0x63, 0xfc, 0xaf, 0x49, 0x45, 0x0d, 0x55, 0xd7, 0x7c, 0xd3, - 0x98, 0x0f, 0x97, 0x79, 0xf3, 0x1b, 0x0d, 0x34, 0xa7, 0xfc, 0x17, 0x30, 0x2b, 0xe9, 0x26, 0x2f, - 0x68, 0xde, 0xfe, 0x87, 0x0b, 0xa6, 0x14, 0x52, 0xb8, 0x86, 0xe7, 0x29, 0x24, 0xbf, 0x60, 0xae, - 0x42, 0xaa, 0x6e, 0x25, 0xdd, 0x01, 0xeb, 0xa5, 0x77, 0xea, 0x2b, 0x95, 0x54, 0x45, 0x50, 0xf3, - 0xcd, 0x39, 0x40, 0xf9, 0x1c, 0xa5, 0xc3, 0x5e, 0x9d, 0xa3, 0x08, 0x9a, 0x90, 0xa3, 0xda, 0x4e, - 0x49, 0x8e, 0xd2, 0x5d, 0x55, 0x9d, 0xa3, 0x08, 0x9a, 0x90, 0xa3, 0xfa, 0x0e, 0xd2, 0x3f, 0x07, - 0x6b, 0x85, 0xdb, 0xfb, 0xfa, 0x94, 0x02, 0x25, 0xa4, 0xf9, 0xc6, 0x4c, 0x48, 0xca, 0xde, 0x5c, - 0xfe, 0xea, 0xe9, 0xc3, 0x9b, 0xda, 0xfe, 0xd1, 0xa3, 0xb3, 0x96, 0xf6, 0xf8, 0xac, 0xa5, 0xfd, - 0x7e, 0xd6, 0xd2, 0xbe, 0x3f, 0x6f, 0xd5, 0x1e, 0x9f, 0xb7, 0x6a, 0xbf, 0x9e, 0xb7, 0x6a, 0x9f, - 0x9a, 0x3e, 0xe6, 0xbd, 0xbe, 0x63, 0xb8, 0x34, 0x34, 0x61, 0x10, 0x60, 0xe2, 0x60, 0xce, 0x4c, - 0xf1, 0x41, 0x71, 0xdf, 0x2c, 0x7e, 0x57, 0x88, 0x3f, 0x58, 0xce, 0x8a, 0xf8, 0x00, 0x78, 0xf7, - 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xe2, 0x5d, 0x55, 0x9a, 0x0d, 0x00, 0x00, + // 1100 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4d, 0x8f, 0xdb, 0x44, + 0x18, 0x8e, 0xf7, 0xab, 0xed, 0xec, 0xb2, 0x65, 0xcd, 0x96, 0x4d, 0x42, 0x49, 0x5a, 0x23, 0x28, + 0x14, 0xb0, 0xd9, 0x45, 0x6a, 0xa5, 0x08, 0x21, 0xed, 0x07, 0x12, 0x11, 0x8a, 0x58, 0xb9, 0xa2, + 0x07, 0x40, 0x58, 0x63, 0x7b, 0xea, 0x8c, 0xd6, 0x9e, 0xb1, 0x3c, 0x93, 0x6c, 0xc3, 0x09, 0x71, + 0x40, 0x88, 0x13, 0x1c, 0xb8, 0xf7, 0x27, 0xf4, 0xc0, 0x8f, 0xe8, 0xb1, 0x70, 0x42, 0x1c, 0x2a, + 0xb4, 0x2b, 0x51, 0xce, 0xfc, 0x02, 0xe4, 0xf1, 0xd8, 0xb1, 0x1d, 0xe7, 0x83, 0x02, 0x97, 0xc8, + 0xf3, 0xbe, 0xcf, 0xfb, 0x31, 0xcf, 0xfb, 0x8c, 0xc7, 0x01, 0x8d, 0x21, 0x84, 0xcc, 0x08, 0x23, + 0x3a, 0xc4, 0x2e, 0x8a, 0x8c, 0xe1, 0xae, 0xc1, 0xef, 0xeb, 0x61, 0x44, 0x39, 0x55, 0x9f, 0x8f, + 0x5d, 0x7a, 0xea, 0xd2, 0x87, 0xbb, 0xcd, 0x2d, 0x18, 0x60, 0x42, 0x0d, 0xf1, 0x9b, 0x80, 0x9a, + 0x3b, 0x0e, 0x65, 0x01, 0x65, 0x46, 0xc0, 0xbc, 0x38, 0x38, 0x60, 0x9e, 0x74, 0x34, 0x12, 0x87, + 0x25, 0x56, 0x46, 0xb2, 0x90, 0xae, 0x6d, 0x8f, 0x7a, 0x34, 0xb1, 0xc7, 0x4f, 0xd2, 0x7a, 0xd5, + 0xa3, 0xd4, 0xf3, 0x91, 0x01, 0x43, 0x6c, 0x40, 0x42, 0x28, 0x87, 0x1c, 0x53, 0x92, 0xc6, 0x34, + 0xa4, 0x57, 0xac, 0xec, 0xc1, 0x3d, 0x03, 0x92, 0x91, 0x74, 0xb5, 0xca, 0x2e, 0x77, 0x10, 0x89, + 0x58, 0xe9, 0x6f, 0x97, 0xfd, 0x1c, 0x07, 0x88, 0x71, 0x18, 0x84, 0x29, 0x00, 0xdb, 0x8e, 0xe1, + 0xd0, 0x08, 0x19, 0x8e, 0x8f, 0x11, 0xe1, 0xf1, 0x46, 0x92, 0x27, 0x09, 0x30, 0x62, 0x80, 0x8f, + 0xbd, 0x3e, 0x4f, 0xcc, 0xcc, 0xe0, 0x88, 0xb8, 0x28, 0x0a, 0x70, 0x02, 0x1e, 0xaf, 0xd2, 0x8c, + 0x39, 0x3f, 0x1f, 0x85, 0x88, 0x19, 0x28, 0x26, 0x91, 0x38, 0x28, 0x05, 0x4c, 0xd0, 0x9e, 0xf1, + 0x2c, 0x00, 0xda, 0x6f, 0x0a, 0xd8, 0xee, 0x31, 0x6f, 0x9f, 0x31, 0xec, 0x91, 0x43, 0x4a, 0xd8, + 0x20, 0x40, 0xd1, 0x47, 0x68, 0xa4, 0xb6, 0xc1, 0xba, 0x23, 0x97, 0x16, 0x76, 0xeb, 0xca, 0x35, + 0xe5, 0xf5, 0x4b, 0x26, 0x48, 0x4d, 0x5d, 0x57, 0xbd, 0x0d, 0x9e, 0x4b, 0x73, 0x59, 0xd0, 0x75, + 0xa3, 0xfa, 0x52, 0x0c, 0x39, 0x50, 0xff, 0x7a, 0xd2, 0xde, 0x1c, 0xc1, 0xc0, 0xef, 0x68, 0xb1, + 0x15, 0x31, 0xa6, 0x99, 0x1b, 0x29, 0x70, 0xdf, 0x75, 0x23, 0xf5, 0x3a, 0xd8, 0xc8, 0x32, 0x9f, + 0xa0, 0x51, 0x7d, 0x59, 0xa4, 0xce, 0xaa, 0xc5, 0xc5, 0xdf, 0x01, 0x6b, 0x71, 0x3f, 0x28, 0xaa, + 0xaf, 0x88, 0xa4, 0xf5, 0x5f, 0x7e, 0x7a, 0x7b, 0x5b, 0xce, 0x76, 0x3f, 0xc9, 0x7a, 0x87, 0x47, + 0x98, 0x78, 0xa6, 0xc4, 0x75, 0x5e, 0xf8, 0xf6, 0x41, 0xbb, 0xf6, 0xe7, 0x83, 0x76, 0xed, 0xeb, + 0xa7, 0x0f, 0x6f, 0x4a, 0xa3, 0xd6, 0x02, 0x57, 0xab, 0xf6, 0x66, 0x22, 0x16, 0x52, 0xc2, 0x90, + 0x76, 0xa6, 0x80, 0x97, 0x7b, 0xcc, 0xbb, 0x33, 0xb0, 0x03, 0xcc, 0x53, 0x40, 0x0f, 0x33, 0x1b, + 0xf5, 0xe1, 0x10, 0xd3, 0x41, 0xa4, 0xde, 0x02, 0x97, 0x98, 0xf0, 0x72, 0x14, 0x25, 0x1c, 0xcc, + 0xe8, 0x65, 0x0c, 0x55, 0x8f, 0xc1, 0x46, 0x90, 0xcb, 0x23, 0xb8, 0x59, 0xdf, 0x7b, 0x4b, 0xc7, + 0xb6, 0xa3, 0xe7, 0x07, 0xac, 0xe7, 0x46, 0x3a, 0xdc, 0xd5, 0xf3, 0xb5, 0xcd, 0x42, 0x86, 0xf2, + 0x3c, 0x96, 0xcb, 0xf3, 0xe8, 0xbc, 0x98, 0x67, 0x60, 0xdc, 0x8a, 0x76, 0x03, 0xbc, 0x3a, 0x73, + 0x8f, 0x19, 0x1b, 0x3f, 0x2f, 0x55, 0xb0, 0x71, 0x44, 0x07, 0xb6, 0x8f, 0xee, 0x52, 0x8e, 0x89, + 0xf7, 0xcc, 0x6c, 0x58, 0x60, 0xc7, 0x1d, 0x84, 0x3e, 0x76, 0x20, 0x47, 0xd6, 0x90, 0x72, 0x64, + 0xa5, 0x32, 0x95, 0xc4, 0xdc, 0xc8, 0xf3, 0x20, 0x84, 0xac, 0x1f, 0xa5, 0x01, 0x77, 0x29, 0x47, + 0x1f, 0x48, 0xb8, 0x79, 0xc5, 0xad, 0x32, 0xab, 0x5f, 0x80, 0x1d, 0x4c, 0xee, 0x45, 0xd0, 0x89, + 0x8f, 0xa3, 0x65, 0xfb, 0xd4, 0x39, 0xb1, 0xfa, 0x08, 0xba, 0x28, 0x12, 0x44, 0xad, 0xef, 0xbd, + 0x36, 0x8f, 0xf9, 0x0f, 0x05, 0xda, 0xbc, 0x32, 0x4e, 0x73, 0x10, 0x67, 0x49, 0xcc, 0x65, 0xf2, + 0x57, 0xfe, 0x15, 0xf9, 0x79, 0x4a, 0x33, 0xf2, 0x7f, 0x50, 0xc0, 0xe5, 0x1e, 0xf3, 0x3e, 0x09, + 0x5d, 0xc8, 0xd1, 0x31, 0x8c, 0x60, 0xc0, 0x62, 0xba, 0xe1, 0x80, 0xf7, 0x69, 0x84, 0xf9, 0x68, + 0x3e, 0xdd, 0x19, 0x54, 0xbd, 0x05, 0xd6, 0x42, 0x91, 0x41, 0xb2, 0x5b, 0xd7, 0xcb, 0x6f, 0x58, + 0x3d, 0xa9, 0x70, 0xb0, 0xf2, 0xe8, 0x49, 0xbb, 0x66, 0x4a, 0x74, 0x67, 0x53, 0x34, 0x9f, 0xe5, + 0xd1, 0x1a, 0x60, 0xa7, 0xd4, 0x52, 0xd6, 0x6e, 0x08, 0xb6, 0x7a, 0xcc, 0x33, 0x51, 0x40, 0x87, + 0x28, 0xdd, 0xd7, 0xfc, 0x57, 0x86, 0x0e, 0x56, 0xe9, 0x69, 0x7c, 0xaa, 0x97, 0xe6, 0x6c, 0x26, + 0x81, 0x75, 0x40, 0xdc, 0x50, 0xf2, 0xac, 0xbd, 0x04, 0x1a, 0x13, 0x15, 0xb3, 0x76, 0xbe, 0x5b, + 0x16, 0xfd, 0x1c, 0x46, 0x08, 0xf2, 0x71, 0x3f, 0xcf, 0x2a, 0xd7, 0x06, 0xb8, 0xe8, 0xf4, 0x21, + 0x26, 0xf1, 0x26, 0x44, 0xa7, 0xe6, 0x05, 0xb1, 0xee, 0xba, 0xea, 0x11, 0xb8, 0x18, 0x20, 0x0e, + 0x5d, 0xc8, 0xa1, 0x54, 0x96, 0x36, 0x49, 0x6e, 0x76, 0xca, 0x24, 0x52, 0xd2, 0x9c, 0x45, 0xaa, + 0x14, 0x34, 0x30, 0xc1, 0x1c, 0x43, 0x1f, 0x7f, 0x29, 0x6e, 0x10, 0x4b, 0x4c, 0x00, 0x71, 0x14, + 0x31, 0x21, 0xae, 0xf5, 0xbd, 0xbd, 0xe9, 0x69, 0xbb, 0x85, 0xd0, 0xe3, 0x2c, 0xd2, 0xac, 0xe3, + 0x29, 0x1e, 0xf5, 0x33, 0x90, 0x13, 0x76, 0xbe, 0xd8, 0xaa, 0x3c, 0x1d, 0x13, 0xc5, 0xba, 0x19, + 0x3c, 0x57, 0x60, 0x1b, 0x57, 0x58, 0xa5, 0x6c, 0xc6, 0x9a, 0x7f, 0x4f, 0x4c, 0xaa, 0x38, 0x8b, + 0x74, 0x52, 0x73, 0x35, 0xa2, 0xfd, 0x91, 0x8c, 0x32, 0x51, 0x5d, 0x36, 0xca, 0x4c, 0x39, 0xca, + 0x42, 0xca, 0x29, 0x97, 0x59, 0x9a, 0x90, 0xe2, 0x11, 0xd8, 0x22, 0xe8, 0xd4, 0x12, 0x68, 0x4b, + 0x5e, 0x54, 0xc9, 0x4b, 0x75, 0x46, 0xf2, 0xcb, 0x04, 0x9d, 0x7e, 0x1c, 0x47, 0x48, 0xb3, 0xfa, + 0x7e, 0x4e, 0x0e, 0x2b, 0x8b, 0xca, 0x61, 0x51, 0x21, 0xac, 0xfe, 0x0f, 0x42, 0xb8, 0x06, 0x36, + 0xe2, 0x6d, 0x67, 0xf2, 0x5e, 0x4b, 0x88, 0x21, 0xe8, 0xf4, 0x50, 0x2a, 0x7c, 0xaa, 0x54, 0x2e, + 0xfc, 0x07, 0x52, 0x99, 0x3c, 0xd0, 0xc5, 0x39, 0xa7, 0x32, 0xd9, 0xfb, 0x71, 0x0d, 0x2c, 0xf7, + 0x98, 0xa7, 0x9e, 0x80, 0xad, 0xc9, 0x4f, 0x93, 0x8a, 0x1e, 0xaa, 0xae, 0xf9, 0xa6, 0xbe, 0x18, + 0x2e, 0xd3, 0xe6, 0x37, 0x0a, 0x68, 0xce, 0xf8, 0x16, 0x30, 0x2a, 0xd3, 0x4d, 0x0f, 0x68, 0xde, + 0xfe, 0x87, 0x01, 0x33, 0x1a, 0x29, 0x5c, 0xc3, 0x8b, 0x34, 0x92, 0x0f, 0x58, 0xa8, 0x91, 0xaa, + 0x5b, 0x49, 0xb5, 0xc1, 0x66, 0xe9, 0x9d, 0xfa, 0x4a, 0x65, 0xaa, 0x22, 0xa8, 0xf9, 0xe6, 0x02, + 0xa0, 0x7c, 0x8d, 0xd2, 0x61, 0xaf, 0xae, 0x51, 0x04, 0x4d, 0xa9, 0x51, 0x2d, 0xa7, 0xb8, 0x46, + 0xe9, 0xae, 0xaa, 0xae, 0x51, 0x04, 0x4d, 0xa9, 0x51, 0x7d, 0x07, 0xa9, 0x9f, 0x83, 0x8d, 0xc2, + 0xed, 0x7d, 0x7d, 0x46, 0x83, 0x09, 0xa4, 0xf9, 0xc6, 0x5c, 0x48, 0x9a, 0xbd, 0xb9, 0xfa, 0xd5, + 0xd3, 0x87, 0x37, 0x95, 0x83, 0xee, 0xa3, 0xb3, 0x96, 0xf2, 0xf8, 0xac, 0xa5, 0xfc, 0x7e, 0xd6, + 0x52, 0xbe, 0x3f, 0x6f, 0xd5, 0x1e, 0x9f, 0xb7, 0x6a, 0xbf, 0x9e, 0xb7, 0x6a, 0x9f, 0x1a, 0x1e, + 0xe6, 0xfd, 0x81, 0xad, 0x3b, 0x34, 0x30, 0xa0, 0xef, 0x63, 0x62, 0x63, 0xce, 0x0c, 0xf1, 0xf9, + 0x7f, 0xdf, 0x28, 0xfe, 0x0b, 0x10, 0x1f, 0x58, 0xf6, 0x9a, 0xf8, 0x03, 0xf0, 0xee, 0xdf, 0x01, + 0x00, 0x00, 0xff, 0xff, 0x1f, 0xdb, 0x6b, 0x69, 0x9a, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/vaas/types/expected_keepers.go b/x/vaas/types/expected_keepers.go index 006426e..f40e363 100644 --- a/x/vaas/types/expected_keepers.go +++ b/x/vaas/types/expected_keepers.go @@ -4,9 +4,10 @@ import ( context "context" "time" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" + clientv2types "github.com/cosmos/ibc-go/v10/modules/core/02-client/v2/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" addresscodec "cosmossdk.io/core/address" @@ -57,34 +58,21 @@ type SlashingKeeper interface { IsTombstoned(context.Context, sdk.ConsAddress) bool } -// ChannelKeeper defines the expected IBC channel keeper -type ChannelKeeper interface { - GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) - SendPacket( - ctx sdk.Context, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - data []byte, - ) (sequence uint64, err error) - ChanCloseInit(ctx sdk.Context, portID, channelID string) error - GetChannelConnection(ctx sdk.Context, portID, channelID string) (string, conntypes.ConnectionEnd, error) -} - -// ConnectionKeeper defines the expected IBC connection keeper -type ConnectionKeeper interface { - GetConnection(ctx sdk.Context, connectionID string) (conntypes.ConnectionEnd, bool) -} - -// ClientKeeper defines the expected IBC client keeper +// ClientKeeper defines the expected IBC client keeper for v1 operations. type ClientKeeper interface { CreateClient(ctx sdk.Context, clientType string, clientState, consensusState []byte) (string, error) GetClientState(ctx sdk.Context, clientID string) (ibcexported.ClientState, bool) - GetLatestClientConsensusState(ctx sdk.Context, clientID string) (ibcexported.ConsensusState, bool) GetClientConsensusState(ctx sdk.Context, clientID string, height ibcexported.Height) (ibcexported.ConsensusState, bool) + GetClientStatus(ctx sdk.Context, clientID string) ibcexported.Status GetStoreProvider() clienttypes.StoreProvider + IterateClientStates(ctx sdk.Context, storePrefix []byte, cb func(clientID string, cs ibcexported.ClientState) bool) +} + +// ClientV2Keeper defines the expected IBC client v2 keeper for counterparty management. +type ClientV2Keeper interface { + SetClientCounterparty(ctx sdk.Context, clientID string, counterparty clientv2types.CounterpartyInfo) + GetClientCounterparty(ctx sdk.Context, clientID string) (clientv2types.CounterpartyInfo, bool) } // ConsumerHooks event hooks for newly bonded cross-chain validators @@ -104,11 +92,13 @@ type AccountKeeper interface { AddressCodec() addresscodec.Codec } -// IBCCoreKeeper defines the expected interface needed for opening a -// channel -type IBCCoreKeeper interface { - ChannelOpenInit( - goCtx context.Context, - msg *channeltypes.MsgChannelOpenInit, - ) (*channeltypes.MsgChannelOpenInitResponse, error) +// ChannelV2Keeper defines the expected IBC v2 channel keeper for sending packets. +type ChannelV2Keeper interface { + SendPacket(ctx context.Context, msg *channeltypesv2.MsgSendPacket) (*channeltypesv2.MsgSendPacketResponse, error) +} + +// IBCTransferKeeper defines the expected interface needed for distribution transfer +// of tokens from the consumer to the provider chain +type IBCTransferKeeper interface { + Transfer(context.Context, *transfertypes.MsgTransfer) (*transfertypes.MsgTransferResponse, error) } diff --git a/x/vaas/types/genesis.go b/x/vaas/types/genesis.go index 027ea76..b43caed 100644 --- a/x/vaas/types/genesis.go +++ b/x/vaas/types/genesis.go @@ -1,8 +1,6 @@ package types import ( - "strings" - abci "github.com/cometbft/cometbft/abci/types" ibctmtypes "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" @@ -16,7 +14,6 @@ func NewInitialConsumerGenesisState( consState *ibctmtypes.ConsensusState, initValSet []abci.ValidatorUpdate, preVAAS bool, - connectionId string, params ConsumerParams, ) *ConsumerGenesisState { return &ConsumerGenesisState{ @@ -27,8 +24,7 @@ func NewInitialConsumerGenesisState( ConsensusState: consState, InitialValSet: initValSet, }, - PreVAAS: preVAAS, - ConnectionId: connectionId, + PreVAAS: preVAAS, } } @@ -60,13 +56,7 @@ func (gs ConsumerGenesisState) Validate() error { // the consumer VAAS module MUST NOT pass validator updates // to the underlying consensus engine if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { - return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") - } - if err := ValidateConnectionIdentifier(gs.ConnectionId); err != nil { - return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId: %s", err.Error()) - } - if strings.TrimSpace(gs.ConnectionId) == "" { - return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId cannot be empty when preVAAS is true") + return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a pre-VAAS genesis state") } } else { // consumer chain MUST NOT start in pre-VAAS state, i.e., @@ -84,9 +74,6 @@ func (gs ConsumerGenesisState) Validate() error { if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { return errorsmod.Wrapf(ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) } - if strings.TrimSpace(gs.ConnectionId) != "" { - return errorsmod.Wrapf(ErrInvalidGenesis, "ConnectionId must be empty when preVAAS is false") - } } return nil } diff --git a/x/vaas/types/keys.go b/x/vaas/types/keys.go index 3aae47d..8b028d3 100644 --- a/x/vaas/types/keys.go +++ b/x/vaas/types/keys.go @@ -4,15 +4,11 @@ const ( // ModuleName defines the VAAS module name ModuleName = "VAAS" - // Version defines the current version the IBC VAAS provider and consumer - // module supports Version = "1" - // ProviderPortID is the default port id the provider VAAS module binds to - ProviderPortID = "provider" + ProviderAppID = "vaasprovider" - // ConsumerPortID is the default port id the consumer VAAS module binds to - ConsumerPortID = "consumer" + ConsumerAppID = "vaasconsumer" RouterKey = ModuleName diff --git a/x/vaas/types/shared_consumer.pb.go b/x/vaas/types/shared_consumer.pb.go index a5d32d5..3a265cd 100644 --- a/x/vaas/types/shared_consumer.pb.go +++ b/x/vaas/types/shared_consumer.pb.go @@ -121,11 +121,6 @@ type ConsumerGenesisState struct { NewChain bool `protobuf:"varint,3,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` // Flag indicating whether the consumer VAAS module starts in pre-VAAS state PreVAAS bool `protobuf:"varint,4,opt,name=preVAAS,proto3" json:"preVAAS,omitempty"` - // The ID of the connection end on the consumer chain on top of which the - // VAAS channel will be established. If connection_id == "", a new client of - // the provider chain and a new connection on top of this client are created. - // The new client is initialized using client_state and consensus_state. - ConnectionId string `protobuf:"bytes,5,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` } func (m *ConsumerGenesisState) Reset() { *m = ConsumerGenesisState{} } @@ -189,21 +184,12 @@ func (m *ConsumerGenesisState) GetPreVAAS() bool { return false } -func (m *ConsumerGenesisState) GetConnectionId() string { - if m != nil { - return m.ConnectionId - } - return "" -} - // ProviderInfo defines all information a consumer needs from a provider // Shared data type between provider and consumer type ProviderInfo struct { // The client state for the provider client filled in on new chain, nil on restart. - // If connection_id != "", then client_state is ignored. ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` // The consensus state for the provider client filled in on new chain, nil on restart. - // If connection_id != "", then consensus_state is ignored. ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` // InitialValset filled in on new chain and on restart. InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` @@ -272,44 +258,42 @@ func init() { func init() { proto.RegisterFile("vaas/v1/shared_consumer.proto", fileDescriptor_58a750255ca5daa3) } var fileDescriptor_58a750255ca5daa3 = []byte{ - // 583 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x6f, 0xd3, 0x4e, - 0x10, 0x8d, 0x9b, 0xfe, 0xda, 0x74, 0xd3, 0x3f, 0xbf, 0x2e, 0x45, 0x84, 0x56, 0xb8, 0x51, 0x91, - 0x50, 0x24, 0xc4, 0x5a, 0x2d, 0x42, 0x5c, 0x69, 0x0b, 0x42, 0xbd, 0x54, 0x95, 0x03, 0x45, 0xe2, - 0x62, 0xad, 0xed, 0xa9, 0x33, 0x92, 0xb3, 0x6b, 0xed, 0xae, 0x53, 0xf8, 0x04, 0x5c, 0x39, 0xf2, - 0x91, 0x7a, 0xec, 0x91, 0x13, 0xa0, 0xf4, 0x7b, 0x20, 0xe4, 0xf5, 0xa6, 0x71, 0x4f, 0x70, 0xb2, - 0xdf, 0xce, 0xbc, 0xf1, 0x7b, 0xcf, 0xb3, 0xe4, 0xd1, 0x84, 0x73, 0x1d, 0x4c, 0xf6, 0x03, 0x3d, - 0xe2, 0x0a, 0xd2, 0x28, 0x91, 0x42, 0x97, 0x63, 0x50, 0xac, 0x50, 0xd2, 0x48, 0xba, 0x5c, 0x95, - 0xd9, 0x64, 0x7f, 0x7b, 0xc7, 0x80, 0x48, 0x41, 0x8d, 0x51, 0x98, 0x80, 0xc7, 0x09, 0x06, 0xe6, - 0x73, 0x01, 0xba, 0xee, 0xda, 0x0e, 0x30, 0x4e, 0x82, 0x1c, 0xb3, 0x91, 0x49, 0x72, 0x04, 0x61, - 0x74, 0xd0, 0xe8, 0x9e, 0xec, 0x37, 0x90, 0x23, 0xf8, 0x99, 0x94, 0x59, 0x0e, 0x81, 0x45, 0x71, - 0x79, 0x11, 0xa4, 0xa5, 0xe2, 0x06, 0xa5, 0x70, 0xf5, 0xad, 0x4c, 0x66, 0xd2, 0xbe, 0x06, 0xd5, - 0x5b, 0x7d, 0xba, 0xf7, 0xdb, 0x23, 0xeb, 0xc7, 0x4e, 0xdf, 0x19, 0x57, 0x7c, 0xac, 0x69, 0x8f, - 0x2c, 0x83, 0xe0, 0x71, 0x0e, 0x69, 0xcf, 0xeb, 0x7b, 0x83, 0x4e, 0x38, 0x83, 0x74, 0x48, 0xee, - 0x55, 0xda, 0x23, 0x83, 0x63, 0x90, 0xa5, 0x89, 0x0a, 0x50, 0x28, 0xd3, 0xde, 0x42, 0xdf, 0x1b, - 0x74, 0x0f, 0x1e, 0xb2, 0x5a, 0x00, 0x9b, 0x09, 0x60, 0xaf, 0x9d, 0x80, 0xa3, 0xce, 0xd5, 0x8f, - 0xdd, 0xd6, 0xb7, 0x9f, 0xbb, 0x5e, 0xb8, 0x59, 0xf1, 0xdf, 0xd5, 0xf4, 0x33, 0xcb, 0xa6, 0xcf, - 0x08, 0x1d, 0xa1, 0x36, 0x52, 0x61, 0xc2, 0xf3, 0x08, 0x84, 0x51, 0x08, 0xba, 0xd7, 0xee, 0x7b, - 0x83, 0x76, 0xb8, 0x39, 0xaf, 0xbc, 0xa9, 0x0b, 0xf4, 0x94, 0xfc, 0x5f, 0x8a, 0x58, 0x8a, 0x14, - 0x45, 0x36, 0x13, 0xb0, 0xf8, 0xef, 0x02, 0x36, 0x6e, 0xc9, 0xf5, 0xe7, 0xf7, 0xa6, 0x1e, 0xd9, - 0x9a, 0x05, 0xf0, 0x16, 0x04, 0x68, 0xd4, 0x43, 0xc3, 0x0d, 0xd0, 0x17, 0x64, 0xa9, 0xb0, 0x81, - 0xd8, 0x14, 0xba, 0x07, 0x0f, 0x98, 0xfb, 0x6f, 0xec, 0x6e, 0x5e, 0x47, 0x8b, 0xd5, 0xf0, 0xd0, - 0x35, 0xd3, 0x97, 0xa4, 0x53, 0x28, 0x39, 0xc1, 0x14, 0x94, 0x0b, 0xe6, 0xfe, 0x2d, 0xf1, 0xcc, - 0x15, 0x4e, 0xc4, 0x85, 0x74, 0xb4, 0xdb, 0x66, 0xba, 0x43, 0x56, 0x04, 0x5c, 0x46, 0xc9, 0x88, - 0xa3, 0xb0, 0xf6, 0x3b, 0x61, 0x47, 0xc0, 0xe5, 0x71, 0x85, 0xab, 0x7f, 0x52, 0x28, 0x38, 0x3f, - 0x3c, 0x1c, 0x5a, 0xb3, 0x9d, 0x70, 0x06, 0xe9, 0x63, 0xb2, 0x96, 0x48, 0x21, 0x20, 0xa9, 0x8c, - 0x46, 0x98, 0xf6, 0xfe, 0xeb, 0x7b, 0x83, 0x95, 0x70, 0x75, 0x7e, 0x78, 0x92, 0xee, 0x7d, 0x59, - 0x20, 0xab, 0xcd, 0x8f, 0xd3, 0x53, 0xb2, 0x5a, 0xaf, 0x55, 0xa4, 0x2b, 0xb3, 0xce, 0xe2, 0x53, - 0x86, 0x71, 0xc2, 0x9a, 0x4b, 0xc7, 0x1a, 0x6b, 0x56, 0x39, 0xb7, 0xa7, 0x36, 0x9f, 0xb0, 0x9b, - 0xcc, 0x01, 0xfd, 0x40, 0x36, 0xaa, 0x2d, 0x07, 0xa1, 0x4b, 0xed, 0x46, 0xd6, 0xe6, 0xd9, 0x5f, - 0x47, 0xce, 0x68, 0xf5, 0xd4, 0xf5, 0xe4, 0x0e, 0xa6, 0xa7, 0x64, 0x03, 0x05, 0x1a, 0xe4, 0x79, - 0x34, 0xe1, 0x79, 0xa4, 0xc1, 0xf4, 0xda, 0xfd, 0xf6, 0xa0, 0x7b, 0xd0, 0x6f, 0xce, 0xa9, 0x6e, - 0x0f, 0x3b, 0xe7, 0x39, 0xa6, 0xdc, 0x48, 0xf5, 0xbe, 0x48, 0xb9, 0x01, 0x17, 0xf0, 0x9a, 0xa3, - 0x9f, 0xf3, 0x7c, 0x08, 0xe6, 0xe8, 0xd5, 0xd5, 0xd4, 0xf7, 0xae, 0xa7, 0xbe, 0xf7, 0x6b, 0xea, - 0x7b, 0x5f, 0x6f, 0xfc, 0xd6, 0xf5, 0x8d, 0xdf, 0xfa, 0x7e, 0xe3, 0xb7, 0x3e, 0x3e, 0xc9, 0xd0, - 0x8c, 0xca, 0x98, 0x25, 0x72, 0x1c, 0xf0, 0x3c, 0x47, 0x11, 0xa3, 0xd1, 0x81, 0xbd, 0xca, 0x9f, - 0xea, 0x87, 0xbd, 0x9e, 0xf1, 0x92, 0x5d, 0xaf, 0xe7, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x6a, - 0x13, 0x36, 0x8c, 0xe6, 0x03, 0x00, 0x00, + // 560 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x41, 0x6f, 0xd4, 0x3c, + 0x10, 0xdd, 0x74, 0xab, 0x36, 0x9f, 0xb7, 0x5f, 0x4b, 0x4d, 0x11, 0x4b, 0x2b, 0xd2, 0x55, 0x0f, + 0x68, 0x25, 0x84, 0xad, 0x16, 0x21, 0xae, 0xb4, 0x05, 0x21, 0x2e, 0x55, 0x95, 0x85, 0x22, 0x71, + 0x89, 0x9c, 0x64, 0x9a, 0xb5, 0x94, 0xb5, 0x23, 0xdb, 0x49, 0xe1, 0x17, 0x70, 0xe5, 0xc8, 0x9f, + 0xe1, 0xde, 0x63, 0x8f, 0x9c, 0x00, 0x75, 0xff, 0x07, 0x42, 0x71, 0x9c, 0x6d, 0x7a, 0x82, 0x53, + 0xfc, 0x3c, 0xf3, 0x26, 0x6f, 0x9e, 0x67, 0xd0, 0xc3, 0x8a, 0x31, 0x4d, 0xab, 0x7d, 0xaa, 0xa7, + 0x4c, 0x41, 0x1a, 0x25, 0x52, 0xe8, 0x72, 0x06, 0x8a, 0x14, 0x4a, 0x1a, 0x89, 0x57, 0xeb, 0x30, + 0xa9, 0xf6, 0xb7, 0x77, 0x0c, 0x88, 0x14, 0xd4, 0x8c, 0x0b, 0x43, 0x59, 0x9c, 0x70, 0x6a, 0x3e, + 0x15, 0xa0, 0x9b, 0xac, 0x6d, 0xca, 0xe3, 0x84, 0xe6, 0x3c, 0x9b, 0x9a, 0x24, 0xe7, 0x20, 0x8c, + 0xa6, 0x9d, 0xec, 0x6a, 0xbf, 0x83, 0x1c, 0x21, 0xc8, 0xa4, 0xcc, 0x72, 0xa0, 0x16, 0xc5, 0xe5, + 0x39, 0x4d, 0x4b, 0xc5, 0x0c, 0x97, 0xc2, 0xc5, 0xb7, 0x32, 0x99, 0x49, 0x7b, 0xa4, 0xf5, 0xa9, + 0xb9, 0xdd, 0xfb, 0xed, 0xa1, 0xf5, 0x63, 0xa7, 0xef, 0x94, 0x29, 0x36, 0xd3, 0x78, 0x88, 0x56, + 0x41, 0xb0, 0x38, 0x87, 0x74, 0xe8, 0x8d, 0xbc, 0xb1, 0x1f, 0xb6, 0x10, 0x4f, 0xd0, 0xdd, 0x5a, + 0x7b, 0x64, 0xf8, 0x0c, 0x64, 0x69, 0xa2, 0x02, 0x14, 0x97, 0xe9, 0x70, 0x69, 0xe4, 0x8d, 0x07, + 0x07, 0x0f, 0x48, 0x23, 0x80, 0xb4, 0x02, 0xc8, 0x4b, 0x27, 0xe0, 0xc8, 0xbf, 0xfc, 0xb1, 0xdb, + 0xfb, 0xfa, 0x73, 0xd7, 0x0b, 0x37, 0x6b, 0xfe, 0xdb, 0x86, 0x7e, 0x6a, 0xd9, 0xf8, 0x09, 0xc2, + 0x53, 0xae, 0x8d, 0x54, 0x3c, 0x61, 0x79, 0x04, 0xc2, 0x28, 0x0e, 0x7a, 0xd8, 0x1f, 0x79, 0xe3, + 0x7e, 0xb8, 0x79, 0x13, 0x79, 0xd5, 0x04, 0xf0, 0x09, 0xba, 0x53, 0x8a, 0x58, 0x8a, 0x94, 0x8b, + 0xac, 0x15, 0xb0, 0xfc, 0xef, 0x02, 0x36, 0x16, 0xe4, 0xe6, 0xf7, 0x7b, 0xdf, 0x3c, 0xb4, 0xd5, + 0x1a, 0xf0, 0x1a, 0x04, 0x68, 0xae, 0x27, 0x86, 0x19, 0xc0, 0xcf, 0xd0, 0x4a, 0x61, 0x0d, 0xb1, + 0x2e, 0x0c, 0x0e, 0xee, 0x13, 0xf7, 0x6e, 0xe4, 0xb6, 0x5f, 0x47, 0xcb, 0x75, 0xf1, 0xd0, 0x25, + 0xe3, 0xe7, 0xc8, 0x2f, 0x94, 0xac, 0x78, 0x0a, 0xca, 0x19, 0x73, 0x6f, 0x41, 0x3c, 0x75, 0x81, + 0x37, 0xe2, 0x5c, 0x3a, 0xda, 0x22, 0x19, 0xef, 0xa0, 0xff, 0x04, 0x5c, 0x44, 0xc9, 0x94, 0x71, + 0x61, 0xdb, 0xf7, 0x43, 0x5f, 0xc0, 0xc5, 0x71, 0x8d, 0xeb, 0x37, 0x29, 0x14, 0x9c, 0x1d, 0x1e, + 0x4e, 0x6c, 0xb3, 0x7e, 0xd8, 0xc2, 0xbd, 0xcf, 0x4b, 0x68, 0xad, 0x5b, 0x17, 0x9f, 0xa0, 0xb5, + 0x66, 0x62, 0x22, 0x5d, 0xf7, 0xe1, 0xd4, 0x3f, 0x26, 0x3c, 0x4e, 0x48, 0x77, 0x9e, 0x48, 0x67, + 0x82, 0xea, 0xa6, 0xec, 0xad, 0x6d, 0x3d, 0x1c, 0x24, 0x37, 0x00, 0xbf, 0x47, 0x1b, 0xf5, 0x00, + 0x83, 0xd0, 0xa5, 0x76, 0x25, 0x9b, 0xbe, 0xc8, 0x5f, 0x4b, 0xb6, 0xb4, 0xa6, 0xea, 0x7a, 0x72, + 0x0b, 0xe3, 0x13, 0xb4, 0xc1, 0x05, 0x37, 0x9c, 0xe5, 0x51, 0xc5, 0xf2, 0x48, 0x83, 0x19, 0xf6, + 0x47, 0xfd, 0xf1, 0xe0, 0x60, 0xd4, 0xad, 0x53, 0x2f, 0x06, 0x39, 0x63, 0x39, 0x4f, 0x99, 0x91, + 0xea, 0x5d, 0x91, 0x32, 0x03, 0xce, 0xbb, 0xff, 0x1d, 0xfd, 0x8c, 0xe5, 0x13, 0x30, 0x47, 0x2f, + 0x2e, 0xaf, 0x03, 0xef, 0xea, 0x3a, 0xf0, 0x7e, 0x5d, 0x07, 0xde, 0x97, 0x79, 0xd0, 0xbb, 0x9a, + 0x07, 0xbd, 0xef, 0xf3, 0xa0, 0xf7, 0xe1, 0x51, 0xc6, 0xcd, 0xb4, 0x8c, 0x49, 0x22, 0x67, 0x94, + 0xe5, 0x39, 0x17, 0x31, 0x37, 0x9a, 0xda, 0x2d, 0xfd, 0xd8, 0x7c, 0xec, 0xe6, 0xc5, 0x2b, 0x76, + 0x72, 0x9e, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x7b, 0x1a, 0x0c, 0xc1, 0x03, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { @@ -386,13 +370,6 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x2a - } if m.PreVAAS { i-- if m.PreVAAS { @@ -543,10 +520,6 @@ func (m *ConsumerGenesisState) Size() (n int) { if m.PreVAAS { n += 2 } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovSharedConsumer(uint64(l)) - } return n } @@ -869,38 +842,6 @@ func (m *ConsumerGenesisState) Unmarshal(dAtA []byte) error { } } m.PreVAAS = bool(v != 0) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) diff --git a/x/vaas/types/shared_params.go b/x/vaas/types/shared_params.go index 2429fab..57bf88e 100644 --- a/x/vaas/types/shared_params.go +++ b/x/vaas/types/shared_params.go @@ -7,8 +7,6 @@ import ( "strings" "time" - ibchost "github.com/cosmos/ibc-go/v10/modules/core/24-host" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" @@ -22,7 +20,7 @@ const ( var KeyVAASTimeoutPeriod = []byte("VaasTimeoutPeriod") -func ValidateDuration(i interface{}) error { +func ValidateDuration(i any) error { period, ok := i.(time.Duration) if !ok { return fmt.Errorf("invalid parameter type: %T", i) @@ -33,21 +31,21 @@ func ValidateDuration(i interface{}) error { return nil } -func ValidateBool(i interface{}) error { +func ValidateBool(i any) error { if _, ok := i.(bool); !ok { return fmt.Errorf("invalid parameter type: %T", i) } return nil } -func ValidateInt64(i interface{}) error { +func ValidateInt64(i any) error { if _, ok := i.(int64); !ok { return fmt.Errorf("invalid parameter type: %T", i) } return nil } -func ValidatePositiveInt64(i interface{}) error { +func ValidatePositiveInt64(i any) error { if err := ValidateInt64(i); err != nil { return err } @@ -57,40 +55,14 @@ func ValidatePositiveInt64(i interface{}) error { return nil } -func ValidateString(i interface{}) error { +func ValidateString(i any) error { if _, ok := i.(string); !ok { return fmt.Errorf("invalid parameter type: %T", i) } return nil } -func ValidateDistributionTransmissionChannel(i interface{}) error { - // Accept empty string as valid, since this means a new - // distribution transmission channel will be created - if i == "" { - return nil - } - // Otherwise validate as usual for a channelID - return ValidateChannelIdentifier(i) -} - -func ValidateChannelIdentifier(i interface{}) error { - value, ok := i.(string) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - return ibchost.ChannelIdentifierValidator(value) -} - -func ValidateConnectionIdentifier(connId string) error { - // accept empty string as valid - if strings.TrimSpace(connId) == "" { - return nil - } - return ibchost.ConnectionIdentifierValidator(connId) -} - -func ValidateAccAddress(i interface{}) error { +func ValidateAccAddress(i any) error { value, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) @@ -99,7 +71,7 @@ func ValidateAccAddress(i interface{}) error { return err } -func ValidateStringFraction(i interface{}) error { +func ValidateStringFraction(i any) error { str, ok := i.(string) if !ok { return fmt.Errorf("invalid parameter type: %T", i) @@ -117,7 +89,7 @@ func ValidateStringFraction(i interface{}) error { return nil } -func ValidateStringFractionNonZero(i interface{}) error { +func ValidateStringFractionNonZero(i any) error { if err := ValidateStringFraction(i); err != nil { return err } diff --git a/x/vaas/types/shared_params_test.go b/x/vaas/types/shared_params_test.go index f77ffbb..9f08dee 100644 --- a/x/vaas/types/shared_params_test.go +++ b/x/vaas/types/shared_params_test.go @@ -21,51 +21,3 @@ func TestValidateConsumerId(t *testing.T) { require.NoError(t, types.ValidateConsumerId("0")) require.NoError(t, types.ValidateConsumerId("18446744073709551615")) // 2^64 - 1 } - -func TestValidateConnectionIdentifier(t *testing.T) { - testCases := []struct { - name string - connId string - expPass bool - }{ - { - name: "valid connection ID", - connId: "connection-0", - expPass: true, - }, - { - name: "valid empty connection ID", - connId: "", - expPass: true, - }, - { - name: "valid empty (multiple spaces) connection ID", - connId: " ", - expPass: true, - }, - { - name: "invalid connection ID with /", - connId: "invalid-connection-id/", - expPass: false, - }, - { - name: "invalid connection ID with special characters", - connId: "connection-@#", - expPass: false, - }, - { - name: "invalid connection ID with spaces", - connId: "connection id", - expPass: false, - }, - } - - for _, tc := range testCases { - err := types.ValidateConnectionIdentifier(tc.connId) - if tc.expPass { - require.NoError(t, err, "valid case: '%s' should not return error. got %w", tc.name, err) - } else { - require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name) - } - } -} diff --git a/x/vaas/types/utils.go b/x/vaas/types/utils.go index 5dbd677..e487c78 100644 --- a/x/vaas/types/utils.go +++ b/x/vaas/types/utils.go @@ -5,16 +5,10 @@ import ( "reflect" "sort" "strings" - "time" abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v10/modules/core/04-channel/types" - - errorsmod "cosmossdk.io/errors" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" @@ -24,11 +18,11 @@ import ( func AccumulateChanges(currentChanges, newChanges []abci.ValidatorUpdate) []abci.ValidatorUpdate { m := make(map[string]abci.ValidatorUpdate) - for i := 0; i < len(currentChanges); i++ { + for i := range currentChanges { m[currentChanges[i].PubKey.String()] = currentChanges[i] } - for i := 0; i < len(newChanges); i++ { + for i := range newChanges { m[newChanges[i].PubKey.String()] = newChanges[i] } @@ -60,37 +54,6 @@ func TMCryptoPublicKeyToConsAddr(k tmprotocrypto.PublicKey) (sdk.ConsAddress, er return sdk.GetConsAddress(sdkK), nil } -// SendIBCPacket sends an IBC packet with packetData -// over the source channelID and portID -func SendIBCPacket( - ctx sdk.Context, - channelKeeper ChannelKeeper, - sourceChannelID string, - sourcePortID string, - packetData []byte, - timeoutPeriod time.Duration, -) error { - _, ok := channelKeeper.GetChannel(ctx, sourcePortID, sourceChannelID) - if !ok { - return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", sourceChannelID) - } - - _, err := channelKeeper.SendPacket(ctx, - sourcePortID, - sourceChannelID, - clienttypes.Height{}, // timeout height disabled - uint64(ctx.BlockTime().Add(timeoutPeriod).UnixNano()), // timeout timestamp - packetData, - ) - return err -} - -func NewErrorAcknowledgementWithLog(ctx sdk.Context, err error) channeltypes.Acknowledgement { - ctx.Logger().Error("IBC ErrorAcknowledgement constructed", "error", err) - return channeltypes.NewErrorAcknowledgement(err) -} - -// AppendMany appends a variable number of byte slices together func AppendMany(byteses ...[]byte) (out []byte) { for _, bytes := range byteses { out = append(out, bytes...) @@ -98,7 +61,7 @@ func AppendMany(byteses ...[]byte) (out []byte) { return out } -func PanicIfZeroOrNil(x interface{}, nameForPanicMsg string) { +func PanicIfZeroOrNil(x any, nameForPanicMsg string) { if x == nil || reflect.ValueOf(x).IsZero() { panic("zero or nil value for " + nameForPanicMsg) } diff --git a/x/vaas/types/wire.pb.go b/x/vaas/types/wire.pb.go index f2f8600..cc187bd 100644 --- a/x/vaas/types/wire.pb.go +++ b/x/vaas/types/wire.pb.go @@ -27,9 +27,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // This packet is sent from provider chain to consumer chain if the validator // set for consumer chain changes (due to new bonding/unbonding messages or -// slashing events) A VSCMatured packet from consumer chain will be sent -// asynchronously once unbonding period is over, and this will function as -// `UnbondingOver` message for this packet. +// slashing events). type ValidatorSetChangePacketData struct { ValidatorUpdates []types.ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates" yaml:"validator_updates"` ValsetUpdateId uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` @@ -82,82 +80,33 @@ func (m *ValidatorSetChangePacketData) GetValsetUpdateId() uint64 { return 0 } -// Note this type is used during IBC handshake methods for both the consumer and -// provider -type HandshakeMetadata struct { - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` -} - -func (m *HandshakeMetadata) Reset() { *m = HandshakeMetadata{} } -func (m *HandshakeMetadata) String() string { return proto.CompactTextString(m) } -func (*HandshakeMetadata) ProtoMessage() {} -func (*HandshakeMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_17a432f87dfb1130, []int{1} -} -func (m *HandshakeMetadata) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HandshakeMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_HandshakeMetadata.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *HandshakeMetadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_HandshakeMetadata.Merge(m, src) -} -func (m *HandshakeMetadata) XXX_Size() int { - return m.Size() -} -func (m *HandshakeMetadata) XXX_DiscardUnknown() { - xxx_messageInfo_HandshakeMetadata.DiscardUnknown(m) -} - -var xxx_messageInfo_HandshakeMetadata proto.InternalMessageInfo - -func (m *HandshakeMetadata) GetVersion() string { - if m != nil { - return m.Version - } - return "" -} - func init() { proto.RegisterType((*ValidatorSetChangePacketData)(nil), "vaas.v1.ValidatorSetChangePacketData") - proto.RegisterType((*HandshakeMetadata)(nil), "vaas.v1.HandshakeMetadata") } func init() { proto.RegisterFile("vaas/v1/wire.proto", fileDescriptor_17a432f87dfb1130) } var fileDescriptor_17a432f87dfb1130 = []byte{ - // 331 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xc1, 0x4a, 0xeb, 0x40, - 0x14, 0x86, 0x33, 0xf7, 0x5e, 0x6e, 0x31, 0x82, 0xd8, 0xe0, 0x22, 0x54, 0x49, 0x43, 0x10, 0xc9, - 0xc6, 0x0c, 0xd1, 0x9d, 0x2b, 0xa9, 0x2e, 0x74, 0x21, 0x48, 0x45, 0x17, 0x6e, 0xca, 0x49, 0x66, - 0x48, 0x87, 0x26, 0x33, 0x25, 0x73, 0x3a, 0xda, 0xb7, 0xf0, 0x75, 0x7c, 0x83, 0x2e, 0xbb, 0x74, - 0x55, 0xa4, 0x7d, 0x03, 0x9f, 0x40, 0x92, 0xb4, 0x8a, 0xb8, 0x9a, 0x73, 0xfe, 0xf3, 0xcd, 0xc7, - 0x70, 0xc6, 0x76, 0x0c, 0x80, 0xa6, 0x26, 0xa6, 0x4f, 0xa2, 0xe4, 0xd1, 0xb8, 0x54, 0xa8, 0x9c, - 0x56, 0x95, 0x45, 0x26, 0xee, 0x1c, 0xa6, 0x4a, 0x17, 0x4a, 0x53, 0x8d, 0x30, 0x12, 0x32, 0xa3, - 0x26, 0x4e, 0x38, 0x42, 0xbc, 0xe9, 0x1b, 0xbc, 0xb3, 0x97, 0xa9, 0x4c, 0xd5, 0x25, 0xad, 0xaa, - 0x75, 0xba, 0x8f, 0x5c, 0x32, 0x5e, 0x16, 0x42, 0x22, 0x85, 0x24, 0x15, 0x14, 0xa7, 0x63, 0xae, - 0x9b, 0x61, 0xf0, 0x4a, 0xec, 0x83, 0x07, 0xc8, 0x05, 0x03, 0x54, 0xe5, 0x1d, 0xc7, 0x8b, 0x21, - 0xc8, 0x8c, 0xdf, 0x42, 0x3a, 0xe2, 0x78, 0x09, 0x08, 0x8e, 0xb2, 0xdb, 0x66, 0x33, 0x1f, 0x4c, - 0xc6, 0x0c, 0x90, 0x6b, 0x97, 0xf8, 0x7f, 0xc3, 0xed, 0x13, 0x3f, 0xfa, 0x36, 0x47, 0x95, 0x39, - 0xfa, 0x32, 0xdd, 0xd7, 0x60, 0xcf, 0x9f, 0x2d, 0xba, 0xd6, 0xc7, 0xa2, 0xeb, 0x4e, 0xa1, 0xc8, - 0xcf, 0x82, 0x5f, 0xa2, 0xa0, 0xbf, 0x6b, 0x7e, 0x5e, 0xd1, 0x4e, 0x68, 0x57, 0x99, 0xe6, 0xb8, - 0x86, 0x06, 0x82, 0xb9, 0x7f, 0x7c, 0x12, 0xfe, 0xeb, 0xef, 0x34, 0x79, 0x03, 0x5e, 0xb3, 0xe0, - 0xd8, 0x6e, 0x5f, 0x81, 0x64, 0x7a, 0x08, 0x23, 0x7e, 0xc3, 0x11, 0x58, 0xf5, 0x5e, 0xd7, 0x6e, - 0x19, 0x5e, 0x6a, 0xa1, 0xa4, 0x4b, 0x7c, 0x12, 0x6e, 0xf5, 0x37, 0x6d, 0xef, 0x7c, 0xb6, 0xf4, - 0xc8, 0x7c, 0xe9, 0x91, 0xf7, 0xa5, 0x47, 0x5e, 0x56, 0x9e, 0x35, 0x5f, 0x79, 0xd6, 0xdb, 0xca, - 0xb3, 0x1e, 0x8f, 0x32, 0x81, 0xc3, 0x49, 0x12, 0xa5, 0xaa, 0xa0, 0x90, 0xe7, 0x42, 0x26, 0x02, - 0x35, 0xad, 0xff, 0xe3, 0xb9, 0x39, 0xea, 0x95, 0x25, 0xff, 0xeb, 0x9d, 0x9d, 0x7e, 0x06, 0x00, - 0x00, 0xff, 0xff, 0x73, 0x98, 0x5b, 0x75, 0xab, 0x01, 0x00, 0x00, + // 296 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x41, 0x4a, 0xc3, 0x40, + 0x14, 0x86, 0x33, 0x2a, 0x0a, 0x11, 0x44, 0x83, 0x8b, 0x52, 0x65, 0x1a, 0x82, 0x48, 0x56, 0x33, + 0x44, 0x77, 0xae, 0xa4, 0xba, 0x71, 0x27, 0x15, 0x5d, 0xb8, 0x29, 0x2f, 0xc9, 0x90, 0x0e, 0x4d, + 0x32, 0x21, 0xf3, 0x3a, 0xda, 0x5b, 0x78, 0x1d, 0x6f, 0xd0, 0x65, 0x97, 0xae, 0x8a, 0x24, 0x37, + 0xf0, 0x04, 0x92, 0xa4, 0x55, 0xc4, 0xd5, 0xbc, 0xf9, 0xdf, 0xf7, 0xbe, 0xc5, 0x6f, 0x3b, 0x06, + 0x40, 0x73, 0x13, 0xf0, 0x17, 0x59, 0x0a, 0x56, 0x94, 0x0a, 0x95, 0xb3, 0xd7, 0x64, 0xcc, 0x04, + 0xfd, 0xb3, 0x48, 0xe9, 0x4c, 0x69, 0xae, 0x11, 0xa6, 0x32, 0x4f, 0xb8, 0x09, 0x42, 0x81, 0x10, + 0x6c, 0xfe, 0x1d, 0xde, 0x3f, 0x4e, 0x54, 0xa2, 0xda, 0x91, 0x37, 0xd3, 0x3a, 0x3d, 0x41, 0x91, + 0xc7, 0xa2, 0xcc, 0x64, 0x8e, 0x1c, 0xc2, 0x48, 0x72, 0x9c, 0x17, 0x42, 0x77, 0x4b, 0xef, 0x9d, + 0xd8, 0xa7, 0x4f, 0x90, 0xca, 0x18, 0x50, 0x95, 0x0f, 0x02, 0x6f, 0x26, 0x90, 0x27, 0xe2, 0x1e, + 0xa2, 0xa9, 0xc0, 0x5b, 0x40, 0x70, 0x94, 0x7d, 0x64, 0x36, 0xfb, 0xf1, 0xac, 0x88, 0x01, 0x85, + 0xee, 0x11, 0x77, 0xdb, 0xdf, 0xbf, 0x70, 0xd9, 0xaf, 0x99, 0x35, 0x66, 0xf6, 0x63, 0x7a, 0x6c, + 0xc1, 0xa1, 0xbb, 0x58, 0x0d, 0xac, 0xaf, 0xd5, 0xa0, 0x37, 0x87, 0x2c, 0xbd, 0xf2, 0xfe, 0x89, + 0xbc, 0xd1, 0xa1, 0xf9, 0x7b, 0xa2, 0x1d, 0xdf, 0x6e, 0x32, 0x2d, 0x70, 0x0d, 0x8d, 0x65, 0xdc, + 0xdb, 0x72, 0x89, 0xbf, 0x33, 0x3a, 0xe8, 0xf2, 0x0e, 0xbc, 0x8b, 0x87, 0xd7, 0x8b, 0x8a, 0x92, + 0x65, 0x45, 0xc9, 0x67, 0x45, 0xc9, 0x5b, 0x4d, 0xad, 0x65, 0x4d, 0xad, 0x8f, 0x9a, 0x5a, 0xcf, + 0xe7, 0x89, 0xc4, 0xc9, 0x2c, 0x64, 0x91, 0xca, 0x38, 0xa4, 0xa9, 0xcc, 0x43, 0x89, 0x9a, 0xb7, + 0x05, 0xbf, 0x76, 0x4f, 0xdb, 0x41, 0xb8, 0xdb, 0x96, 0x70, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, + 0x97, 0x0b, 0xce, 0x58, 0x7c, 0x01, 0x00, 0x00, } func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { @@ -202,36 +151,6 @@ func (m *ValidatorSetChangePacketData) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } -func (m *HandshakeMetadata) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HandshakeMetadata) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HandshakeMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Version) > 0 { - i -= len(m.Version) - copy(dAtA[i:], m.Version) - i = encodeVarintWire(dAtA, i, uint64(len(m.Version))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func encodeVarintWire(dAtA []byte, offset int, v uint64) int { offset -= sovWire(v) base := offset @@ -261,19 +180,6 @@ func (m *ValidatorSetChangePacketData) Size() (n int) { return n } -func (m *HandshakeMetadata) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Version) - if l > 0 { - n += 1 + l + sovWire(uint64(l)) - } - return n -} - func sovWire(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -383,88 +289,6 @@ func (m *ValidatorSetChangePacketData) Unmarshal(dAtA []byte) error { } return nil } -func (m *HandshakeMetadata) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowWire - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: HandshakeMetadata: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HandshakeMetadata: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowWire - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthWire - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthWire - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipWire(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthWire - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipWire(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0