From 6b9eb98ea3a9127a3ac346a28df91e6141efa72c Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Thu, 4 Jun 2026 20:41:37 +0200 Subject: [PATCH 1/6] lock fee denom at keeper wiring --- app/provider/app.go | 2 + proto/vaas/provider/v1/provider.proto | 15 +- testutil/keeper/unit_test_helpers.go | 1 + x/vaas/provider/keeper/fee_denom_test.go | 48 ++++ x/vaas/provider/keeper/fees_test.go | 42 +-- x/vaas/provider/keeper/grpc_query.go | 2 +- x/vaas/provider/keeper/grpc_query_test.go | 2 +- x/vaas/provider/keeper/keeper.go | 19 ++ x/vaas/provider/keeper/msg_server.go | 4 +- x/vaas/provider/keeper/msg_server_test.go | 4 +- x/vaas/provider/keeper/params.go | 19 +- x/vaas/provider/keeper/params_test.go | 4 +- x/vaas/provider/module_test.go | 13 +- x/vaas/provider/types/genesis.go | 2 +- x/vaas/provider/types/genesis_test.go | 7 +- x/vaas/provider/types/params.go | 25 +- x/vaas/provider/types/params_test.go | 10 +- x/vaas/provider/types/provider.pb.go | 297 +++++++++++----------- x/vaas/types/wire.pb.go | 45 ++-- 19 files changed, 314 insertions(+), 247 deletions(-) create mode 100644 x/vaas/provider/keeper/fee_denom_test.go diff --git a/app/provider/app.go b/app/provider/app.go index 402f111..6e7e194 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -398,6 +398,8 @@ func New( authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), authtypes.FeeCollectorName, + // Per-block consumer fee denom, fixed for the lifetime of the binary. + providertypes.DefaultFeesPerBlockDenom, ) govConfig := govtypes.DefaultConfig() diff --git a/proto/vaas/provider/v1/provider.proto b/proto/vaas/provider/v1/provider.proto index 4b6e1d2..19f51a3 100644 --- a/proto/vaas/provider/v1/provider.proto +++ b/proto/vaas/provider/v1/provider.proto @@ -3,7 +3,6 @@ syntax = "proto3"; package vaas.provider.v1; import "amino/amino.proto"; -import "cosmos/base/v1beta1/coin.proto"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; import "cosmos/evidence/v1beta1/evidence.proto"; @@ -38,12 +37,14 @@ message Params { // to the consensus engine on the provider. int64 max_provider_consensus_validators = 4; - // The fee charged per block for consumer chain operation. - cosmos.base.v1beta1.Coin fees_per_block = 5 [ - (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin", - (amino.encoding) = "legacy_coin", - (amino.dont_omitempty) = true, - (gogoproto.nullable) = false + // The per-block fee amount charged for consumer chain operation. The denom + // is not a parameter: it is fixed at module wiring (see Keeper.feeDenom) and + // cannot be changed without a binary upgrade. + string fees_per_block_amount = 5 [ + (cosmos_proto.scalar) = "cosmos.Int", + (gogoproto.customtype) = "cosmossdk.io/math.Int", + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true ]; } diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index 49c4567..313a846 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -113,6 +113,7 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmosvalcons"), authtypes.FeeCollectorName, + providertypes.DefaultFeesPerBlockDenom, ) } diff --git a/x/vaas/provider/keeper/fee_denom_test.go b/x/vaas/provider/keeper/fee_denom_test.go new file mode 100644 index 0000000..f669cab --- /dev/null +++ b/x/vaas/provider/keeper/fee_denom_test.go @@ -0,0 +1,48 @@ +package keeper_test + +import ( + "fmt" + "testing" + + providerkeeper "github.com/allinbits/vaas/x/vaas/provider/keeper" + "github.com/stretchr/testify/require" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" +) + +// NewKeeper fixes the per-block fee denom at construction. The guard exists so +// that GetFeesPerBlock's sdk.NewCoin(feeDenom, amount) can never panic at +// runtime: a bad denom is a wiring mistake that must fail loudly at startup +// rather than surface later as a malformed fee coin. For each rejected denom we +// assert both halves of that contract: the denom genuinely breaks coin +// construction, and NewKeeper refuses it up front. The guard is the first +// statement in NewKeeper, so nil dependencies are fine here; the valid-denom +// path is exercised by every other keeper test through the in-mem helper. +func TestNewKeeperRejectsInvalidFeeDenom(t *testing.T) { + assertRejected := func(denom string) { + require.Panicsf(t, func() { + sdk.NewCoin(denom, math.OneInt()) + }, "sanity: %q must be an invalid coin denom for the guard to be meaningful", denom) + + defer func() { + r := recover() + require.NotNilf(t, r, "expected NewKeeper to panic for fee denom %q", denom) + require.Containsf(t, fmt.Sprint(r), "fee denom", "denom %q should trip the fee-denom guard", denom) + }() + providerkeeper.NewKeeper( + nil, nil, nil, nil, nil, nil, nil, nil, nil, + govkeeper.Keeper{}, + "authority", + nil, nil, + "fee_collector", + denom, + ) + } + + for _, denom := range []string{"", "1leadingdigit", "white space"} { + assertRejected(denom) + } +} diff --git a/x/vaas/provider/keeper/fees_test.go b/x/vaas/provider/keeper/fees_test.go index 1e0957e..f64f7ec 100644 --- a/x/vaas/provider/keeper/fees_test.go +++ b/x/vaas/provider/keeper/fees_test.go @@ -34,7 +34,7 @@ func TestCollectFeesFromConsumers(t *testing.T) { feesPerBlock := sdk.NewInt64Coin("uphoton", 10) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = feesPerBlock + providerParams.FeesPerBlockAmount = feesPerBlock.Amount k.SetParams(ctx, providerParams) consumer0FeePoolAddr := k.GetConsumerFeePoolAddress(consumer0) consumer1FeePoolAddr := k.GetConsumerFeePoolAddress(consumer1) @@ -72,7 +72,7 @@ func TestCollectFeesFromConsumers_PerConsumerOverride(t *testing.T) { overrideFees := sdk.NewCoin("uphoton", overrideAmount) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = defaultFees + providerParams.FeesPerBlockAmount = defaultFees.Amount k.SetParams(ctx, providerParams) // consumer1 gets an override; consumer0 keeps the default. @@ -108,7 +108,7 @@ func TestCollectFeesFromConsumersSkipsWhenInsufficient(t *testing.T) { feesPerBlock := sdk.NewInt64Coin("uphoton", 10) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = feesPerBlock + providerParams.FeesPerBlockAmount = feesPerBlock.Amount k.SetParams(ctx, providerParams) consumer0FeePoolAddr := k.GetConsumerFeePoolAddress(consumer0) consumer1FeePoolAddr := k.GetConsumerFeePoolAddress(consumer1) @@ -139,7 +139,7 @@ func TestCollectFeesFromConsumersClearsDebtWhenRecovered(t *testing.T) { feesPerBlock := sdk.NewInt64Coin("uphoton", 10) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = feesPerBlock + providerParams.FeesPerBlockAmount = feesPerBlock.Amount k.SetParams(ctx, providerParams) consumer0FeePoolAddr := k.GetConsumerFeePoolAddress(consumer0) @@ -168,7 +168,7 @@ func TestCollectFeesFromConsumersContinuesOnGenericError(t *testing.T) { feesPerBlock := sdk.NewInt64Coin("uphoton", 10) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = feesPerBlock + providerParams.FeesPerBlockAmount = feesPerBlock.Amount k.SetParams(ctx, providerParams) consumer0FeePoolAddr := k.GetConsumerFeePoolAddress(consumer0) consumer1FeePoolAddr := k.GetConsumerFeePoolAddress(consumer1) @@ -238,12 +238,12 @@ func TestDistributeFeesToValidators(t *testing.T) { val2.Tokens = sdk.DefaultPowerReduction.MulRaw(20) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) ctx = ctx.WithVoteInfos([]abci.VoteInfo{signerVote(cons1), signerVote(cons2)}) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 300)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -265,11 +265,11 @@ func TestDistributeFeesToValidatorsZeroFees(t *testing.T) { defer ctrl.Finish() providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewCoin("uphoton", math.ZeroInt())) require.NoError(t, k.DistributeFeesToValidators(ctx)) @@ -289,12 +289,12 @@ func TestDistributeFeesToValidatorsSkipsWhenFeesTooSmall(t *testing.T) { val2, _, cons2 := newBondedValidator(t, valAddrCodec, 2) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 1) + providerParams.FeesPerBlockAmount = math.NewInt(1) k.SetParams(ctx, providerParams) ctx = ctx.WithVoteInfos([]abci.VoteInfo{signerVote(cons1), signerVote(cons2)}) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 1)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -318,12 +318,12 @@ func TestDistributeFeesToValidatorsRemainderStaysPooled(t *testing.T) { val3, op3, cons3 := newBondedValidator(t, valAddrCodec, 3) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) ctx = ctx.WithVoteInfos([]abci.VoteInfo{signerVote(cons1), signerVote(cons2), signerVote(cons3)}) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 10)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -345,11 +345,11 @@ func TestDistributeFeesToValidatorsNoSigners(t *testing.T) { defer ctrl.Finish() providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 50) + providerParams.FeesPerBlockAmount = math.NewInt(50) k.SetParams(ctx, providerParams) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 50)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -372,7 +372,7 @@ func TestDistributeFeesToValidatorsSkipsAbsentSigners(t *testing.T) { val2, _, cons2 := newBondedValidator(t, valAddrCodec, 2) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) ctx = ctx.WithVoteInfos([]abci.VoteInfo{ signerVote(cons1), // will be paid @@ -380,7 +380,7 @@ func TestDistributeFeesToValidatorsSkipsAbsentSigners(t *testing.T) { }) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 100)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -409,12 +409,12 @@ func TestDistributeFeesToValidatorsSkipsNonBondedSigner(t *testing.T) { _, _, consGone := newBondedValidator(t, valAddrCodec, 2) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) ctx = ctx.WithVoteInfos([]abci.VoteInfo{signerVote(cons1), signerVote(consGone)}) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 100)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). @@ -435,11 +435,11 @@ func TestDistributeFeesToValidatorsPropagatesBondedFetchError(t *testing.T) { defer ctrl.Finish() providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = math.NewInt(10) k.SetParams(ctx, providerParams) mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). Return(sdk.NewInt64Coin("uphoton", 100)) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). diff --git a/x/vaas/provider/keeper/grpc_query.go b/x/vaas/provider/keeper/grpc_query.go index 1750d54..bc7a19e 100644 --- a/x/vaas/provider/keeper/grpc_query.go +++ b/x/vaas/provider/keeper/grpc_query.go @@ -357,7 +357,7 @@ func (k Keeper) QueryConsumerGenesisTime(goCtx context.Context, req *types.Query } // QueryConsumerFeesPerBlock returns the effective per-block fee for the -// given consumer (override if set, else Params.FeesPerBlock). +// given consumer (override if set, else the default Params.FeesPerBlockAmount). func (k Keeper) QueryConsumerFeesPerBlock( goCtx context.Context, req *types.QueryConsumerFeesPerBlockRequest, diff --git a/x/vaas/provider/keeper/grpc_query_test.go b/x/vaas/provider/keeper/grpc_query_test.go index 1a6df99..aadf844 100644 --- a/x/vaas/provider/keeper/grpc_query_test.go +++ b/x/vaas/provider/keeper/grpc_query_test.go @@ -69,7 +69,7 @@ func TestQueryConsumerFeesPerBlock(t *testing.T) { defer ctrl.Finish() providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = defaultFees + providerParams.FeesPerBlockAmount = defaultFees.Amount k.SetParams(ctx, providerParams) consumerId := k.FetchAndIncrementConsumerId(ctx) diff --git a/x/vaas/provider/keeper/keeper.go b/x/vaas/provider/keeper/keeper.go index 4e233e0..d7a226b 100644 --- a/x/vaas/provider/keeper/keeper.go +++ b/x/vaas/provider/keeper/keeper.go @@ -41,6 +41,10 @@ type Keeper struct { bankKeeper vaastypes.BankKeeper govKeeper govkeeper.Keeper feeCollectorName string + // feeDenom is the denom charged to consumers per block. It is fixed at + // construction and cannot be changed without a binary upgrade. The amount + // is instead governed via Params.FeesPerBlockAmount. + feeDenom string validatorAddressCodec addresscodec.Codec consensusAddressCodec addresscodec.Codec @@ -94,7 +98,15 @@ func NewKeeper( authority string, validatorAddressCodec, consensusAddressCodec addresscodec.Codec, feeCollectorName string, + feeDenom string, ) Keeper { + // The per-block fee denom is fixed for the lifetime of the binary. A bad + // value is a wiring mistake that must fail loudly at startup rather than + // surface later as malformed fee coins. + if err := sdk.ValidateDenom(feeDenom); err != nil { + panic(fmt.Errorf("invalid provider fee denom %q: %w", feeDenom, err)) + } + sb := collections.NewSchemaBuilder(storeService) k := Keeper{ @@ -108,6 +120,7 @@ func NewKeeper( accountKeeper: accountKeeper, bankKeeper: bankKeeper, feeCollectorName: feeCollectorName, + feeDenom: feeDenom, validatorAddressCodec: validatorAddressCodec, consensusAddressCodec: consensusAddressCodec, channelKeeperV2: channelKeeperV2, @@ -177,6 +190,12 @@ func (k Keeper) GetAuthority() string { return k.authority } +// GetFeeDenom returns the denom charged to consumer chains per block. It is +// fixed at module wiring and immutable without a binary upgrade. +func (k Keeper) GetFeeDenom() string { + return k.feeDenom +} + // ValidatorAddressCodec returns the app validator address codec. func (k Keeper) ValidatorAddressCodec() addresscodec.Codec { return k.validatorAddressCodec diff --git a/x/vaas/provider/keeper/msg_server.go b/x/vaas/provider/keeper/msg_server.go index 5e594a3..bcd0ab6 100644 --- a/x/vaas/provider/keeper/msg_server.go +++ b/x/vaas/provider/keeper/msg_server.go @@ -55,8 +55,8 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam // Per-consumer fees_per_block overrides must stay strictly above the global // default. Only a higher floor can leave an existing override underwater; an // unchanged or lower floor keeps every override valid, so skip the walk. - if msg.Params.FeesPerBlock.Amount.GT(oldFloor) { - if err := k.reconcileFeesPerBlockOverrides(ctx, msg.Params.FeesPerBlock.Amount); err != nil { + if msg.Params.FeesPerBlockAmount.GT(oldFloor) { + if err := k.reconcileFeesPerBlockOverrides(ctx, msg.Params.FeesPerBlockAmount); err != nil { return nil, err } } diff --git a/x/vaas/provider/keeper/msg_server_test.go b/x/vaas/provider/keeper/msg_server_test.go index 6e18faa..889f7ae 100644 --- a/x/vaas/provider/keeper/msg_server_test.go +++ b/x/vaas/provider/keeper/msg_server_test.go @@ -595,7 +595,7 @@ func TestUpdateParams_ReconcilesFeesPerBlockOverrides(t *testing.T) { // Raise the global default to 2000. newParams := providertypes.DefaultParams() - newParams.FeesPerBlock = sdk.NewInt64Coin(providertypes.DefaultFeesPerBlockDenom, 2000) + newParams.FeesPerBlockAmount = math.NewInt(2000) msgSrv := providerkeeper.NewMsgServerImpl(&k) _, err := msgSrv.UpdateParams(ctx, &providertypes.MsgUpdateParams{ @@ -618,7 +618,7 @@ func TestUpdateParams_ReconcilesFeesPerBlockOverrides(t *testing.T) { // Lowering the floor never invalidates overrides: the survivor stays. lowerParams := providertypes.DefaultParams() - lowerParams.FeesPerBlock = sdk.NewInt64Coin(providertypes.DefaultFeesPerBlockDenom, 500) + lowerParams.FeesPerBlockAmount = math.NewInt(500) _, err = msgSrv.UpdateParams(ctx, &providertypes.MsgUpdateParams{ Authority: k.GetAuthority(), Params: lowerParams, diff --git a/x/vaas/provider/keeper/params.go b/x/vaas/provider/keeper/params.go index f20d0d8..92d8528 100644 --- a/x/vaas/provider/keeper/params.go +++ b/x/vaas/provider/keeper/params.go @@ -60,17 +60,18 @@ func (k Keeper) GetMaxProviderConsensusValidators(ctx context.Context) int64 { return params.MaxProviderConsensusValidators } -// GetFeesPerBlock returns the fees that each consumer chain must pay per block +// GetFeesPerBlock returns the fees that each consumer chain must pay per block. +// The amount is governed via Params.FeesPerBlockAmount while the denom is a +// keeper-wired constant and cannot be changed without a binary upgrade. func (k Keeper) GetFeesPerBlock(ctx context.Context) sdk.Coin { - params := k.GetParams(ctx) - return params.FeesPerBlock + return sdk.NewCoin(k.feeDenom, k.GetParams(ctx).FeesPerBlockAmount) } // GetEffectiveFeesPerBlock returns the per-block fee charged to a specific -// consumer: the override amount if one is set, else Params.FeesPerBlock. -// The returned Coin always carries Params.FeesPerBlock.Denom. The bool -// reports whether an override was applied (true) or the default was used -// (false). +// consumer: the override amount if one is set, else the default +// Params.FeesPerBlockAmount. The returned Coin always carries the module fee +// denom (Keeper.feeDenom). The bool reports whether an override was applied +// (true) or the default was used (false). func (k Keeper) GetEffectiveFeesPerBlock(ctx context.Context, consumerId uint64) (sdk.Coin, bool) { return k.effectiveFeesPerBlock(ctx, consumerId, k.GetFeesPerBlock(ctx)) } @@ -91,8 +92,8 @@ func (k Keeper) effectiveFeesPerBlock(ctx context.Context, consumerId uint64, de } // reconcileFeesPerBlockOverrides drops every per-consumer override that is no -// longer strictly greater than floor (the module-wide Params.FeesPerBlock -// amount). It is called when the global fees_per_block rises so the "override +// longer strictly greater than floor (the module-wide Params.FeesPerBlockAmount). +// It is called when the global fees_per_block rises so the "override // must exceed the default" floor holds as a true invariant, not just at set // time: a higher default can leave overrides underwater, and those consumers // should revert to paying the new (higher) default. diff --git a/x/vaas/provider/keeper/params_test.go b/x/vaas/provider/keeper/params_test.go index 5b07dd8..b99c60b 100644 --- a/x/vaas/provider/keeper/params_test.go +++ b/x/vaas/provider/keeper/params_test.go @@ -30,7 +30,7 @@ func TestParams(t *testing.T) { 7*24*time.Hour, 600, 10, - sdk.NewInt64Coin("uphoton", 50), + math.NewInt(50), ) providerKeeper.SetParams(ctx, newParams) params = providerKeeper.GetParams(ctx) @@ -81,7 +81,7 @@ func TestGetEffectiveFeesPerBlock(t *testing.T) { defer ctrl.Finish() providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = defaultFees + providerParams.FeesPerBlockAmount = defaultFees.Amount k.SetParams(ctx, providerParams) if !tc.overrideAmount.IsNil() { diff --git a/x/vaas/provider/module_test.go b/x/vaas/provider/module_test.go index 7d99b97..a849997 100644 --- a/x/vaas/provider/module_test.go +++ b/x/vaas/provider/module_test.go @@ -37,8 +37,9 @@ func TestBeginBlockCommitsDebtStateWhenDistributionFails(t *testing.T) { k.SetConsumerPhase(ctx, consumerInDebt, providertypes.CONSUMER_PHASE_LAUNCHED) k.SetConsumerPhase(ctx, consumerPaying, providertypes.CONSUMER_PHASE_LAUNCHED) + feesPerBlock := sdk.NewInt64Coin("uphoton", 10) providerParams := providertypes.DefaultParams() - providerParams.FeesPerBlock = sdk.NewInt64Coin("uphoton", 10) + providerParams.FeesPerBlockAmount = feesPerBlock.Amount k.SetParams(ctx, providerParams) consumerInDebtFeePoolAddr := k.GetConsumerFeePoolAddress(consumerInDebt) @@ -67,20 +68,20 @@ func TestBeginBlockCommitsDebtStateWhenDistributionFails(t *testing.T) { // Collection phase: one consumer underfunded (ErrInsufficientFunds), one pays. mocks.MockBankKeeper.EXPECT(). - SendCoinsFromAccountToModule(gomock.Any(), consumerInDebtFeePoolAddr, providertypes.ModuleName, sdk.NewCoins(providerParams.FeesPerBlock)). + SendCoinsFromAccountToModule(gomock.Any(), consumerInDebtFeePoolAddr, providertypes.ModuleName, sdk.NewCoins(feesPerBlock)). Return(sdkerrors.ErrInsufficientFunds.Wrapf("spendable 5 < 10")) mocks.MockBankKeeper.EXPECT(). - SendCoinsFromAccountToModule(gomock.Any(), consumerPayingFeePoolAddr, providertypes.ModuleName, sdk.NewCoins(providerParams.FeesPerBlock)). + SendCoinsFromAccountToModule(gomock.Any(), consumerPayingFeePoolAddr, providertypes.ModuleName, sdk.NewCoins(feesPerBlock)). Return(nil) // Distribution phase: bank send errors out, rolls back distribution only. mocks.MockBankKeeper.EXPECT(). - GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providerParams.FeesPerBlock.Denom). - Return(providerParams.FeesPerBlock) + GetBalance(gomock.Any(), authtypes.NewModuleAddress(providertypes.ModuleName), providertypes.DefaultFeesPerBlockDenom). + Return(feesPerBlock) mocks.MockStakingKeeper.EXPECT(). GetBondedValidatorsByPower(gomock.Any()). Return([]stakingtypes.Validator{val}, nil) mocks.MockBankKeeper.EXPECT(). - SendCoinsFromModuleToAccount(gomock.Any(), providertypes.ModuleName, sdk.AccAddress(opBytes), sdk.NewCoins(providerParams.FeesPerBlock)). + SendCoinsFromModuleToAccount(gomock.Any(), providertypes.ModuleName, sdk.AccAddress(opBytes), sdk.NewCoins(feesPerBlock)). Return(errors.New("distribution boom")) require.NoError(t, appModule.BeginBlock(sdk.WrapSDKContext(ctx))) diff --git a/x/vaas/provider/types/genesis.go b/x/vaas/provider/types/genesis.go index 4179c82..cfd5f64 100644 --- a/x/vaas/provider/types/genesis.go +++ b/x/vaas/provider/types/genesis.go @@ -86,7 +86,7 @@ func (gs GenesisState) Validate() error { // Overrides must reference a known consumer and stay strictly above the // module-wide fees_per_block floor (the same invariant the msg handler and // UpdateParams reconciliation enforce at runtime). - floor := gs.Params.FeesPerBlock.Amount + floor := gs.Params.FeesPerBlockAmount for _, ov := range gs.ConsumerFeesPerBlockOverrides { amt, ok := math.NewIntFromString(ov.Amount) if !ok { diff --git a/x/vaas/provider/types/genesis_test.go b/x/vaas/provider/types/genesis_test.go index 3be234b..fc5e142 100644 --- a/x/vaas/provider/types/genesis_test.go +++ b/x/vaas/provider/types/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "cosmossdk.io/math" "github.com/allinbits/vaas/testutil/crypto" "github.com/allinbits/vaas/x/vaas/provider/types" vaastypes "github.com/allinbits/vaas/x/vaas/types" @@ -83,7 +84,7 @@ func TestValidateGenesisState(t *testing.T) { nil, []types.ConsumerState{launchedCS(0, "chainid-1", "client-id", false)}, types.NewParams( - types.DefaultTrustingPeriodFraction, time.Hour, 600, 180, sdk.NewInt64Coin("uphoton", 42)), + types.DefaultTrustingPeriodFraction, time.Hour, 600, 180, math.NewInt(42)), nil, nil, nil, @@ -127,7 +128,7 @@ func TestValidateGenesisState(t *testing.T) { []types.ConsumerState{launchedCS(0, "chainid-1", "client-id", false)}, types.NewParams( "0.0", // 0 trusting period fraction here - vaastypes.DefaultVAASTimeoutPeriod, 600, 180, sdk.NewInt64Coin("uphoton", 42)), + vaastypes.DefaultVAASTimeoutPeriod, 600, 180, math.NewInt(42)), nil, nil, nil, @@ -144,7 +145,7 @@ func TestValidateGenesisState(t *testing.T) { types.NewParams( types.DefaultTrustingPeriodFraction, 0, // 0 ccv timeout here - 600, 180, sdk.NewInt64Coin("uphoton", 42)), + 600, 180, math.NewInt(42)), nil, nil, nil, diff --git a/x/vaas/provider/types/params.go b/x/vaas/provider/types/params.go index 3173d92..67afbb0 100644 --- a/x/vaas/provider/types/params.go +++ b/x/vaas/provider/types/params.go @@ -9,8 +9,6 @@ import ( clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -31,7 +29,10 @@ const ( // be passed on from the staking module to the consensus engine on the provider. DefaultMaxProviderConsensusValidators = 180 - // DefaultFeesPerBlockDenom is the base denom charged to each consumer chain per block. + // DefaultFeesPerBlockDenom is the denom charged to each consumer chain per + // block. It is not a module parameter: it is wired into the keeper at app + // construction (Keeper.feeDenom) and cannot be changed without a binary + // upgrade. The atomone hub wires photontypes.Denom here. DefaultFeesPerBlockDenom = "uphoton" // DefaultFeesPerBlockAmount is the default amount (in DefaultFeesPerBlockDenom) charged per block. @@ -50,14 +51,14 @@ func NewParams( vaasTimeoutPeriod time.Duration, blocksPerEpoch int64, maxProviderConsensusValidators int64, - feesPerBlock sdk.Coin, + feesPerBlockAmount math.Int, ) Params { return Params{ TrustingPeriodFraction: trustingPeriodFraction, VaasTimeoutPeriod: vaasTimeoutPeriod, BlocksPerEpoch: blocksPerEpoch, MaxProviderConsensusValidators: maxProviderConsensusValidators, - FeesPerBlock: feesPerBlock, + FeesPerBlockAmount: feesPerBlockAmount, } } @@ -67,7 +68,7 @@ func DefaultParams() Params { vaastypes.DefaultVAASTimeoutPeriod, DefaultBlocksPerEpoch, DefaultMaxProviderConsensusValidators, - sdk.NewInt64Coin(DefaultFeesPerBlockDenom, DefaultFeesPerBlockAmount), + math.NewInt(DefaultFeesPerBlockAmount), ) } @@ -146,19 +147,19 @@ func (p Params) Validate() error { if err := vaastypes.ValidatePositiveInt64(p.MaxProviderConsensusValidators); err != nil { return fmt.Errorf("max provider consensus validators is invalid: %s", err) } - if err := validateFeesPerBlock(p.FeesPerBlock); err != nil { + if err := validateFeesPerBlockAmount(p.FeesPerBlockAmount); err != nil { return err } return nil } -func validateFeesPerBlock(coin sdk.Coin) error { - if !coin.IsValid() { - return fmt.Errorf("fees per block coin is invalid: %s", coin) +func validateFeesPerBlockAmount(amount math.Int) error { + if amount.IsNil() { + return fmt.Errorf("fees per block amount must be set") } - if coin.IsZero() { - return fmt.Errorf("fees per block must be positive") + if !amount.IsPositive() { + return fmt.Errorf("fees per block amount must be positive") } return nil } diff --git a/x/vaas/provider/types/params_test.go b/x/vaas/provider/types/params_test.go index a3a88a7..449b283 100644 --- a/x/vaas/provider/types/params_test.go +++ b/x/vaas/provider/types/params_test.go @@ -7,7 +7,7 @@ import ( "github.com/allinbits/vaas/x/vaas/provider/types" "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" + "cosmossdk.io/math" ) func TestValidateParams(t *testing.T) { @@ -17,12 +17,12 @@ func TestValidateParams(t *testing.T) { expPass bool }{ {"default params", types.DefaultParams(), true}, - {"custom valid params", types.NewParams("0.33", time.Hour, 1000, 180, sdk.NewInt64Coin("uphoton", 42)), true}, - {"zero fees per block", types.NewParams("0.33", time.Hour, 1000, 180, sdk.NewInt64Coin("uphoton", 0)), false}, + {"custom valid params", types.NewParams("0.33", time.Hour, 1000, 180, math.NewInt(42)), true}, + {"zero fees per block", types.NewParams("0.33", time.Hour, 1000, 180, math.NewInt(0)), false}, {"0 trusting period fraction", types.NewParams( - "0.00", time.Hour, 1000, 180, sdk.NewInt64Coin("uphoton", 1)), false}, + "0.00", time.Hour, 1000, 180, math.NewInt(1)), false}, {"0 ccv timeout period", types.NewParams( - "0.33", 0, 1000, 180, sdk.NewInt64Coin("uphoton", 1)), false}, + "0.33", 0, 1000, 180, math.NewInt(1)), false}, } for _, tc := range testCases { diff --git a/x/vaas/provider/types/provider.pb.go b/x/vaas/provider/types/provider.pb.go index 74d51d0..0096a7e 100644 --- a/x/vaas/provider/types/provider.pb.go +++ b/x/vaas/provider/types/provider.pb.go @@ -7,16 +7,14 @@ import ( cosmossdk_io_math "cosmossdk.io/math" _ "cosmossdk.io/x/evidence/types" fmt "fmt" - types1 "github.com/allinbits/vaas/x/vaas/types" + types "github.com/allinbits/vaas/x/vaas/types" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/cosmos-proto" - _ "github.com/cosmos/cosmos-sdk/types" - github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - types2 "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + types1 "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" _ "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" @@ -99,8 +97,10 @@ type Params struct { // The maximal number of validators that will be passed // to the consensus engine on the provider. MaxProviderConsensusValidators int64 `protobuf:"varint,4,opt,name=max_provider_consensus_validators,json=maxProviderConsensusValidators,proto3" json:"max_provider_consensus_validators,omitempty"` - // The fee charged per block for consumer chain operation. - FeesPerBlock github_com_cosmos_cosmos_sdk_types.Coin `protobuf:"bytes,5,opt,name=fees_per_block,json=feesPerBlock,proto3,casttype=github.com/cosmos/cosmos-sdk/types.Coin" json:"fees_per_block"` + // The per-block fee amount charged for consumer chain operation. The denom + // is not a parameter: it is fixed at module wiring (see Keeper.feeDenom) and + // cannot be changed without a binary upgrade. + FeesPerBlockAmount cosmossdk_io_math.Int `protobuf:"bytes,5,opt,name=fees_per_block_amount,json=feesPerBlockAmount,proto3,customtype=cosmossdk.io/math.Int" json:"fees_per_block_amount"` } func (m *Params) Reset() { *m = Params{} } @@ -164,13 +164,6 @@ func (m *Params) GetMaxProviderConsensusValidators() int64 { return 0 } -func (m *Params) GetFeesPerBlock() github_com_cosmos_cosmos_sdk_types.Coin { - if m != nil { - return m.FeesPerBlock - } - return github_com_cosmos_cosmos_sdk_types.Coin{} -} - // AddressList contains a list of consensus addresses type AddressList struct { Addresses [][]byte `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` @@ -218,7 +211,7 @@ func (m *AddressList) GetAddresses() [][]byte { // ValidatorSetChangePackets is a pb list of ccv.ValidatorSetChangePacketData. type ValidatorSetChangePackets struct { - List []types1.ValidatorSetChangePacketData `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` + List []types.ValidatorSetChangePacketData `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` } func (m *ValidatorSetChangePackets) Reset() { *m = ValidatorSetChangePackets{} } @@ -254,7 +247,7 @@ func (m *ValidatorSetChangePackets) XXX_DiscardUnknown() { var xxx_messageInfo_ValidatorSetChangePackets proto.InternalMessageInfo -func (m *ValidatorSetChangePackets) GetList() []types1.ValidatorSetChangePacketData { +func (m *ValidatorSetChangePackets) GetList() []types.ValidatorSetChangePacketData { if m != nil { return m.List } @@ -661,7 +654,7 @@ type ConsumerInitializationParameters struct { // the proposed initial height of new consumer chain. // For a completely new chain, this will be {0,1}. However, it may be // different if this is a chain that is converting to a consumer chain. - InitialHeight types2.Height `protobuf:"bytes,1,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height"` + InitialHeight types1.Height `protobuf:"bytes,1,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height"` // The hash of the consumer chain genesis state without the consumer VAAS // module genesis params. It is used for off-chain confirmation of // genesis.json validity by validators and other parties. @@ -718,11 +711,11 @@ func (m *ConsumerInitializationParameters) XXX_DiscardUnknown() { var xxx_messageInfo_ConsumerInitializationParameters proto.InternalMessageInfo -func (m *ConsumerInitializationParameters) GetInitialHeight() types2.Height { +func (m *ConsumerInitializationParameters) GetInitialHeight() types1.Height { if m != nil { return m.InitialHeight } - return types2.Height{} + return types1.Height{} } func (m *ConsumerInitializationParameters) GetGenesisHash() []byte { @@ -940,95 +933,92 @@ func init() { func init() { proto.RegisterFile("vaas/provider/v1/provider.proto", fileDescriptor_6404dd5d21545279) } var fileDescriptor_6404dd5d21545279 = []byte{ - // 1400 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6f, 0xdb, 0x46, - 0x16, 0x37, 0x2d, 0x25, 0xb1, 0x47, 0xb2, 0x57, 0x99, 0x18, 0x89, 0xec, 0x24, 0x92, 0xa3, 0x45, - 0x76, 0x8d, 0xec, 0x86, 0x84, 0x52, 0xa0, 0x28, 0xda, 0x43, 0x60, 0x49, 0x4c, 0xac, 0xda, 0x71, - 0x04, 0x4a, 0xe9, 0x21, 0x68, 0x41, 0x0c, 0xc9, 0x89, 0x34, 0x31, 0xc9, 0x21, 0x38, 0x23, 0x39, - 0xea, 0xb9, 0x05, 0x7a, 0x4c, 0x81, 0x1e, 0x8a, 0x9e, 0x5a, 0xf4, 0xd2, 0x63, 0x0e, 0x45, 0x8f, - 0x3d, 0xa7, 0xb7, 0xa0, 0xa7, 0xa2, 0x28, 0xd2, 0x22, 0x39, 0xe4, 0x7f, 0xe8, 0xa9, 0x98, 0xe1, - 0x90, 0xa2, 0x3f, 0x82, 0x3a, 0xe8, 0x45, 0xe2, 0xfc, 0xde, 0xfb, 0xcd, 0xfb, 0x98, 0x37, 0xef, - 0x0d, 0xa8, 0x4f, 0x10, 0x62, 0x46, 0x14, 0xd3, 0x09, 0xf1, 0x70, 0x6c, 0x4c, 0x9a, 0xd9, 0xb7, - 0x1e, 0xc5, 0x94, 0x53, 0x58, 0x11, 0x0a, 0x7a, 0x06, 0x4e, 0x9a, 0x6b, 0x67, 0x51, 0x40, 0x42, - 0x6a, 0xc8, 0xdf, 0x44, 0x69, 0xad, 0xe6, 0x52, 0x16, 0x50, 0x66, 0x38, 0x88, 0x61, 0x63, 0xd2, - 0x74, 0x30, 0x47, 0x4d, 0xc3, 0xa5, 0x24, 0x54, 0xf2, 0xd5, 0x44, 0x6e, 0xcb, 0x95, 0x91, 0x2c, - 0x94, 0x68, 0x65, 0x48, 0x87, 0x34, 0xc1, 0xc5, 0x97, 0x42, 0xff, 0xa3, 0x36, 0xc4, 0xc2, 0x6a, - 0xe8, 0xce, 0x36, 0x4d, 0x81, 0xd4, 0xf0, 0x90, 0xd2, 0xa1, 0x8f, 0x0d, 0xb9, 0x72, 0xc6, 0x0f, - 0x0c, 0x6f, 0x1c, 0x23, 0x4e, 0x68, 0x6a, 0xb8, 0x7e, 0x58, 0xce, 0x49, 0x80, 0x19, 0x47, 0x41, - 0x94, 0x2a, 0x10, 0xc7, 0x35, 0x5c, 0x1a, 0x63, 0xc3, 0xf5, 0x09, 0x0e, 0xb9, 0xc8, 0x40, 0xf2, - 0xa5, 0x14, 0x0c, 0xa1, 0xe0, 0x93, 0xe1, 0x88, 0x27, 0x30, 0x33, 0x38, 0x0e, 0x3d, 0x1c, 0x07, - 0x24, 0x51, 0x9e, 0xad, 0x14, 0x01, 0xca, 0x8c, 0x4e, 0x9a, 0xc6, 0x3e, 0x89, 0x53, 0x37, 0x2f, - 0xe5, 0x38, 0x6e, 0x3c, 0x8d, 0x38, 0x35, 0xf6, 0xf0, 0x54, 0xa5, 0xa0, 0xf1, 0x45, 0x01, 0x9c, - 0xee, 0xa1, 0x18, 0x05, 0x0c, 0xbe, 0x03, 0xaa, 0x3c, 0x1e, 0x33, 0x4e, 0xc2, 0xa1, 0x1d, 0xe1, - 0x98, 0x50, 0xcf, 0x7e, 0x10, 0x23, 0x57, 0x44, 0x54, 0xd5, 0xd6, 0xb5, 0x8d, 0x45, 0xeb, 0x7c, - 0x2a, 0xef, 0x49, 0xf1, 0x2d, 0x25, 0x85, 0x7d, 0x70, 0x4e, 0x18, 0xb6, 0x45, 0x80, 0x74, 0xcc, - 0x15, 0xbb, 0x3a, 0xbf, 0xae, 0x6d, 0x94, 0x6e, 0xac, 0xea, 0x49, 0x1e, 0xf4, 0x34, 0x0f, 0x7a, - 0x47, 0xe5, 0xa9, 0xb5, 0xf0, 0xf4, 0x79, 0x7d, 0xee, 0xcb, 0xdf, 0xeb, 0x9a, 0x75, 0x56, 0xf0, - 0x07, 0x09, 0x3d, 0xd9, 0x1c, 0x6e, 0x80, 0x8a, 0xe3, 0x53, 0x77, 0x8f, 0x89, 0xed, 0x6c, 0x1c, - 0x51, 0x77, 0x54, 0x2d, 0xac, 0x6b, 0x1b, 0x05, 0x6b, 0x39, 0xc1, 0x7b, 0x38, 0x36, 0x05, 0x0a, - 0xbb, 0xe0, 0x4a, 0x80, 0x1e, 0xd9, 0x69, 0x9d, 0xd8, 0x2e, 0x0d, 0x19, 0x0e, 0xd9, 0x98, 0xd9, - 0x13, 0xe4, 0x13, 0x0f, 0x71, 0x1a, 0xb3, 0x6a, 0x51, 0x52, 0x6b, 0x01, 0x7a, 0xd4, 0x53, 0x7a, - 0xed, 0x54, 0xed, 0x83, 0x4c, 0x0b, 0x7e, 0xaa, 0x81, 0xe5, 0x07, 0x18, 0x27, 0x36, 0xa5, 0x99, - 0xea, 0x29, 0x15, 0x85, 0xaa, 0x1c, 0x51, 0x66, 0xba, 0xaa, 0x08, 0xbd, 0x4d, 0x49, 0xd8, 0xea, - 0x88, 0x28, 0xfe, 0x7c, 0x5e, 0xff, 0xef, 0x90, 0xf0, 0xd1, 0xd8, 0xd1, 0x5d, 0x1a, 0xa8, 0x32, - 0x53, 0x7f, 0xd7, 0x99, 0xb7, 0x67, 0xf0, 0x69, 0x84, 0x99, 0x24, 0x7c, 0xf5, 0xea, 0xc9, 0xb5, - 0x92, 0x8f, 0x87, 0xc8, 0x9d, 0xda, 0xa2, 0x4e, 0xbf, 0x7b, 0xf5, 0xe4, 0x9a, 0x66, 0x95, 0x85, - 0xd9, 0x1e, 0x8e, 0x5b, 0xc2, 0x68, 0xe3, 0x7f, 0xa0, 0xb4, 0xe9, 0x79, 0x31, 0x66, 0x6c, 0x87, - 0x30, 0x0e, 0x2f, 0x81, 0x45, 0x94, 0x2c, 0x31, 0xab, 0x6a, 0xeb, 0x85, 0x8d, 0xb2, 0x35, 0x03, - 0x1a, 0x1f, 0x82, 0xd5, 0x2c, 0x84, 0x3e, 0xe6, 0xed, 0x11, 0x0a, 0x87, 0xb8, 0x87, 0xdc, 0x3d, - 0xcc, 0x19, 0xbc, 0x09, 0x8a, 0x3e, 0x61, 0x5c, 0xb2, 0x4a, 0x37, 0xae, 0xea, 0xf2, 0x4a, 0x4d, - 0x9a, 0xfa, 0xeb, 0x18, 0x1d, 0xc4, 0x51, 0xab, 0x28, 0x42, 0xb2, 0x24, 0xb1, 0xf1, 0xb9, 0x06, - 0xaa, 0xdb, 0x78, 0xba, 0xc9, 0x18, 0x19, 0x86, 0x01, 0x0e, 0xb9, 0x85, 0x23, 0x1f, 0xb9, 0x58, - 0x7c, 0xc2, 0x7f, 0x83, 0xa5, 0x2c, 0xed, 0xc2, 0x21, 0x59, 0x28, 0x65, 0xab, 0x9c, 0x82, 0x22, - 0x08, 0xf8, 0x2e, 0x00, 0x51, 0x8c, 0x27, 0xb6, 0x6b, 0xef, 0xe1, 0xa9, 0xaa, 0x8a, 0x4b, 0x7a, - 0xae, 0x78, 0x93, 0xb2, 0xd4, 0x7b, 0x63, 0xc7, 0x27, 0xee, 0x36, 0x9e, 0x5a, 0x0b, 0x42, 0xbf, - 0xbd, 0x8d, 0xa7, 0x70, 0x05, 0x9c, 0x8a, 0xe8, 0x3e, 0x8e, 0xd5, 0xd1, 0x27, 0x8b, 0xc6, 0xd7, - 0x1a, 0xb8, 0x90, 0x05, 0x20, 0xce, 0x71, 0x1c, 0xe0, 0xb8, 0x37, 0x76, 0x04, 0xa3, 0x0e, 0x4a, - 0xae, 0x42, 0x6c, 0xe2, 0x49, 0x87, 0x8a, 0x16, 0x48, 0xa1, 0xae, 0x77, 0xd4, 0xe7, 0xf9, 0x63, - 0x7c, 0xbe, 0x09, 0xca, 0xd9, 0x2e, 0xc2, 0xeb, 0xc2, 0x09, 0xbc, 0xce, 0xec, 0x6e, 0xe3, 0x69, - 0xe3, 0x93, 0xbc, 0x8b, 0xad, 0x69, 0xea, 0xa4, 0xdc, 0xfc, 0x24, 0x2e, 0x66, 0x0a, 0x79, 0x17, - 0xdd, 0xfc, 0x2e, 0x47, 0xe2, 0x28, 0x1c, 0x8d, 0xa3, 0xf1, 0xa3, 0x06, 0x56, 0xf2, 0xb6, 0xd9, - 0x80, 0xf6, 0xe2, 0x71, 0x88, 0xff, 0xde, 0x87, 0x9b, 0x60, 0x21, 0x12, 0x9a, 0x36, 0x67, 0xea, - 0xcc, 0xd6, 0x8e, 0xdc, 0xe4, 0x41, 0xda, 0xd1, 0x92, 0xab, 0xfc, 0x58, 0x5c, 0xe5, 0x33, 0x92, - 0x35, 0x60, 0xb0, 0x03, 0x96, 0x0f, 0x04, 0xc1, 0x54, 0x12, 0x2f, 0xeb, 0x87, 0xdb, 0xba, 0x9e, - 0xab, 0x75, 0x6b, 0x29, 0x1f, 0x24, 0x6b, 0xfc, 0xa0, 0x01, 0x78, 0xf4, 0xa6, 0xc2, 0xff, 0x03, - 0x78, 0xe0, 0xbe, 0xe7, 0xab, 0xaf, 0x12, 0xe5, 0x6e, 0xb8, 0x4c, 0x55, 0x56, 0x45, 0xf3, 0xb9, - 0x2a, 0x82, 0xef, 0x01, 0x10, 0xc9, 0xc3, 0x3b, 0xf1, 0x09, 0x2f, 0x46, 0xe9, 0xa7, 0xc8, 0xdf, - 0x43, 0x4a, 0x42, 0x7b, 0x84, 0x45, 0x7f, 0x56, 0xed, 0x05, 0x08, 0x68, 0x4b, 0x22, 0x0d, 0x0f, - 0x54, 0xd2, 0xc4, 0xdf, 0xc1, 0x1c, 0x79, 0x88, 0x23, 0x08, 0x41, 0x31, 0x44, 0x01, 0x56, 0xed, - 0x54, 0x7e, 0xc3, 0x75, 0x50, 0xf2, 0x30, 0x73, 0x63, 0x12, 0xc9, 0x4e, 0x3b, 0x2f, 0x45, 0x79, - 0x08, 0xae, 0x81, 0x85, 0x40, 0xed, 0x20, 0xbd, 0x5c, 0xb4, 0xb2, 0x75, 0xe3, 0x69, 0x01, 0xac, - 0xa7, 0x66, 0xba, 0x21, 0xe1, 0x04, 0xf9, 0xe4, 0x63, 0xd9, 0x5d, 0x65, 0x57, 0xc7, 0x1c, 0xc7, - 0x0c, 0xde, 0x06, 0xcb, 0x24, 0x91, 0xa5, 0xee, 0x6a, 0xea, 0x40, 0x89, 0xe3, 0xea, 0x62, 0x02, - 0xe9, 0x6a, 0xee, 0x4c, 0x9a, 0x7a, 0xe2, 0xbe, 0x6a, 0x01, 0x4b, 0x8a, 0x97, 0x80, 0xf0, 0x0a, - 0x28, 0x0f, 0x71, 0x88, 0x19, 0x61, 0xf6, 0x08, 0xb1, 0x91, 0x2a, 0xcb, 0x92, 0xc2, 0xb6, 0x10, - 0x1b, 0x89, 0xbc, 0x38, 0x24, 0x44, 0xf1, 0x34, 0xd1, 0x48, 0x6a, 0x12, 0x24, 0x90, 0x54, 0x68, - 0x03, 0xc0, 0x22, 0xb4, 0x1f, 0xca, 0x69, 0x21, 0xf3, 0x76, 0xd2, 0xca, 0x5a, 0x94, 0x3c, 0x21, - 0x81, 0xbb, 0xa0, 0x32, 0x0e, 0x1d, 0x1a, 0x7a, 0xb3, 0x61, 0x95, 0x35, 0xea, 0x13, 0x8c, 0x9b, - 0x7f, 0x65, 0x64, 0x35, 0x6c, 0x5e, 0x33, 0xc1, 0x4e, 0xff, 0xa3, 0x09, 0x76, 0x1d, 0xc0, 0x11, - 0x61, 0x9c, 0xc6, 0xc4, 0x45, 0xbe, 0x8d, 0x43, 0x1e, 0x13, 0xcc, 0xaa, 0x67, 0x64, 0xa5, 0x9c, - 0x9d, 0x49, 0xcc, 0x44, 0xd0, 0xa8, 0x83, 0x52, 0x76, 0x92, 0x1e, 0x83, 0x15, 0x50, 0x20, 0x5e, - 0xd2, 0xed, 0x8b, 0x96, 0xf8, 0x6c, 0x7c, 0xa3, 0x81, 0x95, 0x6e, 0x98, 0xce, 0xe4, 0xdc, 0xf9, - 0xde, 0x02, 0x25, 0x8f, 0x8e, 0x1d, 0x1f, 0xdb, 0xa2, 0x47, 0xab, 0xc3, 0xbd, 0x7a, 0xf4, 0x9a, - 0xf5, 0x7d, 0xc4, 0x46, 0xef, 0x23, 0xe2, 0xcf, 0xb8, 0x16, 0x48, 0x98, 0x7d, 0x32, 0x0c, 0xe1, - 0x26, 0x58, 0xf0, 0xe8, 0x7e, 0x28, 0x0f, 0x66, 0xfe, 0x4d, 0x36, 0xc9, 0x68, 0x8d, 0xdf, 0x34, - 0x70, 0xee, 0x18, 0x0d, 0xf8, 0x11, 0x58, 0x66, 0x02, 0x3e, 0xf8, 0xa4, 0x28, 0xb7, 0xde, 0x16, - 0x09, 0xfc, 0xf5, 0x79, 0xfd, 0x62, 0x32, 0x2a, 0x99, 0xb7, 0xa7, 0x13, 0x6a, 0x04, 0x88, 0x8f, - 0xf4, 0x1d, 0x39, 0x22, 0x3b, 0xd8, 0xfd, 0xf9, 0xfb, 0xeb, 0x40, 0x4d, 0xdf, 0x0e, 0x76, 0x93, - 0x71, 0xb9, 0x24, 0x77, 0xcb, 0x5e, 0x20, 0x5b, 0x60, 0xe9, 0x21, 0x22, 0xbe, 0x9d, 0x3e, 0xc1, - 0xde, 0xe4, 0xed, 0x51, 0x16, 0xcc, 0x14, 0x17, 0xa3, 0x96, 0xd3, 0xc0, 0x61, 0x9c, 0x86, 0x58, - 0x56, 0xef, 0x82, 0x35, 0x03, 0xae, 0xfd, 0xa4, 0x81, 0xa5, 0x6c, 0xde, 0x8c, 0x10, 0xc3, 0xb0, - 0x06, 0xd6, 0xda, 0x77, 0x77, 0xfb, 0xf7, 0xee, 0x98, 0x96, 0xdd, 0xdb, 0xda, 0xec, 0x9b, 0xf6, - 0xbd, 0xdd, 0x7e, 0xcf, 0x6c, 0x77, 0x6f, 0x75, 0xcd, 0x4e, 0x65, 0x0e, 0x5e, 0x06, 0xab, 0x87, - 0xe4, 0x96, 0x79, 0xbb, 0xdb, 0x1f, 0x98, 0x96, 0xd9, 0xa9, 0x68, 0xc7, 0xd0, 0xbb, 0xbb, 0xdd, - 0x41, 0x77, 0x73, 0xa7, 0x7b, 0xdf, 0xec, 0x54, 0xe6, 0xe1, 0x45, 0x70, 0xe1, 0x90, 0x7c, 0x67, - 0xf3, 0xde, 0x6e, 0x7b, 0xcb, 0xec, 0x54, 0x0a, 0x70, 0x0d, 0x9c, 0x3f, 0x24, 0xec, 0x0f, 0xee, - 0xf6, 0x7a, 0x66, 0xa7, 0x52, 0x3c, 0x46, 0xd6, 0x31, 0x77, 0xcc, 0x81, 0xd9, 0xa9, 0x9c, 0x5a, - 0x2b, 0x7e, 0xf6, 0x6d, 0x6d, 0xae, 0xd5, 0x7d, 0xfa, 0xa2, 0xa6, 0x3d, 0x7b, 0x51, 0xd3, 0xfe, - 0x78, 0x51, 0xd3, 0x1e, 0xbf, 0xac, 0xcd, 0x3d, 0x7b, 0x59, 0x9b, 0xfb, 0xe5, 0x65, 0x6d, 0xee, - 0xbe, 0x91, 0x7b, 0xc9, 0x20, 0xdf, 0x27, 0xa1, 0x43, 0x38, 0x33, 0xe4, 0xdb, 0xf2, 0x91, 0x71, - 0xf0, 0xd1, 0x2e, 0x9f, 0x35, 0xce, 0x69, 0x99, 0xdf, 0xb7, 0xfe, 0x0a, 0x00, 0x00, 0xff, 0xff, - 0x42, 0xd8, 0xe2, 0x59, 0xd2, 0x0b, 0x00, 0x00, + // 1360 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcf, 0x6f, 0xdc, 0x44, + 0x14, 0x8e, 0xb3, 0xdb, 0x36, 0x99, 0x4d, 0xc2, 0x76, 0x9a, 0xb6, 0x9b, 0xb4, 0xdd, 0xa4, 0x8b, + 0x8a, 0xa2, 0x42, 0x6d, 0x52, 0x24, 0x84, 0xe0, 0x50, 0x25, 0x59, 0xb7, 0x31, 0x49, 0xd3, 0x95, + 0x77, 0xcb, 0xa1, 0x02, 0x59, 0x63, 0x7b, 0xba, 0x3b, 0x8d, 0x3d, 0x63, 0x79, 0x66, 0x37, 0x5d, + 0xce, 0x1c, 0x38, 0x96, 0x1b, 0x47, 0x10, 0x17, 0x8e, 0x1c, 0x10, 0x47, 0xce, 0xe5, 0x56, 0x71, + 0x42, 0x08, 0x15, 0xd4, 0x1e, 0x38, 0xf3, 0x1f, 0xa0, 0x19, 0x8f, 0x1d, 0xe7, 0x47, 0x45, 0x2a, + 0x2e, 0xd6, 0xcc, 0xf7, 0xde, 0xf7, 0xfc, 0xe6, 0xbd, 0x37, 0xef, 0x0d, 0x58, 0x1a, 0x21, 0xc4, + 0xad, 0x24, 0x65, 0x23, 0x12, 0xe2, 0xd4, 0x1a, 0xad, 0x16, 0x6b, 0x33, 0x49, 0x99, 0x60, 0xb0, + 0x2e, 0x15, 0xcc, 0x02, 0x1c, 0xad, 0x2e, 0x9e, 0x45, 0x31, 0xa1, 0xcc, 0x52, 0xdf, 0x4c, 0x69, + 0x71, 0x21, 0x60, 0x3c, 0x66, 0xdc, 0x53, 0x3b, 0x2b, 0xdb, 0x68, 0xd1, 0x7c, 0x9f, 0xf5, 0x59, + 0x86, 0xcb, 0x95, 0x46, 0xdf, 0xca, 0x74, 0x2c, 0x2c, 0xad, 0xd2, 0x00, 0x5b, 0xa3, 0x55, 0x1f, + 0x0b, 0xb4, 0x5a, 0x00, 0x5a, 0xaf, 0xd9, 0x67, 0xac, 0x1f, 0x61, 0x4b, 0xed, 0xfc, 0xe1, 0x43, + 0x2b, 0x1c, 0xa6, 0x48, 0x10, 0x46, 0xb5, 0x7c, 0xe9, 0xb0, 0x5c, 0x90, 0x18, 0x73, 0x81, 0xe2, + 0x24, 0x57, 0x20, 0x7e, 0x60, 0x05, 0x2c, 0xc5, 0x56, 0x10, 0x11, 0x4c, 0x85, 0x3c, 0x61, 0xb6, + 0xd2, 0x0a, 0x96, 0x54, 0x88, 0x48, 0x7f, 0x20, 0x32, 0x98, 0x5b, 0x02, 0xd3, 0x10, 0xa7, 0x31, + 0xc9, 0x94, 0xf7, 0x77, 0x9a, 0x00, 0x55, 0xc4, 0x46, 0xab, 0xd6, 0x1e, 0x49, 0x73, 0x37, 0x2f, + 0x97, 0x38, 0x41, 0x3a, 0x4e, 0x04, 0xb3, 0x76, 0xf1, 0x58, 0x87, 0xa0, 0xf5, 0xcf, 0x24, 0x38, + 0xdd, 0x41, 0x29, 0x8a, 0x39, 0xfc, 0x00, 0x34, 0x44, 0x3a, 0xe4, 0x82, 0xd0, 0xbe, 0x97, 0xe0, + 0x94, 0xb0, 0xd0, 0x7b, 0x98, 0xa2, 0x40, 0x9e, 0xa8, 0x61, 0x2c, 0x1b, 0x2b, 0xd3, 0xee, 0x85, + 0x5c, 0xde, 0x51, 0xe2, 0xdb, 0x5a, 0x0a, 0xbb, 0xe0, 0x9c, 0xfc, 0xb1, 0x27, 0x0f, 0xc8, 0x86, + 0x42, 0xb3, 0x1b, 0x93, 0xcb, 0xc6, 0x4a, 0xed, 0xe6, 0x82, 0x99, 0xc5, 0xc1, 0xcc, 0xe3, 0x60, + 0xb6, 0x75, 0x9c, 0xd6, 0xa7, 0x9e, 0x3e, 0x5f, 0x9a, 0xf8, 0xfa, 0xcf, 0x25, 0xc3, 0x3d, 0x2b, + 0xf9, 0xbd, 0x8c, 0x9e, 0x19, 0x87, 0x2b, 0xa0, 0xee, 0x47, 0x2c, 0xd8, 0xe5, 0xd2, 0x9c, 0x87, + 0x13, 0x16, 0x0c, 0x1a, 0x95, 0x65, 0x63, 0xa5, 0xe2, 0xce, 0x65, 0x78, 0x07, 0xa7, 0xb6, 0x44, + 0xa1, 0x03, 0xae, 0xc6, 0xe8, 0xb1, 0x97, 0xd7, 0x81, 0x17, 0x30, 0xca, 0x31, 0xe5, 0x43, 0xee, + 0x8d, 0x50, 0x44, 0x42, 0x24, 0x58, 0xca, 0x1b, 0x55, 0x45, 0x6d, 0xc6, 0xe8, 0x71, 0x47, 0xeb, + 0x6d, 0xe4, 0x6a, 0x9f, 0x14, 0x5a, 0x30, 0x00, 0xe7, 0x1f, 0x62, 0x9c, 0xfd, 0x52, 0xfd, 0xc5, + 0x43, 0x31, 0x1b, 0x52, 0xd1, 0x38, 0x25, 0x03, 0xb0, 0xfe, 0xae, 0x74, 0xf8, 0xf7, 0xe7, 0x4b, + 0xe7, 0xb3, 0x12, 0xe1, 0xe1, 0xae, 0x49, 0x98, 0x15, 0x23, 0x31, 0x30, 0x1d, 0x2a, 0x7e, 0xfd, + 0xf1, 0x06, 0xd0, 0xf5, 0xe5, 0x50, 0xf1, 0xfd, 0xdf, 0x3f, 0x5c, 0x37, 0x5c, 0x28, 0xcd, 0x75, + 0x70, 0xba, 0x2e, 0x8d, 0xad, 0x29, 0x5b, 0xad, 0xb7, 0x41, 0x6d, 0x2d, 0x0c, 0x53, 0xcc, 0xf9, + 0x36, 0xe1, 0x02, 0x5e, 0x06, 0xd3, 0x28, 0xdb, 0x62, 0xde, 0x30, 0x96, 0x2b, 0x2b, 0x33, 0xee, + 0x3e, 0xd0, 0xfa, 0x14, 0x2c, 0x14, 0xfe, 0x75, 0xb1, 0xd8, 0x18, 0x20, 0xda, 0xc7, 0x1d, 0x14, + 0xec, 0x62, 0xc1, 0xe1, 0x2d, 0x50, 0x8d, 0x08, 0x17, 0x8a, 0x55, 0xbb, 0x79, 0xcd, 0x54, 0xf7, + 0x61, 0xb4, 0x6a, 0xbe, 0x8a, 0xd1, 0x46, 0x02, 0xad, 0x57, 0xe5, 0x21, 0x5c, 0x45, 0x6c, 0x7d, + 0x65, 0x80, 0xc6, 0x16, 0x1e, 0xaf, 0x71, 0x4e, 0xfa, 0x34, 0xc6, 0x54, 0xb8, 0x38, 0x89, 0x50, + 0x80, 0xe5, 0x12, 0xbe, 0x09, 0x66, 0x8b, 0x98, 0x4a, 0x87, 0x54, 0x15, 0xcc, 0xb8, 0x33, 0x39, + 0x28, 0x0f, 0x01, 0x3f, 0x04, 0x20, 0x49, 0xf1, 0xc8, 0x0b, 0xbc, 0x5d, 0x3c, 0xd6, 0x29, 0xbf, + 0x6c, 0x96, 0x2a, 0x33, 0xab, 0x39, 0xb3, 0x33, 0xf4, 0x23, 0x12, 0x6c, 0xe1, 0xb1, 0x3b, 0x25, + 0xf5, 0x37, 0xb6, 0xf0, 0x18, 0xce, 0x83, 0x53, 0x09, 0xdb, 0xc3, 0xa9, 0xce, 0x6b, 0xb6, 0x69, + 0x7d, 0x63, 0x80, 0x8b, 0xc5, 0x01, 0x64, 0x92, 0x86, 0x31, 0x4e, 0x3b, 0x43, 0x5f, 0x32, 0x96, + 0x40, 0x2d, 0xd0, 0x88, 0x47, 0x42, 0xe5, 0x50, 0xd5, 0x05, 0x39, 0xe4, 0x84, 0x47, 0x7d, 0x9e, + 0x3c, 0xc6, 0xe7, 0x5b, 0x60, 0xa6, 0xb0, 0x22, 0xbd, 0xae, 0x9c, 0xc0, 0xeb, 0xe2, 0xbf, 0x5b, + 0x78, 0xdc, 0xfa, 0xa2, 0xec, 0xe2, 0xfa, 0x38, 0x77, 0x52, 0x19, 0x3f, 0x89, 0x8b, 0x85, 0x42, + 0xd9, 0xc5, 0xa0, 0x6c, 0xe5, 0xc8, 0x39, 0x2a, 0x47, 0xcf, 0xd1, 0xfa, 0xd9, 0x00, 0xf3, 0xe5, + 0x7f, 0xf3, 0x1e, 0xeb, 0xa4, 0x43, 0x8a, 0xff, 0xdb, 0x87, 0x5b, 0x60, 0x2a, 0x91, 0x9a, 0x9e, + 0xe0, 0x3a, 0x67, 0x8b, 0x47, 0xae, 0x69, 0x2f, 0x6f, 0x57, 0xd9, 0x3d, 0x7d, 0x22, 0xef, 0xe9, + 0x19, 0xc5, 0xea, 0x71, 0xd8, 0x06, 0x73, 0x07, 0x0e, 0xc1, 0x75, 0x10, 0xaf, 0x98, 0x87, 0x7b, + 0xb2, 0x59, 0xaa, 0x75, 0x77, 0xb6, 0x7c, 0x48, 0xde, 0xfa, 0xc9, 0x00, 0xf0, 0xe8, 0x35, 0x84, + 0xef, 0x00, 0x78, 0xe0, 0x32, 0x97, 0xab, 0xaf, 0x9e, 0x94, 0xae, 0xaf, 0x0a, 0x55, 0x51, 0x45, + 0x93, 0xa5, 0x2a, 0x82, 0x1f, 0x01, 0x90, 0xa8, 0xe4, 0x9d, 0x38, 0xc3, 0xd3, 0x49, 0xbe, 0x94, + 0xf1, 0x7b, 0xc4, 0x08, 0xf5, 0x06, 0x58, 0x36, 0x5f, 0xdd, 0x3b, 0x80, 0x84, 0x36, 0x15, 0xd2, + 0x0a, 0x41, 0x3d, 0x0f, 0xfc, 0x5d, 0x2c, 0x50, 0x88, 0x04, 0x82, 0x10, 0x54, 0x29, 0x8a, 0xb1, + 0xee, 0x95, 0x6a, 0x0d, 0x97, 0x41, 0x2d, 0xc4, 0x3c, 0x48, 0x49, 0xa2, 0xda, 0xe8, 0xa4, 0x12, + 0x95, 0x21, 0xb8, 0x08, 0xa6, 0x62, 0x6d, 0x41, 0x79, 0x39, 0xed, 0x16, 0xfb, 0xd6, 0xd3, 0x0a, + 0x58, 0xce, 0x7f, 0xe3, 0x50, 0x22, 0x08, 0x8a, 0xc8, 0xe7, 0xaa, 0x75, 0xaa, 0x96, 0x8d, 0x05, + 0x4e, 0x39, 0xbc, 0x03, 0xe6, 0x48, 0x26, 0xcb, 0xdd, 0x35, 0x74, 0x42, 0x89, 0x1f, 0x98, 0x72, + 0xbc, 0x98, 0x7a, 0xa8, 0x8c, 0x56, 0xcd, 0xcc, 0x7d, 0xdd, 0x02, 0x66, 0x35, 0x2f, 0x03, 0xe1, + 0x55, 0x30, 0xd3, 0xc7, 0x14, 0x73, 0xc2, 0xbd, 0x01, 0xe2, 0x03, 0x5d, 0x96, 0x35, 0x8d, 0x6d, + 0x22, 0x3e, 0x90, 0x71, 0xf1, 0x09, 0x45, 0xe9, 0x38, 0xd3, 0xc8, 0x6a, 0x12, 0x64, 0x90, 0x52, + 0xd8, 0x00, 0x80, 0x27, 0x68, 0x8f, 0xaa, 0x51, 0xa0, 0xe2, 0x76, 0xd2, 0xca, 0x9a, 0x56, 0x3c, + 0x29, 0x81, 0x3b, 0xa0, 0x3e, 0xa4, 0x3e, 0xa3, 0xe1, 0xfe, 0x24, 0x52, 0xfd, 0xf7, 0x84, 0xb3, + 0xe4, 0x8d, 0x82, 0xac, 0x27, 0xc9, 0x2b, 0xc6, 0xd3, 0xe9, 0xff, 0x35, 0x9e, 0x6e, 0x00, 0x38, + 0x20, 0x5c, 0xb0, 0x94, 0x04, 0x28, 0xf2, 0x30, 0x15, 0x29, 0xc1, 0xbc, 0x71, 0x46, 0x55, 0xca, + 0xd9, 0x7d, 0x89, 0x9d, 0x09, 0x5a, 0x4b, 0xa0, 0x56, 0x64, 0x32, 0xe4, 0xb0, 0x0e, 0x2a, 0x24, + 0xcc, 0xba, 0x7d, 0xd5, 0x95, 0xcb, 0xd6, 0xb7, 0x06, 0x98, 0x77, 0x68, 0x3e, 0x70, 0x4b, 0xf9, + 0xbd, 0x0d, 0x6a, 0x21, 0x1b, 0xfa, 0x11, 0xf6, 0x64, 0x8f, 0xd6, 0xc9, 0xbd, 0x76, 0xf4, 0x9a, + 0x75, 0x23, 0xc4, 0x07, 0x1f, 0x23, 0x12, 0xed, 0x73, 0x5d, 0x90, 0x31, 0xbb, 0xa4, 0x4f, 0xe1, + 0x1a, 0x98, 0x0a, 0xd9, 0x1e, 0x55, 0x89, 0x99, 0x7c, 0x1d, 0x23, 0x05, 0xad, 0xf5, 0x87, 0x01, + 0xce, 0x1d, 0xa3, 0x01, 0x3f, 0x03, 0x73, 0x5c, 0xc2, 0x07, 0xdf, 0x0b, 0x33, 0xeb, 0xef, 0xeb, + 0x71, 0x79, 0xe9, 0xe8, 0xb8, 0xdc, 0xc6, 0x7d, 0x14, 0x8c, 0xdb, 0x38, 0x28, 0x0d, 0xcd, 0x36, + 0x0e, 0xb2, 0xa1, 0x39, 0xab, 0xac, 0x15, 0xcf, 0x8b, 0x4d, 0x30, 0xfb, 0x08, 0x91, 0xc8, 0xcb, + 0xdf, 0x57, 0xaf, 0xf3, 0xb0, 0x98, 0x91, 0xcc, 0x1c, 0x97, 0xa3, 0x56, 0xb0, 0xd8, 0xe7, 0x82, + 0x51, 0xac, 0xaa, 0x77, 0xca, 0xdd, 0x07, 0xae, 0xff, 0x62, 0x80, 0xd9, 0x62, 0xde, 0x0c, 0x10, + 0xc7, 0xb0, 0x09, 0x16, 0x37, 0xee, 0xed, 0x74, 0xef, 0xdf, 0xb5, 0x5d, 0xaf, 0xb3, 0xb9, 0xd6, + 0xb5, 0xbd, 0xfb, 0x3b, 0xdd, 0x8e, 0xbd, 0xe1, 0xdc, 0x76, 0xec, 0x76, 0x7d, 0x02, 0x5e, 0x01, + 0x0b, 0x87, 0xe4, 0xae, 0x7d, 0xc7, 0xe9, 0xf6, 0x6c, 0xd7, 0x6e, 0xd7, 0x8d, 0x63, 0xe8, 0xce, + 0x8e, 0xd3, 0x73, 0xd6, 0xb6, 0x9d, 0x07, 0x76, 0xbb, 0x3e, 0x09, 0x2f, 0x81, 0x8b, 0x87, 0xe4, + 0xdb, 0x6b, 0xf7, 0x77, 0x36, 0x36, 0xed, 0x76, 0xbd, 0x02, 0x17, 0xc1, 0x85, 0x43, 0xc2, 0x6e, + 0xef, 0x5e, 0xa7, 0x63, 0xb7, 0xeb, 0xd5, 0x63, 0x64, 0x6d, 0x7b, 0xdb, 0xee, 0xd9, 0xed, 0xfa, + 0xa9, 0xc5, 0xea, 0x97, 0xdf, 0x35, 0x27, 0xd6, 0x9d, 0xa7, 0x2f, 0x9a, 0xc6, 0xb3, 0x17, 0x4d, + 0xe3, 0xaf, 0x17, 0x4d, 0xe3, 0xc9, 0xcb, 0xe6, 0xc4, 0xb3, 0x97, 0xcd, 0x89, 0xdf, 0x5e, 0x36, + 0x27, 0x1e, 0x58, 0x7d, 0x22, 0x06, 0x43, 0xdf, 0x0c, 0x58, 0x6c, 0xa1, 0x28, 0x22, 0xd4, 0x27, + 0x82, 0x5b, 0xea, 0xe1, 0xf8, 0xd8, 0x3a, 0xf8, 0xe2, 0x16, 0xe3, 0x04, 0x73, 0xff, 0xb4, 0x8a, + 0xef, 0x7b, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x62, 0x0e, 0x35, 0x8f, 0x0b, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -1052,11 +1042,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l { - size, err := m.FeesPerBlock.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { + size := m.FeesPerBlockAmount.Size() + i -= size + if _, err := m.FeesPerBlockAmount.MarshalTo(dAtA[i:]); err != nil { return 0, err } - i -= size i = encodeVarintProvider(dAtA, i, uint64(size)) } i-- @@ -1071,12 +1061,12 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.VaasTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.VaasTimeoutPeriod):]) - if err2 != nil { - return 0, err2 + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.VaasTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.VaasTimeoutPeriod):]) + if err1 != nil { + return 0, err1 } - i -= n2 - i = encodeVarintProvider(dAtA, i, uint64(n2)) + i -= n1 + i = encodeVarintProvider(dAtA, i, uint64(n1)) i-- dAtA[i] = 0x12 if len(m.TrustingPeriodFraction) > 0 { @@ -1326,12 +1316,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 m.ConsumerId != 0 { @@ -1463,29 +1453,29 @@ func (m *ConsumerInitializationParameters) MarshalToSizedBuffer(dAtA []byte) (in 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) @@ -1535,20 +1525,20 @@ func (m *ConsumerIds) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if len(m.Ids) > 0 { - dAtA13 := make([]byte, len(m.Ids)*10) - var j12 int + dAtA12 := make([]byte, len(m.Ids)*10) + var j11 int for _, num := range m.Ids { for num >= 1<<7 { - dAtA13[j12] = uint8(uint64(num)&0x7f | 0x80) + dAtA12[j11] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j12++ + j11++ } - dAtA13[j12] = uint8(num) - j12++ + dAtA12[j11] = uint8(num) + j11++ } - i -= j12 - copy(dAtA[i:], dAtA13[:j12]) - i = encodeVarintProvider(dAtA, i, uint64(j12)) + i -= j11 + copy(dAtA[i:], dAtA12[:j11]) + i = encodeVarintProvider(dAtA, i, uint64(j11)) i-- dAtA[i] = 0xa } @@ -1632,12 +1622,12 @@ func (m *SlashJailParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - n16, err16 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.JailDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.JailDuration):]) - if err16 != nil { - return 0, err16 + n15, err15 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.JailDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.JailDuration):]) + if err15 != nil { + return 0, err15 } - i -= n16 - i = encodeVarintProvider(dAtA, i, uint64(n16)) + i -= n15 + i = encodeVarintProvider(dAtA, i, uint64(n15)) i-- dAtA[i] = 0x12 { @@ -1682,7 +1672,7 @@ func (m *Params) Size() (n int) { if m.MaxProviderConsensusValidators != 0 { n += 1 + sovProvider(uint64(m.MaxProviderConsensusValidators)) } - l = m.FeesPerBlock.Size() + l = m.FeesPerBlockAmount.Size() n += 1 + l + sovProvider(uint64(l)) return n } @@ -2056,9 +2046,9 @@ func (m *Params) Unmarshal(dAtA []byte) error { } case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FeesPerBlock", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field FeesPerBlockAmount", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -2068,22 +2058,23 @@ func (m *Params) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.FeesPerBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.FeesPerBlockAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -2248,7 +2239,7 @@ func (m *ValidatorSetChangePackets) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.List = append(m.List, types1.ValidatorSetChangePacketData{}) + m.List = append(m.List, types.ValidatorSetChangePacketData{}) if err := m.List[len(m.List)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/x/vaas/types/wire.pb.go b/x/vaas/types/wire.pb.go index f32b100..10eb5ee 100644 --- a/x/vaas/types/wire.pb.go +++ b/x/vaas/types/wire.pb.go @@ -6,6 +6,7 @@ package types import ( fmt "fmt" types "github.com/cometbft/cometbft/abci/types" + _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -108,28 +109,28 @@ func init() { func init() { proto.RegisterFile("vaas/v1/wire.proto", fileDescriptor_17a432f87dfb1130) } var fileDescriptor_17a432f87dfb1130 = []byte{ - // 321 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xb1, 0x4a, 0xc3, 0x40, - 0x18, 0xc7, 0x73, 0x56, 0x54, 0x22, 0x14, 0x0d, 0x0e, 0xa1, 0x4a, 0x1a, 0x8a, 0x48, 0xa6, 0x1c, - 0xd1, 0xcd, 0x49, 0x6a, 0x97, 0x6e, 0x52, 0xd1, 0xc1, 0x25, 0x7c, 0x97, 0x1c, 0xe9, 0xd1, 0xe4, - 0xae, 0xe4, 0xbe, 0x46, 0xfb, 0x16, 0x3e, 0x56, 0xc7, 0x8e, 0x4e, 0x45, 0x9a, 0x37, 0xf0, 0x09, - 0x24, 0x49, 0xa3, 0x88, 0xd3, 0x7d, 0xf7, 0xfb, 0x7e, 0xf7, 0x1f, 0xfe, 0x67, 0x5a, 0x05, 0x80, - 0xa6, 0x45, 0x40, 0x5f, 0x45, 0xce, 0xfd, 0x79, 0xae, 0x50, 0x59, 0x87, 0x15, 0xf3, 0x8b, 0xa0, - 0x77, 0x19, 0x29, 0x9d, 0x29, 0x4d, 0x35, 0xc2, 0x4c, 0xc8, 0x84, 0x16, 0x01, 0xe3, 0x08, 0x41, - 0x7b, 0x6f, 0xf4, 0xde, 0x59, 0xa2, 0x12, 0x55, 0x8f, 0xb4, 0x9a, 0x76, 0xf4, 0x1c, 0xb9, 0x8c, - 0x79, 0x9e, 0x09, 0x89, 0x14, 0x58, 0x24, 0x28, 0x2e, 0xe7, 0x5c, 0x37, 0xcb, 0x41, 0x49, 0xcc, - 0x8b, 0x67, 0x48, 0x45, 0x0c, 0xa8, 0xf2, 0x47, 0x8e, 0xf7, 0x53, 0x90, 0x09, 0x7f, 0x80, 0x68, - 0xc6, 0x71, 0x04, 0x08, 0x96, 0x32, 0x4f, 0x8b, 0x76, 0x1f, 0x2e, 0xe6, 0x31, 0x20, 0xd7, 0x36, - 0x71, 0x3b, 0xde, 0xf1, 0xb5, 0xeb, 0xff, 0x26, 0xfb, 0x55, 0xb2, 0xff, 0x93, 0xf4, 0x54, 0x8b, - 0x43, 0x77, 0xb5, 0xe9, 0x1b, 0x5f, 0x9b, 0xbe, 0xbd, 0x84, 0x2c, 0xbd, 0x1d, 0xfc, 0x0b, 0x1a, - 0x4c, 0x4e, 0x8a, 0xbf, 0x4f, 0xb4, 0xe5, 0x99, 0x15, 0xd3, 0x1c, 0x77, 0x52, 0x28, 0x62, 0x7b, - 0xcf, 0x25, 0xde, 0xfe, 0xa4, 0xdb, 0xf0, 0x46, 0x1c, 0xc7, 0x95, 0x19, 0x29, 0xa9, 0x17, 0x19, - 0xcf, 0x43, 0x21, 0xc3, 0x98, 0x33, 0xb4, 0x3b, 0x2e, 0xf1, 0x8e, 0x26, 0xdd, 0x96, 0x8f, 0xe5, - 0x88, 0x33, 0x1c, 0xde, 0xad, 0xb6, 0x0e, 0x59, 0x6f, 0x1d, 0xf2, 0xb9, 0x75, 0xc8, 0x7b, 0xe9, - 0x18, 0xeb, 0xd2, 0x31, 0x3e, 0x4a, 0xc7, 0x78, 0xb9, 0x4a, 0x04, 0x4e, 0x17, 0xcc, 0x8f, 0x54, - 0x46, 0x21, 0x4d, 0x85, 0x64, 0x02, 0x35, 0xad, 0xbf, 0xe2, 0xad, 0x39, 0xea, 0xb6, 0xd8, 0x41, - 0x5d, 0xd7, 0xcd, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa5, 0xee, 0x04, 0x36, 0xa6, 0x01, 0x00, - 0x00, + // 333 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xc1, 0x4a, 0xeb, 0x40, + 0x14, 0x86, 0x33, 0xb7, 0x97, 0x7b, 0x2f, 0xb9, 0x50, 0x34, 0xb8, 0x88, 0x55, 0xd2, 0x50, 0x44, + 0xb2, 0xca, 0x10, 0xdd, 0xb9, 0x92, 0xda, 0x4d, 0x77, 0x52, 0xd1, 0x85, 0x9b, 0x70, 0x26, 0x19, + 0xd2, 0xa1, 0xc9, 0x4c, 0xc9, 0x9c, 0x46, 0xfb, 0x16, 0x3e, 0x56, 0x97, 0x5d, 0xba, 0x2a, 0xd2, + 0xbc, 0x81, 0x4f, 0x20, 0xc9, 0xb4, 0x8a, 0xb8, 0x9a, 0x73, 0xfe, 0xff, 0x3b, 0xff, 0x81, 0x33, + 0xb6, 0x53, 0x01, 0x68, 0x5a, 0x45, 0xf4, 0x49, 0x94, 0x3c, 0x9c, 0x97, 0x0a, 0x95, 0xf3, 0xb7, + 0xd1, 0xc2, 0x2a, 0xea, 0x9d, 0x25, 0x4a, 0x17, 0x4a, 0x53, 0x8d, 0x30, 0x13, 0x32, 0xa3, 0x55, + 0xc4, 0x38, 0x42, 0xb4, 0xef, 0x0d, 0xde, 0x3b, 0xca, 0x54, 0xa6, 0xda, 0x92, 0x36, 0xd5, 0x4e, + 0x3d, 0x41, 0x2e, 0x53, 0x5e, 0x16, 0x42, 0x22, 0x05, 0x96, 0x08, 0x8a, 0xcb, 0x39, 0xd7, 0x3b, + 0xf3, 0xd8, 0x04, 0xc7, 0x66, 0xca, 0x34, 0xc6, 0x1a, 0xd4, 0xc4, 0x3e, 0x7d, 0x80, 0x5c, 0xa4, + 0x80, 0xaa, 0xbc, 0xe3, 0x78, 0x33, 0x05, 0x99, 0xf1, 0x5b, 0x48, 0x66, 0x1c, 0x47, 0x80, 0xe0, + 0x28, 0xfb, 0xb0, 0xda, 0xfb, 0xf1, 0x62, 0x9e, 0x02, 0x72, 0xed, 0x12, 0xbf, 0x13, 0xfc, 0xbf, + 0xf0, 0xc3, 0xaf, 0xa5, 0x61, 0xb3, 0x34, 0xfc, 0x4c, 0xba, 0x6f, 0xc1, 0xa1, 0xbf, 0xda, 0xf4, + 0xad, 0xf7, 0x4d, 0xdf, 0x5d, 0x42, 0x91, 0x5f, 0x0d, 0x7e, 0x04, 0x0d, 0x26, 0x07, 0xd5, 0xf7, + 0x11, 0xed, 0x04, 0x76, 0xa3, 0x69, 0x8e, 0x3b, 0x28, 0x16, 0xa9, 0xfb, 0xcb, 0x27, 0xc1, 0xef, + 0x49, 0xd7, 0xe8, 0x06, 0x1c, 0xa7, 0x0d, 0x99, 0x28, 0xa9, 0x17, 0x05, 0x2f, 0x63, 0x21, 0xe3, + 0x94, 0x33, 0x74, 0x3b, 0x3e, 0x09, 0xfe, 0x4d, 0xba, 0x7b, 0x7d, 0x2c, 0x47, 0x9c, 0xe1, 0xf0, + 0x7a, 0xb5, 0xf5, 0xc8, 0x7a, 0xeb, 0x91, 0xb7, 0xad, 0x47, 0x5e, 0x6a, 0xcf, 0x5a, 0xd7, 0x9e, + 0xf5, 0x5a, 0x7b, 0xd6, 0xe3, 0x79, 0x26, 0x70, 0xba, 0x60, 0x61, 0xa2, 0x0a, 0x0a, 0x79, 0x2e, + 0x24, 0x13, 0xa8, 0x69, 0xfb, 0x4b, 0xcf, 0xe6, 0x69, 0x0f, 0xc9, 0xfe, 0xb4, 0xe7, 0xba, 0xfc, + 0x08, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x4a, 0x54, 0xd8, 0xc1, 0x01, 0x00, 0x00, } func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { From b415bc771de7e97c90ec911fafdb76bb0168e2cf Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Fri, 5 Jun 2026 00:17:18 +0200 Subject: [PATCH 2/6] update protos comments --- proto/vaas/provider/v1/query.proto | 8 +++++--- proto/vaas/provider/v1/tx.proto | 6 +++--- x/vaas/provider/types/query.pb.go | 11 +++++++---- x/vaas/provider/types/tx.pb.go | 6 +++--- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/proto/vaas/provider/v1/query.proto b/proto/vaas/provider/v1/query.proto index a29a9da..667d567 100644 --- a/proto/vaas/provider/v1/query.proto +++ b/proto/vaas/provider/v1/query.proto @@ -110,7 +110,8 @@ service Query { } // QueryConsumerFeesPerBlock returns the effective per-block fee for a - // consumer chain: the override if one is set, else Params.FeesPerBlock. + // consumer chain: the override amount if one is set, else + // Params.FeesPerBlockAmount, carried at the module's wired fee denom. rpc QueryConsumerFeesPerBlock(QueryConsumerFeesPerBlockRequest) returns (QueryConsumerFeesPerBlockResponse) { option (google.api.http).get = @@ -297,8 +298,9 @@ message QueryConsumerFeesPerBlockRequest { uint64 consumer_id = 1; } -// Effective fee for the consumer: the override if one is set, else -// Params.FeesPerBlock. is_override distinguishes the two cases. +// Effective fee for the consumer (a resolved coin at the module's wired fee +// denom): the override amount if one is set, else Params.FeesPerBlockAmount. +// is_override distinguishes the two cases. message QueryConsumerFeesPerBlockResponse { cosmos.base.v1beta1.Coin fees_per_block = 1 [ (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin", diff --git a/proto/vaas/provider/v1/tx.proto b/proto/vaas/provider/v1/tx.proto index 8cef12a..e5c53ce 100644 --- a/proto/vaas/provider/v1/tx.proto +++ b/proto/vaas/provider/v1/tx.proto @@ -171,12 +171,12 @@ message MsgSetConsumerFeesPerBlock { // consumer_id is the internal numeric id of the target consumer. uint64 consumer_id = 2; // amount is the per-block fee charged to the consumer, expressed in the - // module's fee denom (Params.FeesPerBlock.Denom). + // module's fee denom (fixed at module wiring). // // Empty string clears any existing override; the consumer reverts to - // Params.FeesPerBlock.Amount. A non-empty value must parse as a + // Params.FeesPerBlockAmount. A non-empty value must parse as a // cosmossdk.io/math.Int and must be strictly greater than the module-wide - // Params.FeesPerBlock.Amount, which acts as a floor: an override may only + // Params.FeesPerBlockAmount, which acts as a floor: an override may only // raise a consumer's per-block fee above the global default, never lower it. string amount = 3 [(cosmos_proto.scalar) = "cosmos.Int"]; } diff --git a/x/vaas/provider/types/query.pb.go b/x/vaas/provider/types/query.pb.go index 37ea6d3..82f6d73 100644 --- a/x/vaas/provider/types/query.pb.go +++ b/x/vaas/provider/types/query.pb.go @@ -1390,8 +1390,9 @@ func (m *QueryConsumerFeesPerBlockRequest) GetConsumerId() uint64 { return 0 } -// Effective fee for the consumer: the override if one is set, else -// Params.FeesPerBlock. is_override distinguishes the two cases. +// Effective fee for the consumer (a resolved coin at the module's wired fee +// denom): the override amount if one is set, else Params.FeesPerBlockAmount. +// is_override distinguishes the two cases. type QueryConsumerFeesPerBlockResponse struct { FeesPerBlock github_com_cosmos_cosmos_sdk_types.Coin `protobuf:"bytes,1,opt,name=fees_per_block,json=feesPerBlock,proto3,casttype=github.com/cosmos/cosmos-sdk/types.Coin" json:"fees_per_block"` IsOverride bool `protobuf:"varint,2,opt,name=is_override,json=isOverride,proto3" json:"is_override,omitempty"` @@ -1756,7 +1757,8 @@ type QueryClient interface { // of the consumer chain associated with the provided consumer id QueryConsumerGenesisTime(ctx context.Context, in *QueryConsumerGenesisTimeRequest, opts ...grpc.CallOption) (*QueryConsumerGenesisTimeResponse, error) // QueryConsumerFeesPerBlock returns the effective per-block fee for a - // consumer chain: the override if one is set, else Params.FeesPerBlock. + // consumer chain: the override amount if one is set, else + // Params.FeesPerBlockAmount, carried at the module's wired fee denom. QueryConsumerFeesPerBlock(ctx context.Context, in *QueryConsumerFeesPerBlockRequest, opts ...grpc.CallOption) (*QueryConsumerFeesPerBlockResponse, error) // QueryAllConsumerFeesPerBlockOverrides returns the list of per-consumer // fees_per_block amount overrides. @@ -1924,7 +1926,8 @@ type QueryServer interface { // of the consumer chain associated with the provided consumer id QueryConsumerGenesisTime(context.Context, *QueryConsumerGenesisTimeRequest) (*QueryConsumerGenesisTimeResponse, error) // QueryConsumerFeesPerBlock returns the effective per-block fee for a - // consumer chain: the override if one is set, else Params.FeesPerBlock. + // consumer chain: the override amount if one is set, else + // Params.FeesPerBlockAmount, carried at the module's wired fee denom. QueryConsumerFeesPerBlock(context.Context, *QueryConsumerFeesPerBlockRequest) (*QueryConsumerFeesPerBlockResponse, error) // QueryAllConsumerFeesPerBlockOverrides returns the list of per-consumer // fees_per_block amount overrides. diff --git a/x/vaas/provider/types/tx.pb.go b/x/vaas/provider/types/tx.pb.go index 451e69a..ace1a80 100644 --- a/x/vaas/provider/types/tx.pb.go +++ b/x/vaas/provider/types/tx.pb.go @@ -720,12 +720,12 @@ type MsgSetConsumerFeesPerBlock struct { // consumer_id is the internal numeric id of the target consumer. ConsumerId uint64 `protobuf:"varint,2,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // amount is the per-block fee charged to the consumer, expressed in the - // module's fee denom (Params.FeesPerBlock.Denom). + // module's fee denom (fixed at module wiring). // // Empty string clears any existing override; the consumer reverts to - // Params.FeesPerBlock.Amount. A non-empty value must parse as a + // Params.FeesPerBlockAmount. A non-empty value must parse as a // cosmossdk.io/math.Int and must be strictly greater than the module-wide - // Params.FeesPerBlock.Amount, which acts as a floor: an override may only + // Params.FeesPerBlockAmount, which acts as a floor: an override may only // raise a consumer's per-block fee above the global default, never lower it. Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` } From 69f1016dd8f42b3aae3e7b6ed9e6f518cec396aa Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Fri, 5 Jun 2026 00:17:35 +0200 Subject: [PATCH 3/6] fix e2e --- tests/e2e/chain_test.go | 1 + tests/e2e/e2e_debt_test.go | 2 +- tests/e2e/e2e_setup_test.go | 11 ++++------- tests/e2e/scripts/provider-init.sh | 3 ++- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/e2e/chain_test.go b/tests/e2e/chain_test.go index 608f9d1..4e548da 100644 --- a/tests/e2e/chain_test.go +++ b/tests/e2e/chain_test.go @@ -6,6 +6,7 @@ const ( providerHomePath = "/home/nonroot/.provider" consumerHomePath = "/home/nonroot/.consumer" bondDenom = "uatone" + feeDenom = "uphoton" providerChainID = "provider-e2e" consumerChainID = "consumer-e2e" ) diff --git a/tests/e2e/e2e_debt_test.go b/tests/e2e/e2e_debt_test.go index fbace25..49cdde3 100644 --- a/tests/e2e/e2e_debt_test.go +++ b/tests/e2e/e2e_debt_test.go @@ -93,7 +93,7 @@ func (s *IntegrationTestSuite) testConsumerDebtFlow() { "consumer did not enter debt; last dry-run did not surface debt error") s.T().Log("funding consumer fee pool on provider...") - s.providerFundAddress(feePoolAddr, "10000000"+bondDenom) + s.providerFundAddress(feePoolAddr, "10000000"+feeDenom) s.T().Log("waiting for consumer to exit debt (bank send should succeed)...") s.Require().Eventuallyf(func() bool { diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index d1ea1fe..c4c288b 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -249,16 +249,13 @@ func (s *IntegrationTestSuite) initAndStartProvider() { } } - // Set fast epoch for VSC, and override fees_per_block to use the - // bond denom so the e2e debt-flow test can fund the consumer fee - // pool from existing genesis accounts. + // Set fast epoch for VSC and a small per-block fee amount. The fee + // denom is fixed to feeDenom at module wiring, only the amount is + // configurable here. val is funded with feeDenom in provider-init.sh if provider, ok := appState["provider"].(map[string]any); ok { if params, ok := provider["params"].(map[string]any); ok { params["blocks_per_epoch"] = "5" - params["fees_per_block"] = map[string]any{ - "denom": bondDenom, - "amount": "1000", - } + params["fees_per_block_amount"] = "1000" } } }) diff --git a/tests/e2e/scripts/provider-init.sh b/tests/e2e/scripts/provider-init.sh index 137a6e9..e7a451a 100755 --- a/tests/e2e/scripts/provider-init.sh +++ b/tests/e2e/scripts/provider-init.sh @@ -9,6 +9,7 @@ BINARY="${BINARY:-provider}" HOME_DIR="${HOME_DIR:-/home/nonroot/.provider}" CHAIN_ID="${CHAIN_ID:-provider-e2e}" DENOM="${DENOM:-uatone}" +FEE_DENOM="${FEE_DENOM:-uphoton}" MNEMONIC="${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}" # Initialize chain @@ -24,7 +25,7 @@ $BINARY keys add user --home "$HOME_DIR" --keyring-backend test echo "$MNEMONIC" | $BINARY keys add relayer --recover --home "$HOME_DIR" --keyring-backend test # Add genesis accounts -$BINARY genesis add-genesis-account val "1000000000000${DENOM}" --home "$HOME_DIR" --keyring-backend test +$BINARY genesis add-genesis-account val "1000000000000${DENOM},1000000000000${FEE_DENOM}" --home "$HOME_DIR" --keyring-backend test $BINARY genesis add-genesis-account user "1000000000${DENOM}" --home "$HOME_DIR" --keyring-backend test $BINARY genesis add-genesis-account relayer "100000000${DENOM}" --home "$HOME_DIR" --keyring-backend test From 83a8ebe3abcf9e12386c7a52237e31a72be363b9 Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:59:46 +0200 Subject: [PATCH 4/6] address f/b --- Makefile | 2 +- x/vaas/provider/keeper/fees.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1b53ff5..279ecea 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ 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,1000000000000uphoton $(providerd) keys add user $(providerd) genesis add-genesis-account user 1000000000uatone $(providerd) genesis gentx val 1000000000uatone diff --git a/x/vaas/provider/keeper/fees.go b/x/vaas/provider/keeper/fees.go index 9954edf..5a094c8 100644 --- a/x/vaas/provider/keeper/fees.go +++ b/x/vaas/provider/keeper/fees.go @@ -87,7 +87,7 @@ func (k Keeper) CollectFeesFromConsumers(ctx sdk.Context) sdk.Coin { // does via BeginBlock VoteInfos. Signers that have since unbonded or been // removed from the set forfeit their share — we only pay current participants. func (k Keeper) DistributeFeesToValidators(ctx sdk.Context) error { - totalFees := k.bankKeeper.GetBalance(ctx, authtypes.NewModuleAddress(types.ModuleName), k.GetFeesPerBlock(ctx).Denom) + totalFees := k.bankKeeper.GetBalance(ctx, authtypes.NewModuleAddress(types.ModuleName), k.GetFeeDenom()) if totalFees.IsZero() { return nil } From 9787415d2ca462f4c49da603e79e9a930be52015 Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:20:51 +0200 Subject: [PATCH 5/6] post-merge fixes --- x/vaas/provider/keeper/fee_denom_test.go | 2 +- x/vaas/provider/keeper/msg_server.go | 5 +++-- x/vaas/provider/keeper/msg_server_test.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x/vaas/provider/keeper/fee_denom_test.go b/x/vaas/provider/keeper/fee_denom_test.go index f669cab..185fd11 100644 --- a/x/vaas/provider/keeper/fee_denom_test.go +++ b/x/vaas/provider/keeper/fee_denom_test.go @@ -33,7 +33,7 @@ func TestNewKeeperRejectsInvalidFeeDenom(t *testing.T) { require.Containsf(t, fmt.Sprint(r), "fee denom", "denom %q should trip the fee-denom guard", denom) }() providerkeeper.NewKeeper( - nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, govkeeper.Keeper{}, "authority", nil, nil, diff --git a/x/vaas/provider/keeper/msg_server.go b/x/vaas/provider/keeper/msg_server.go index dfa98df..69fadb7 100644 --- a/x/vaas/provider/keeper/msg_server.go +++ b/x/vaas/provider/keeper/msg_server.go @@ -597,9 +597,10 @@ func (k msgServer) FundConsumerFeePool( } params := k.GetParams(ctx) - if msg.Amount.Denom != params.FeesPerBlock.Denom { + feeDenom := k.GetFeeDenom() + if msg.Amount.Denom != feeDenom { return nil, errorsmod.Wrapf(types.ErrInvalidFundDenom, - "expected denom %s, got %s", params.FeesPerBlock.Denom, msg.Amount.Denom) + "expected denom %s, got %s", feeDenom, msg.Amount.Denom) } if params.MinDepositBlocks > 0 { diff --git a/x/vaas/provider/keeper/msg_server_test.go b/x/vaas/provider/keeper/msg_server_test.go index de216c2..b956966 100644 --- a/x/vaas/provider/keeper/msg_server_test.go +++ b/x/vaas/provider/keeper/msg_server_test.go @@ -850,7 +850,7 @@ func TestFundConsumerFeePool(t *testing.T) { if feesAmount == 0 { feesAmount = 10 } - params.FeesPerBlock = sdk.NewInt64Coin("uphoton", feesAmount) + params.FeesPerBlockAmount = math.NewInt(feesAmount) params.MinDepositBlocks = tc.minDepositBlocks k.SetParams(ctx, params) From 2fd329207c7261ed858d86521262cc4053d682a4 Mon Sep 17 00:00:00 2001 From: Giuseppe Natale <12249307+giunatale@users.noreply.github.com> Date: Fri, 5 Jun 2026 17:10:58 +0200 Subject: [PATCH 6/6] fix e2e and add make target to fund consumer --- Makefile | 13 ++++++++++++- tests/e2e/e2e_fee_pool_test.go | 8 ++++---- x/vaas/provider/keeper/fees_test.go | 3 ++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 279ecea..25efb4f 100644 --- a/Makefile +++ b/Makefile @@ -167,7 +167,18 @@ consumer-start: consumer-init consumer-create $(MAKE) consumer-genesis CONSUMER_ID=0 $(MAKE) consumer-run -.PHONY: consumer-init consumer-create consumer-genesis consumer-run consumer-start +# Fund a consumer's fee pool so the provider can collect its per-block fees and +# the consumer stays out of debt. The fee denom is uphoton (fixed at module +# wiring); FEE_POOL_AMOUNT must clear the min-deposit floor +# (fees_per_block_amount x min_deposit_blocks). Run after the consumer exists, +# e.g. make provider-fund-consumer-fee-pool CONSUMER_ID=0 +FEE_POOL_AMOUNT ?= 100000000uphoton +provider-fund-consumer-fee-pool: + $(providerd) tx provider fund-consumer-fee-pool $(CONSUMER_ID) $(FEE_POOL_AMOUNT) \ + --from val --keyring-backend test --chain-id provider-localnet \ + --gas auto --gas-adjustment 1.5 --fees 10000uatone -y + +.PHONY: consumer-init consumer-create consumer-genesis consumer-run consumer-start provider-fund-consumer-fee-pool ############################################################################### ### TS Relayer ### diff --git a/tests/e2e/e2e_fee_pool_test.go b/tests/e2e/e2e_fee_pool_test.go index b2c84c4..02dc1c1 100644 --- a/tests/e2e/e2e_fee_pool_test.go +++ b/tests/e2e/e2e_fee_pool_test.go @@ -128,7 +128,7 @@ func (s *IntegrationTestSuite) providerFundCommunityPool(amount string) { func (s *IntegrationTestSuite) testFeePoolFundAndLockEnforcement() { s.Run("fee pool fund and lock enforcement", func() { const consumerID = "0" - denom := bondDenom + denom := feeDenom valAddr := s.providerKeyAddress("val") userAddr := s.providerKeyAddress("user") @@ -222,7 +222,7 @@ func (s *IntegrationTestSuite) testFeePoolSendRestriction() { func (s *IntegrationTestSuite) testFeePoolGovSubsidyClawback() { s.Run("fee pool gov subsidy + clawback", func() { const consumerID = "0" - denom := bondDenom + denom := feeDenom govAddr := s.queryGovAuthority() distrAddr := s.queryModuleAccountAddress("distribution") @@ -242,7 +242,7 @@ func (s *IntegrationTestSuite) testFeePoolGovSubsidyClawback() { "deposit": "10000000%s", "title": "Subsidize consumer %s", "summary": "e2e gov subsidy test" -}`, govAddr, consumerID, denom, denom, consumerID) +}`, govAddr, consumerID, denom, bondDenom, consumerID) s.submitAndPassProposal(fundJSON) @@ -263,7 +263,7 @@ func (s *IntegrationTestSuite) testFeePoolGovSubsidyClawback() { "deposit": "10000000%s", "title": "Clawback consumer %s subsidy", "summary": "e2e gov clawback test" -}`, govAddr, consumerID, denom, denom, consumerID) +}`, govAddr, consumerID, denom, bondDenom, consumerID) s.submitAndPassProposal(clawbackJSON) diff --git a/x/vaas/provider/keeper/fees_test.go b/x/vaas/provider/keeper/fees_test.go index f64f7ec..40d2479 100644 --- a/x/vaas/provider/keeper/fees_test.go +++ b/x/vaas/provider/keeper/fees_test.go @@ -56,7 +56,8 @@ func TestCollectFeesFromConsumers(t *testing.T) { // TestCollectFeesFromConsumers_PerConsumerOverride verifies that each consumer // is charged its effective per-block fee: consumer1 has an override and pays -// the override amount; consumer0 has no override and pays Params.FeesPerBlock. +// the override amount; consumer0 has no override and pays +// Params.FeesPerBlockAmount. func TestCollectFeesFromConsumers_PerConsumerOverride(t *testing.T) { params := testkeeper.NewInMemKeeperParams(t) k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, params)