diff --git a/.changelog/unreleased/features/1587-enable-opt-in-chains-through-gov-proposals.md b/.changelog/unreleased/features/1587-enable-opt-in-chains-through-gov-proposals.md new file mode 100644 index 0000000000..57f16adc9b --- /dev/null +++ b/.changelog/unreleased/features/1587-enable-opt-in-chains-through-gov-proposals.md @@ -0,0 +1,2 @@ +- Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) \ No newline at end of file diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 4da89022e8..9d815a1768 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -83,6 +83,11 @@ message ConsumerAdditionProposal { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintain the existing ibc transfer channel string distribution_transmission_channel = 14; + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + uint32 top_N = 15; } // ConsumerRemovalProposal is a governance proposal on the provider chain to diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index ff3df99763..05bef232e3 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -271,6 +271,7 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { types.DefaultCCVTimeoutPeriod, types.DefaultTransferTimeoutPeriod, types.DefaultConsumerUnbondingPeriod, + 0, ).(*providertypes.ConsumerAdditionProposal) return prop diff --git a/x/ccv/provider/client/proposal_handler.go b/x/ccv/provider/client/proposal_handler.go index fa74bb953e..9b5674f4c7 100644 --- a/x/ccv/provider/client/proposal_handler.go +++ b/x/ccv/provider/client/proposal_handler.go @@ -64,7 +64,8 @@ Where proposal.json contains: "transfer_timeout_period": 3600000000000, "ccv_timeout_period": 2419200000000000, "unbonding_period": 1728000000000000, - "deposit": "10000stake" + "deposit": "10000stake", + "top_n": 0, } `, RunE: func(cmd *cobra.Command, args []string) error { @@ -86,7 +87,7 @@ Where proposal.json contains: proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, - proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) + proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod, proposal.TopN) from := clientCtx.GetFromAddress() @@ -241,6 +242,7 @@ type ConsumerAdditionProposalJSON struct { UnbondingPeriod time.Duration `json:"unbonding_period"` Deposit string `json:"deposit"` + TopN uint32 `json:"top_N"` } type ConsumerAdditionProposalReq struct { diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 510d957c5d..1a7fe69ee5 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -1136,3 +1136,51 @@ func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string { return allConsumerChains } + +// SetTopN stores the N value associated to chain with `chainID` +func (k Keeper) SetTopN( + ctx sdk.Context, + chainID string, + N uint32, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, N) + + store.Set(types.TopNKey(chainID), buf) +} + +// DeleteTopN removes the N value associated to chain with `chainID` +func (k Keeper) DeleteTopN( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.TopNKey(chainID)) +} + +// GetTopN returns (N, true) if chain `chainID` has a top N associated, and (0, false) otherwise. +func (k Keeper) GetTopN( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.TopNKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// IsTopN returns true if chain with `chainID` is a Top N chain (i.e., enforces at least one validator to validate chain `chainID`) +func (k Keeper) IsTopN(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return found && topN > 0 +} + +// IsOptIn returns true if chain with `chainID` is an Opt In chain (i.e., no validator is forced to validate chain `chainID`) +func (k Keeper) IsOptIn(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return !found || topN == 0 +} diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 9c9d421fd9..4dc73b7f9e 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -628,3 +628,34 @@ func TestGetAllProposedConsumerChainIDs(t *testing.T) { } } } + +// TestTopN tests `SetTopN`, `GetTopN`, `IsTopN`, and `IsOptIn` methods +func TestTopN(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + tests := []struct { + chainID string + N uint32 + isOptIn bool + }{ + {chainID: "TopNChain1", N: 50, isOptIn: false}, + {chainID: "TopNChain2", N: 100, isOptIn: false}, + {chainID: "OptInChain", N: 0, isOptIn: true}, + } + + for _, test := range tests { + providerKeeper.SetTopN(ctx, test.chainID, test.N) + topN, found := providerKeeper.GetTopN(ctx, test.chainID) + require.Equal(t, test.N, topN) + require.True(t, found) + + if test.isOptIn { + require.True(t, providerKeeper.IsOptIn(ctx, test.chainID)) + require.False(t, providerKeeper.IsTopN(ctx, test.chainID)) + } else { + require.False(t, providerKeeper.IsOptIn(ctx, test.chainID)) + require.True(t, providerKeeper.IsTopN(ctx, test.chainID)) + } + } +} diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index b0e2845502..f1af329d60 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -214,6 +214,8 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteUnbondingOpIndex(ctx, chainID, unbondingOpsIndex.VscId) } + k.DeleteTopN(ctx, chainID) + k.Logger(ctx).Info("consumer chain removed from provider", "chainID", chainID) return nil @@ -373,6 +375,11 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { ctx.Logger().Info("consumer client could not be created: %w", err) continue } + + // Only set Top N at the moment a chain starts. If we were to do this earlier (e.g., during the proposal), + // then someone could create a bogus ConsumerAdditionProposal to override the Top N for a specific chain. + k.SetTopN(ctx, prop.ChainId, prop.Top_N) + // The cached context is created with a new EventManager so we merge the event // into the original context ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index fc1c7a4344..8de4282474 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -64,6 +64,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: true, @@ -89,6 +90,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: false, @@ -552,6 +554,10 @@ func TestStopConsumerChain(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) + + // in case the chain was successfully stopped, it should not contain a Top N associated to it + _, found := providerKeeper.GetTopN(ctx, "chainID") + require.False(t, found) } testkeeper.TestProviderStateIsCleanedAfterConsumerChainIsStopped(t, ctx, providerKeeper, "chainID", "channelID") @@ -924,6 +930,7 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 67, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "spawn time passed", "chain2", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, @@ -935,6 +942,7 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "spawn time not passed", "chain3", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, @@ -946,6 +954,7 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "invalid proposal: chain id already exists", "chain2", clienttypes.NewHeight(4, 5), []byte{}, []byte{}, @@ -957,6 +966,7 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ).(*providertypes.ConsumerAdditionProposal), } @@ -989,6 +999,13 @@ func TestBeginBlockInit(t *testing.T) { _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[3].SpawnTime, pendingProps[3].ChainId) require.False(t, found) + + // test that Top N is set correctly + require.True(t, providerKeeper.IsTopN(ctx, "chain1")) + topN, found := providerKeeper.GetTopN(ctx, "chain1") + require.Equal(t, uint32(67), topN) + + require.True(t, providerKeeper.IsOptIn(ctx, "chain2")) } // TestBeginBlockCCR tests BeginBlockCCR against the spec. @@ -1058,6 +1075,7 @@ func TestBeginBlockCCR(t *testing.T) { // // Test execution // + providerKeeper.BeginBlockCCR(ctx) // Only the 3rd (final) proposal is still stored as pending diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 65e84ac661..30c1793360 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -44,6 +44,7 @@ func TestProviderProposalHandler(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ), blockTime: hourFromNow, // ctx blocktime is after proposal's spawn time expValidConsumerAddition: true, diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index e9222ade98..125ad4a473 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -150,6 +150,9 @@ const ( // ConsumerValidatorBytePrefix is the byte prefix used when storing for each consumer chain all the consumer validators in this epoch ConsumerValidatorBytePrefix + // TopNBytePrefix is the byte prefix storing the mapping from a consumer chain to the N value of this chain, + // that corresponds to the N% of the top validators that have to validate this consumer chain + TopNBytePrefix // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -522,6 +525,11 @@ func ConsumerValidatorKey(chainID string, providerAddr []byte) []byte { return append(prefix, providerAddr...) } +// TopNKey returns the key of consumer chain `chainID` +func TopNKey(chainID string) []byte { + return ChainIdWithLenKey(TopNBytePrefix, chainID) +} + // // End of generic helpers section // diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index 02faa9a640..da2dbbea31 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -57,6 +57,7 @@ func getAllKeyPrefixes() []byte { providertypes.EquivocationEvidenceMinHeightBytePrefix, providertypes.ProposedConsumerChainByteKey, providertypes.ConsumerValidatorBytePrefix, + providertypes.TopNBytePrefix, } } diff --git a/x/ccv/provider/types/proposal.go b/x/ccv/provider/types/proposal.go index 93cadfd14e..10f3a88865 100644 --- a/x/ccv/provider/types/proposal.go +++ b/x/ccv/provider/types/proposal.go @@ -49,6 +49,7 @@ func NewConsumerAdditionProposal(title, description, chainID string, ccvTimeoutPeriod time.Duration, transferTimeoutPeriod time.Duration, unbondingPeriod time.Duration, + topN uint32, ) govv1beta1.Content { return &ConsumerAdditionProposal{ Title: title, @@ -65,6 +66,7 @@ func NewConsumerAdditionProposal(title, description, chainID string, CcvTimeoutPeriod: ccvTimeoutPeriod, TransferTimeoutPeriod: transferTimeoutPeriod, UnbondingPeriod: unbondingPeriod, + Top_N: topN, } } @@ -135,6 +137,12 @@ func (cccp *ConsumerAdditionProposal) ValidateBasic() error { return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "unbonding period cannot be zero") } + // Top N corresponds to the top N% of validators that have to validate the consumer chain and can only be 0 (for an + // Opt In chain) or in the range [50, 100] (for a Top N chain). + if cccp.Top_N != 0 && cccp.Top_N < 50 || cccp.Top_N > 100 { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "Top N can either be 0 or in the range [50, 100]") + } + return nil } diff --git a/x/ccv/provider/types/proposal_test.go b/x/ccv/provider/types/proposal_test.go index 72fcfe8436..13e7edb11e 100644 --- a/x/ccv/provider/types/proposal_test.go +++ b/x/ccv/provider/types/proposal_test.go @@ -36,6 +36,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, ), true, }, @@ -48,7 +49,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), true, }, { @@ -60,7 +62,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -72,7 +75,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -104,7 +108,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -116,7 +121,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -128,7 +134,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -140,7 +147,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -152,7 +160,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 10000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -164,7 +173,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -176,7 +186,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { -2, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -188,7 +199,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 0, 100000000000, - 100000000000), + 100000000000, + 0), false, }, { @@ -200,7 +212,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 0, - 100000000000), + 100000000000, + 0), false, }, { @@ -212,6 +225,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, + 0, 0), false, }, @@ -236,7 +250,8 @@ func TestMarshalConsumerAdditionProposal(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000) + 100000000000, + 0) cccp, ok := content.(*types.ConsumerAdditionProposal) require.True(t, ok) @@ -278,7 +293,8 @@ func TestConsumerAdditionProposalString(t *testing.T) { 500000, 100000000000, 10000000000, - 100000000000) + 100000000000, + 0) expect := fmt.Sprintf(`CreateConsumerChain Proposal Title: title diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index 819154b75d..2ef5f607d0 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -90,6 +90,11 @@ type ConsumerAdditionProposal struct { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintain the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,14,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,15,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` } func (m *ConsumerAdditionProposal) Reset() { *m = ConsumerAdditionProposal{} } @@ -1395,7 +1400,7 @@ func (m *ConsumerAddrsToPrune) GetConsumerAddrs() *AddressList { } // ConsumerValidator is used to facilitate epoch-based transitions. It contains relevant info for -// a validator that is opted in, in an epoch, on a consumer chain. +// a validator that is expected to validate on a consumer chain during an epoch. type ConsumerValidator struct { // validator's consensus address on the provider chain ProviderConsAddr []byte `protobuf:"bytes,1,opt,name=provider_cons_addr,json=providerConsAddr,proto3" json:"provider_cons_addr,omitempty"` @@ -1490,117 +1495,118 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1755 bytes of a gzipped FileDescriptorProto + // 1776 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4f, 0x6f, 0x1b, 0xc7, - 0x15, 0xd7, 0x92, 0x94, 0x2c, 0x3e, 0x4a, 0x94, 0xb4, 0x52, 0xe2, 0x95, 0xab, 0x52, 0xf2, 0xa6, - 0x49, 0x55, 0xa4, 0x59, 0x56, 0x4a, 0x0b, 0x04, 0x46, 0x83, 0x40, 0xa2, 0x9c, 0x58, 0x56, 0x12, + 0x15, 0xd7, 0x8a, 0x94, 0x2c, 0x3e, 0x4a, 0x94, 0xb4, 0x52, 0xe2, 0x95, 0xab, 0x52, 0xf4, 0xa6, + 0x49, 0x55, 0xa4, 0x59, 0x56, 0x4a, 0x0b, 0x04, 0x46, 0x83, 0x40, 0xa2, 0x9c, 0x58, 0x56, 0x62, 0x2b, 0x2b, 0x55, 0x46, 0xdb, 0xc3, 0x62, 0x38, 0x3b, 0x26, 0x07, 0x5a, 0xee, 0xac, 0x67, 0x66, 0xd7, 0xe1, 0xa5, 0xe7, 0x1e, 0xd3, 0x5b, 0xd0, 0x4b, 0xd3, 0x02, 0x3d, 0xf7, 0x6b, 0xe4, 0x98, - 0x63, 0x4f, 0x49, 0x61, 0x1f, 0xfb, 0x25, 0x8a, 0x99, 0xfd, 0x4b, 0x4a, 0x72, 0x69, 0xb8, 0xbd, - 0xcd, 0xbe, 0x79, 0xef, 0xf7, 0xfe, 0xbf, 0x37, 0x24, 0xec, 0xd3, 0x50, 0x12, 0x8e, 0x87, 0x88, - 0x86, 0x9e, 0x20, 0x38, 0xe6, 0x54, 0x8e, 0xbb, 0x18, 0x27, 0xdd, 0x88, 0xb3, 0x84, 0xfa, 0x84, - 0x77, 0x93, 0xbd, 0xe2, 0xec, 0x44, 0x9c, 0x49, 0x66, 0xbe, 0x75, 0x8d, 0x8c, 0x83, 0x71, 0xe2, - 0x14, 0x7c, 0xc9, 0xde, 0x9d, 0xb7, 0x6f, 0x02, 0x4e, 0xf6, 0xba, 0xcf, 0x28, 0x27, 0x29, 0xd6, - 0x9d, 0x8d, 0x01, 0x1b, 0x30, 0x7d, 0xec, 0xaa, 0x53, 0x46, 0xdd, 0x1e, 0x30, 0x36, 0x08, 0x48, - 0x57, 0x7f, 0xf5, 0xe3, 0x27, 0x5d, 0x49, 0x47, 0x44, 0x48, 0x34, 0x8a, 0x32, 0x86, 0xce, 0x34, - 0x83, 0x1f, 0x73, 0x24, 0x29, 0x0b, 0x73, 0x00, 0xda, 0xc7, 0x5d, 0xcc, 0x38, 0xe9, 0xe2, 0x80, - 0x92, 0x50, 0x2a, 0xad, 0xe9, 0x29, 0x63, 0xe8, 0x2a, 0x86, 0x80, 0x0e, 0x86, 0x32, 0x25, 0x8b, - 0xae, 0x24, 0xa1, 0x4f, 0xf8, 0x88, 0xa6, 0xcc, 0xe5, 0x57, 0x26, 0xb0, 0x55, 0xb9, 0xc7, 0x7c, - 0x1c, 0x49, 0xd6, 0xbd, 0x24, 0x63, 0x91, 0xdd, 0xbe, 0x83, 0x99, 0x18, 0x31, 0xd1, 0x25, 0xca, - 0xff, 0x10, 0x93, 0x6e, 0xb2, 0xd7, 0x27, 0x12, 0xed, 0x15, 0x84, 0xdc, 0xee, 0x8c, 0xaf, 0x8f, - 0x44, 0xc9, 0x83, 0x19, 0xcd, 0xec, 0xb6, 0x7f, 0x58, 0x00, 0xab, 0xc7, 0x42, 0x11, 0x8f, 0x08, - 0x3f, 0xf0, 0x7d, 0xaa, 0x5c, 0x3a, 0xe5, 0x2c, 0x62, 0x02, 0x05, 0xe6, 0x06, 0xcc, 0x4b, 0x2a, - 0x03, 0x62, 0x19, 0x3b, 0xc6, 0x6e, 0xd3, 0x4d, 0x3f, 0xcc, 0x1d, 0x68, 0xf9, 0x44, 0x60, 0x4e, - 0x23, 0xc5, 0x6c, 0xd5, 0xf4, 0x5d, 0x95, 0x64, 0x6e, 0xc2, 0x62, 0x9a, 0x07, 0xea, 0x5b, 0x75, - 0x7d, 0x7d, 0x4b, 0x7f, 0x1f, 0xfb, 0xe6, 0x27, 0xd0, 0xa6, 0x21, 0x95, 0x14, 0x05, 0xde, 0x90, - 0xa8, 0x68, 0x58, 0x8d, 0x1d, 0x63, 0xb7, 0xb5, 0x7f, 0xc7, 0xa1, 0x7d, 0xec, 0xa8, 0x00, 0x3a, - 0x59, 0xd8, 0x92, 0x3d, 0xe7, 0x81, 0xe6, 0x38, 0x6c, 0x7c, 0xfb, 0xfd, 0xf6, 0x9c, 0xbb, 0x9c, - 0xc9, 0xa5, 0x44, 0xf3, 0x2e, 0x2c, 0x0d, 0x48, 0x48, 0x04, 0x15, 0xde, 0x10, 0x89, 0xa1, 0x35, - 0xbf, 0x63, 0xec, 0x2e, 0xb9, 0xad, 0x8c, 0xf6, 0x00, 0x89, 0xa1, 0xb9, 0x0d, 0xad, 0x3e, 0x0d, - 0x11, 0x1f, 0xa7, 0x1c, 0x0b, 0x9a, 0x03, 0x52, 0x92, 0x66, 0xe8, 0x01, 0x88, 0x08, 0x3d, 0x0b, - 0x3d, 0x95, 0x6d, 0xeb, 0x56, 0x66, 0x48, 0x9a, 0x69, 0x27, 0xcf, 0xb4, 0x73, 0x9e, 0x97, 0xc2, - 0xe1, 0xa2, 0x32, 0xe4, 0xab, 0x1f, 0xb6, 0x0d, 0xb7, 0xa9, 0xe5, 0xd4, 0x8d, 0xf9, 0x39, 0xac, - 0xc6, 0x61, 0x9f, 0x85, 0x3e, 0x0d, 0x07, 0x5e, 0x44, 0x38, 0x65, 0xbe, 0xb5, 0xa8, 0xa1, 0x36, - 0xaf, 0x40, 0x1d, 0x65, 0x45, 0x93, 0x22, 0x7d, 0xad, 0x90, 0x56, 0x0a, 0xe1, 0x53, 0x2d, 0x6b, - 0x7e, 0x01, 0x26, 0xc6, 0x89, 0x36, 0x89, 0xc5, 0x32, 0x47, 0x6c, 0xce, 0x8e, 0xb8, 0x8a, 0x71, - 0x72, 0x9e, 0x4a, 0x67, 0x90, 0xbf, 0x87, 0xdb, 0x92, 0xa3, 0x50, 0x3c, 0x21, 0x7c, 0x1a, 0x17, - 0x66, 0xc7, 0x7d, 0x23, 0xc7, 0x98, 0x04, 0x7f, 0x00, 0x3b, 0x38, 0x2b, 0x20, 0x8f, 0x13, 0x9f, - 0x0a, 0xc9, 0x69, 0x3f, 0x56, 0xb2, 0xde, 0x13, 0x8e, 0xb0, 0xae, 0x91, 0x96, 0x2e, 0x82, 0x4e, - 0xce, 0xe7, 0x4e, 0xb0, 0x7d, 0x9c, 0x71, 0x99, 0x8f, 0xe0, 0x27, 0xfd, 0x80, 0xe1, 0x4b, 0xa1, - 0x8c, 0xf3, 0x26, 0x90, 0xb4, 0xea, 0x11, 0x15, 0x42, 0xa1, 0x2d, 0xed, 0x18, 0xbb, 0x75, 0xf7, - 0x6e, 0xca, 0x7b, 0x4a, 0xf8, 0x51, 0x85, 0xf3, 0xbc, 0xc2, 0x68, 0xbe, 0x07, 0xe6, 0x90, 0x0a, - 0xc9, 0x38, 0xc5, 0x28, 0xf0, 0x48, 0x28, 0x39, 0x25, 0xc2, 0x5a, 0xd6, 0xe2, 0x6b, 0xe5, 0xcd, - 0xfd, 0xf4, 0xc2, 0x7c, 0x08, 0x77, 0x6f, 0x54, 0xea, 0xe1, 0x21, 0x0a, 0x43, 0x12, 0x58, 0x6d, - 0xed, 0xca, 0xb6, 0x7f, 0x83, 0xce, 0x5e, 0xca, 0x76, 0x6f, 0xf1, 0x8f, 0xdf, 0x6c, 0xcf, 0x7d, - 0xfd, 0xcd, 0xf6, 0x9c, 0xfd, 0x0f, 0x03, 0x6e, 0xf7, 0x0a, 0xc7, 0x47, 0x2c, 0x41, 0xc1, 0xff, - 0xb3, 0xc1, 0x0e, 0xa0, 0x29, 0x24, 0x8b, 0xd2, 0x92, 0x6e, 0xbc, 0x42, 0x49, 0x2f, 0x2a, 0x31, - 0x75, 0x61, 0xff, 0xc5, 0x80, 0x8d, 0xfb, 0x4f, 0x63, 0x9a, 0x30, 0x8c, 0xfe, 0x27, 0xf3, 0xe0, - 0x04, 0x96, 0x49, 0x05, 0x4f, 0x58, 0xf5, 0x9d, 0xfa, 0x6e, 0x6b, 0xff, 0x6d, 0x27, 0x1d, 0x4e, - 0x4e, 0x31, 0xb3, 0xb2, 0x01, 0xe5, 0x54, 0xb5, 0xbb, 0x93, 0xb2, 0xf7, 0x6a, 0x96, 0x61, 0xff, - 0xcd, 0x80, 0x3b, 0x2a, 0xd2, 0x03, 0xe2, 0x92, 0x67, 0x88, 0xfb, 0x47, 0x24, 0x64, 0x23, 0xf1, - 0xda, 0x76, 0xda, 0xb0, 0xec, 0x6b, 0x24, 0x4f, 0x32, 0x0f, 0xf9, 0xbe, 0xb6, 0x53, 0xf3, 0x28, - 0xe2, 0x39, 0x3b, 0xf0, 0x7d, 0x73, 0x17, 0x56, 0x4b, 0x1e, 0xae, 0xf2, 0xa9, 0xc2, 0xac, 0xd8, - 0xda, 0x39, 0x9b, 0xce, 0x32, 0xb1, 0xff, 0x6d, 0xc0, 0xea, 0x27, 0x01, 0xeb, 0xa3, 0xe0, 0x2c, - 0x40, 0x62, 0xa8, 0xaa, 0x6c, 0xac, 0xd2, 0xc3, 0x49, 0xd6, 0xde, 0xda, 0xbc, 0x99, 0xd3, 0xa3, - 0xc4, 0xf4, 0xc0, 0xf9, 0x08, 0xd6, 0x8a, 0x86, 0x2b, 0xaa, 0x40, 0x7b, 0x73, 0xb8, 0xfe, 0xfc, - 0xfb, 0xed, 0x95, 0xbc, 0xd8, 0x7a, 0xba, 0x22, 0x8e, 0xdc, 0x15, 0x3c, 0x41, 0xf0, 0xcd, 0x0e, - 0xb4, 0x68, 0x1f, 0x7b, 0x82, 0x3c, 0xf5, 0xc2, 0x78, 0xa4, 0x0b, 0xa8, 0xe1, 0x36, 0x69, 0x1f, - 0x9f, 0x91, 0xa7, 0x9f, 0xc7, 0x23, 0xf3, 0x7d, 0x78, 0x33, 0x5f, 0xac, 0x5e, 0x82, 0x02, 0x4f, - 0xc9, 0xab, 0x70, 0x70, 0x5d, 0x4f, 0x4b, 0xee, 0x7a, 0x7e, 0x7b, 0x81, 0x02, 0xa5, 0xec, 0xc0, - 0xf7, 0xb9, 0xfd, 0x62, 0x1e, 0x16, 0x4e, 0x11, 0x47, 0x23, 0x61, 0x9e, 0xc3, 0x8a, 0x24, 0xa3, - 0x28, 0x40, 0x92, 0x78, 0xe9, 0x30, 0xcf, 0x3c, 0x7d, 0x57, 0x0f, 0xf9, 0xea, 0x12, 0x74, 0x2a, - 0x6b, 0x2f, 0xd9, 0x73, 0x7a, 0x9a, 0x7a, 0x26, 0x91, 0x24, 0x6e, 0x3b, 0xc7, 0x48, 0x89, 0xe6, - 0x07, 0x60, 0x49, 0x1e, 0x0b, 0x59, 0x8e, 0xd9, 0x72, 0xbe, 0xa4, 0xb9, 0x7c, 0x33, 0xbf, 0x4f, - 0x27, 0x53, 0x31, 0x57, 0xae, 0x9f, 0xa8, 0xf5, 0xd7, 0x99, 0xa8, 0x67, 0xb0, 0xae, 0xd6, 0xd1, - 0x34, 0x66, 0x63, 0x76, 0xcc, 0x35, 0x25, 0x3f, 0x09, 0xfa, 0x05, 0x98, 0x89, 0xc0, 0xd3, 0x98, - 0xf3, 0xaf, 0x60, 0x67, 0x22, 0xf0, 0x24, 0xa4, 0x0f, 0x5b, 0x42, 0x15, 0x9f, 0x37, 0x22, 0x52, - 0xcf, 0xe7, 0x28, 0x20, 0x21, 0x15, 0xc3, 0x1c, 0x7c, 0x61, 0x76, 0xf0, 0x4d, 0x0d, 0xf4, 0x99, - 0xc2, 0x71, 0x73, 0x98, 0x4c, 0x4b, 0x0f, 0x3a, 0xd7, 0x6b, 0x29, 0x12, 0x74, 0x4b, 0x27, 0xe8, - 0x47, 0xd7, 0x40, 0x14, 0x59, 0x12, 0xf0, 0x4e, 0x65, 0x8f, 0xa8, 0xae, 0xf6, 0x74, 0x43, 0x79, - 0x9c, 0x0c, 0xd4, 0xb0, 0x45, 0xe9, 0x4a, 0x21, 0xa4, 0xd8, 0x85, 0xd9, 0xf4, 0x50, 0x4f, 0x9b, - 0x62, 0x72, 0xf4, 0x18, 0x0d, 0xb3, 0x07, 0x83, 0x5d, 0xae, 0x9b, 0x62, 0x46, 0xb8, 0x15, 0xac, - 0x8f, 0x09, 0x51, 0xdd, 0x5c, 0x59, 0x39, 0x24, 0x62, 0x78, 0xa8, 0x57, 0x62, 0xdd, 0x6d, 0x17, - 0xeb, 0xe5, 0xbe, 0xa2, 0x3e, 0x6c, 0x2c, 0x2e, 0xae, 0x36, 0xed, 0x9f, 0x41, 0x53, 0x37, 0xf3, - 0x01, 0xbe, 0x14, 0xe6, 0x16, 0x34, 0x55, 0x57, 0x10, 0x21, 0x88, 0xb0, 0x0c, 0x3d, 0x03, 0x4a, - 0x82, 0x2d, 0x61, 0xf3, 0xa6, 0x87, 0x95, 0x30, 0x1f, 0xc3, 0xad, 0x88, 0xe8, 0xad, 0xaf, 0x05, - 0x5b, 0xfb, 0x1f, 0x3a, 0x33, 0xbc, 0x71, 0x9d, 0x9b, 0x00, 0xdd, 0x1c, 0xcd, 0xe6, 0xe5, 0x73, - 0x6e, 0x6a, 0xd9, 0x08, 0xf3, 0x62, 0x5a, 0xe9, 0xaf, 0x5f, 0x49, 0xe9, 0x14, 0x5e, 0xa9, 0xf3, - 0x5d, 0x68, 0x1d, 0xa4, 0x6e, 0x7f, 0x4a, 0x85, 0xbc, 0x1a, 0x96, 0xa5, 0x6a, 0x58, 0x1e, 0x42, - 0x3b, 0xdb, 0x91, 0xe7, 0x4c, 0x0f, 0x24, 0xf3, 0xc7, 0x00, 0xd9, 0x72, 0x55, 0x83, 0x2c, 0x1d, - 0xd9, 0xcd, 0x8c, 0x72, 0xec, 0x4f, 0xec, 0xba, 0xda, 0xc4, 0xae, 0xb3, 0x5d, 0x58, 0xb9, 0x10, - 0xf8, 0x37, 0xf9, 0x03, 0xea, 0x51, 0x24, 0xcc, 0x37, 0x60, 0x41, 0xf5, 0x50, 0x06, 0xd4, 0x70, - 0xe7, 0x13, 0x81, 0x8f, 0xf5, 0xd4, 0x2e, 0x1f, 0x69, 0x2c, 0xf2, 0xa8, 0x2f, 0xac, 0xda, 0x4e, - 0x7d, 0xb7, 0xe1, 0xb6, 0xe3, 0x52, 0xfc, 0xd8, 0x17, 0xf6, 0x6f, 0xa1, 0x55, 0x01, 0x34, 0xdb, - 0x50, 0x2b, 0xb0, 0x6a, 0xd4, 0x37, 0xef, 0xc1, 0x66, 0x09, 0x34, 0x39, 0x86, 0x53, 0xc4, 0xa6, - 0x7b, 0xbb, 0x60, 0x98, 0x98, 0xc4, 0xc2, 0x7e, 0x04, 0x1b, 0xc7, 0x65, 0xd3, 0x17, 0x43, 0x7e, - 0xc2, 0x43, 0x63, 0x72, 0x9b, 0x6f, 0x41, 0xb3, 0xf8, 0x25, 0xa2, 0xbd, 0x6f, 0xb8, 0x25, 0xc1, - 0x1e, 0xc1, 0xea, 0x85, 0xc0, 0x67, 0x24, 0xf4, 0x4b, 0xb0, 0x1b, 0x02, 0x70, 0x38, 0x0d, 0x34, - 0xf3, 0x4b, 0xb7, 0x54, 0xc7, 0x60, 0xf3, 0x02, 0x05, 0xd4, 0x47, 0x92, 0xf1, 0x33, 0x22, 0xd3, - 0x05, 0x7c, 0x8a, 0xf0, 0x25, 0x91, 0xc2, 0x74, 0xa1, 0x11, 0x50, 0x21, 0xb3, 0xca, 0xfa, 0xe0, - 0xc6, 0xca, 0x4a, 0xf6, 0x9c, 0x9b, 0x40, 0x8e, 0x90, 0x44, 0x59, 0xef, 0x6a, 0x2c, 0xfb, 0xa7, - 0xb0, 0xfe, 0x19, 0x92, 0x31, 0x27, 0xfe, 0x44, 0x8e, 0x57, 0xa1, 0xae, 0xf2, 0x67, 0xe8, 0xfc, - 0xa9, 0xa3, 0x7a, 0x0f, 0x58, 0xf7, 0xbf, 0x8c, 0x18, 0x97, 0xc4, 0xbf, 0x12, 0x91, 0x97, 0x84, - 0xf7, 0x12, 0xd6, 0x55, 0xb0, 0x04, 0x09, 0x7d, 0xaf, 0xf0, 0x33, 0xcd, 0x63, 0x6b, 0xff, 0x57, - 0x33, 0x75, 0xc7, 0xb4, 0xba, 0xcc, 0x81, 0xb5, 0x64, 0x8a, 0x2e, 0xec, 0x3f, 0x19, 0x60, 0x9d, - 0x90, 0xf1, 0x81, 0x10, 0x74, 0x10, 0x8e, 0x48, 0x28, 0xd5, 0x0c, 0x44, 0x98, 0xa8, 0xa3, 0xf9, - 0x16, 0x2c, 0x17, 0x3b, 0x57, 0xaf, 0x5a, 0x43, 0xaf, 0xda, 0xa5, 0x9c, 0xa8, 0x1a, 0xcc, 0xbc, - 0x07, 0x10, 0x71, 0x92, 0x78, 0xd8, 0xbb, 0x24, 0xe3, 0x2c, 0x8b, 0x5b, 0xd5, 0x15, 0x9a, 0xfe, - 0x4e, 0x74, 0x4e, 0xe3, 0x7e, 0x40, 0xf1, 0x09, 0x19, 0xbb, 0x8b, 0x8a, 0xbf, 0x77, 0x42, 0xc6, - 0xea, 0x4d, 0x14, 0xb1, 0x67, 0x84, 0xeb, 0xbd, 0x57, 0x77, 0xd3, 0x0f, 0xfb, 0xcf, 0x06, 0xdc, - 0x2e, 0xd2, 0x91, 0x97, 0xeb, 0x69, 0xdc, 0x57, 0x12, 0x2f, 0x89, 0xdb, 0x15, 0x6b, 0x6b, 0xd7, - 0x58, 0xfb, 0x11, 0x2c, 0x15, 0x0d, 0xa2, 0xec, 0xad, 0xcf, 0x60, 0x6f, 0x2b, 0x97, 0x38, 0x21, - 0x63, 0xfb, 0x0f, 0x15, 0xdb, 0x0e, 0xc7, 0x95, 0xd9, 0xc7, 0xff, 0x8b, 0x6d, 0x85, 0xda, 0xaa, - 0x6d, 0xb8, 0x2a, 0x7f, 0xc5, 0x81, 0xfa, 0x55, 0x07, 0xec, 0xbf, 0x1a, 0xb0, 0x51, 0xd5, 0x2a, - 0xce, 0xd9, 0x29, 0x8f, 0x43, 0xf2, 0x32, 0xed, 0x65, 0xfb, 0xd5, 0xaa, 0xed, 0xf7, 0x18, 0xda, - 0x13, 0x46, 0x89, 0x2c, 0x1a, 0xbf, 0x98, 0xa9, 0xc6, 0x2a, 0xd3, 0xd5, 0x5d, 0xae, 0xfa, 0x21, - 0xec, 0xbf, 0x1b, 0xb0, 0x96, 0xdb, 0x58, 0x04, 0xcb, 0xfc, 0x39, 0x98, 0x85, 0x7b, 0xe5, 0xeb, - 0x2d, 0x2d, 0xa9, 0xd5, 0xfc, 0x26, 0x7f, 0xba, 0x95, 0xa5, 0x51, 0xab, 0x94, 0x86, 0xf9, 0x29, - 0xac, 0x17, 0x26, 0x47, 0x3a, 0x41, 0x33, 0x67, 0xb1, 0x78, 0x9f, 0x16, 0xa4, 0xc3, 0xc7, 0xdf, - 0x3e, 0xef, 0x18, 0xdf, 0x3d, 0xef, 0x18, 0xff, 0x7a, 0xde, 0x31, 0xbe, 0x7a, 0xd1, 0x99, 0xfb, - 0xee, 0x45, 0x67, 0xee, 0x9f, 0x2f, 0x3a, 0x73, 0xbf, 0xfb, 0x70, 0x40, 0xe5, 0x30, 0xee, 0x3b, - 0x98, 0x8d, 0xba, 0xd9, 0x9f, 0x15, 0x65, 0x4c, 0xde, 0x2b, 0xfe, 0xc9, 0x49, 0x7e, 0xd9, 0xfd, - 0x72, 0xf2, 0x7f, 0x22, 0x39, 0x8e, 0x88, 0xe8, 0x2f, 0xe8, 0xe9, 0xf5, 0xfe, 0x7f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0x0a, 0xef, 0x81, 0x2b, 0x58, 0x12, 0x00, 0x00, + 0x63, 0x4f, 0x69, 0x61, 0x1f, 0x7b, 0xed, 0x07, 0x28, 0x66, 0xf6, 0x2f, 0x29, 0xc9, 0xa5, 0x91, + 0xf6, 0xb6, 0x7c, 0xf3, 0xde, 0xef, 0xbd, 0x79, 0x7f, 0x7e, 0x6f, 0x24, 0xd8, 0xa7, 0xa1, 0x24, + 0x1c, 0x0f, 0x11, 0x0d, 0x3d, 0x41, 0x70, 0xcc, 0xa9, 0x1c, 0x77, 0x31, 0x4e, 0xba, 0x11, 0x67, + 0x09, 0xf5, 0x09, 0xef, 0x26, 0x7b, 0xc5, 0xb7, 0x13, 0x71, 0x26, 0x99, 0xf9, 0xd6, 0x35, 0x36, + 0x0e, 0xc6, 0x89, 0x53, 0xe8, 0x25, 0x7b, 0x77, 0xde, 0xbe, 0x09, 0x38, 0xd9, 0xeb, 0x3e, 0xa7, + 0x9c, 0xa4, 0x58, 0x77, 0x36, 0x07, 0x6c, 0xc0, 0xf4, 0x67, 0x57, 0x7d, 0x65, 0xd2, 0x9d, 0x01, + 0x63, 0x83, 0x80, 0x74, 0xf5, 0xaf, 0x7e, 0xfc, 0xb4, 0x2b, 0xe9, 0x88, 0x08, 0x89, 0x46, 0x51, + 0xa6, 0xd0, 0x9e, 0x56, 0xf0, 0x63, 0x8e, 0x24, 0x65, 0x61, 0x0e, 0x40, 0xfb, 0xb8, 0x8b, 0x19, + 0x27, 0x5d, 0x1c, 0x50, 0x12, 0x4a, 0xe5, 0x35, 0xfd, 0xca, 0x14, 0xba, 0x4a, 0x21, 0xa0, 0x83, + 0xa1, 0x4c, 0xc5, 0xa2, 0x2b, 0x49, 0xe8, 0x13, 0x3e, 0xa2, 0xa9, 0x72, 0xf9, 0x2b, 0x33, 0xd8, + 0xae, 0x9c, 0x63, 0x3e, 0x8e, 0x24, 0xeb, 0x5e, 0x92, 0xb1, 0xc8, 0x4e, 0xdf, 0xc1, 0x4c, 0x8c, + 0x98, 0xe8, 0x12, 0x75, 0xff, 0x10, 0x93, 0x6e, 0xb2, 0xd7, 0x27, 0x12, 0xed, 0x15, 0x82, 0x3c, + 0xee, 0x4c, 0xaf, 0x8f, 0x44, 0xa9, 0x83, 0x19, 0xcd, 0xe2, 0xb6, 0xff, 0xbd, 0x08, 0x56, 0x8f, + 0x85, 0x22, 0x1e, 0x11, 0x7e, 0xe0, 0xfb, 0x54, 0x5d, 0xe9, 0x94, 0xb3, 0x88, 0x09, 0x14, 0x98, + 0x9b, 0xb0, 0x20, 0xa9, 0x0c, 0x88, 0x65, 0x74, 0x8c, 0xdd, 0x86, 0x9b, 0xfe, 0x30, 0x3b, 0xd0, + 0xf4, 0x89, 0xc0, 0x9c, 0x46, 0x4a, 0xd9, 0x9a, 0xd7, 0x67, 0x55, 0x91, 0xb9, 0x05, 0x4b, 0x69, + 0x1d, 0xa8, 0x6f, 0xd5, 0xf4, 0xf1, 0x2d, 0xfd, 0xfb, 0xd8, 0x37, 0x3f, 0x81, 0x16, 0x0d, 0xa9, + 0xa4, 0x28, 0xf0, 0x86, 0x44, 0x65, 0xc3, 0xaa, 0x77, 0x8c, 0xdd, 0xe6, 0xfe, 0x1d, 0x87, 0xf6, + 0xb1, 0xa3, 0x12, 0xe8, 0x64, 0x69, 0x4b, 0xf6, 0x9c, 0x07, 0x5a, 0xe3, 0xb0, 0xfe, 0xcd, 0x77, + 0x3b, 0x73, 0xee, 0x4a, 0x66, 0x97, 0x0a, 0xcd, 0xbb, 0xb0, 0x3c, 0x20, 0x21, 0x11, 0x54, 0x78, + 0x43, 0x24, 0x86, 0xd6, 0x42, 0xc7, 0xd8, 0x5d, 0x76, 0x9b, 0x99, 0xec, 0x01, 0x12, 0x43, 0x73, + 0x07, 0x9a, 0x7d, 0x1a, 0x22, 0x3e, 0x4e, 0x35, 0x16, 0xb5, 0x06, 0xa4, 0x22, 0xad, 0xd0, 0x03, + 0x10, 0x11, 0x7a, 0x1e, 0x7a, 0xaa, 0xda, 0xd6, 0xad, 0x2c, 0x90, 0xb4, 0xd2, 0x4e, 0x5e, 0x69, + 0xe7, 0x3c, 0x6f, 0x85, 0xc3, 0x25, 0x15, 0xc8, 0x97, 0xff, 0xd8, 0x31, 0xdc, 0x86, 0xb6, 0x53, + 0x27, 0xe6, 0x23, 0x58, 0x8b, 0xc3, 0x3e, 0x0b, 0x7d, 0x1a, 0x0e, 0xbc, 0x88, 0x70, 0xca, 0x7c, + 0x6b, 0x49, 0x43, 0x6d, 0x5d, 0x81, 0x3a, 0xca, 0x9a, 0x26, 0x45, 0xfa, 0x4a, 0x21, 0xad, 0x16, + 0xc6, 0xa7, 0xda, 0xd6, 0xfc, 0x1c, 0x4c, 0x8c, 0x13, 0x1d, 0x12, 0x8b, 0x65, 0x8e, 0xd8, 0x98, + 0x1d, 0x71, 0x0d, 0xe3, 0xe4, 0x3c, 0xb5, 0xce, 0x20, 0x7f, 0x0b, 0xb7, 0x25, 0x47, 0xa1, 0x78, + 0x4a, 0xf8, 0x34, 0x2e, 0xcc, 0x8e, 0xfb, 0x46, 0x8e, 0x31, 0x09, 0xfe, 0x00, 0x3a, 0x38, 0x6b, + 0x20, 0x8f, 0x13, 0x9f, 0x0a, 0xc9, 0x69, 0x3f, 0x56, 0xb6, 0xde, 0x53, 0x8e, 0xb0, 0xee, 0x91, + 0xa6, 0x6e, 0x82, 0x76, 0xae, 0xe7, 0x4e, 0xa8, 0x7d, 0x9c, 0x69, 0x99, 0x8f, 0xe1, 0x47, 0xfd, + 0x80, 0xe1, 0x4b, 0xa1, 0x82, 0xf3, 0x26, 0x90, 0xb4, 0xeb, 0x11, 0x15, 0x42, 0xa1, 0x2d, 0x77, + 0x8c, 0xdd, 0x9a, 0x7b, 0x37, 0xd5, 0x3d, 0x25, 0xfc, 0xa8, 0xa2, 0x79, 0x5e, 0x51, 0x34, 0xdf, + 0x03, 0x73, 0x48, 0x85, 0x64, 0x9c, 0x62, 0x14, 0x78, 0x24, 0x94, 0x9c, 0x12, 0x61, 0xad, 0x68, + 0xf3, 0xf5, 0xf2, 0xe4, 0x7e, 0x7a, 0x60, 0x3e, 0x84, 0xbb, 0x37, 0x3a, 0xf5, 0xf0, 0x10, 0x85, + 0x21, 0x09, 0xac, 0x96, 0xbe, 0xca, 0x8e, 0x7f, 0x83, 0xcf, 0x5e, 0xaa, 0x66, 0x6e, 0xc0, 0x82, + 0x64, 0x91, 0xf7, 0xc8, 0x5a, 0xed, 0x18, 0xbb, 0x2b, 0x6e, 0x5d, 0xb2, 0xe8, 0xd1, 0xbd, 0xa5, + 0xdf, 0x7f, 0xbd, 0x33, 0xf7, 0xd5, 0xd7, 0x3b, 0x73, 0xf6, 0xdf, 0x0c, 0xb8, 0xdd, 0x2b, 0xb2, + 0x31, 0x62, 0x09, 0x0a, 0xfe, 0x9f, 0x53, 0x77, 0x00, 0x0d, 0xa1, 0xc2, 0xd1, 0x7d, 0x5e, 0x7f, + 0x8d, 0x3e, 0x5f, 0x52, 0x66, 0xea, 0xc0, 0xfe, 0x93, 0x01, 0x9b, 0xf7, 0x9f, 0xc5, 0x34, 0x61, + 0x18, 0xfd, 0x4f, 0x48, 0xe2, 0x04, 0x56, 0x48, 0x05, 0x4f, 0x58, 0xb5, 0x4e, 0x6d, 0xb7, 0xb9, + 0xff, 0xb6, 0x93, 0x32, 0x96, 0x53, 0x10, 0x59, 0xc6, 0x5a, 0x4e, 0xd5, 0xbb, 0x3b, 0x69, 0x7b, + 0x6f, 0xde, 0x32, 0xec, 0xbf, 0x18, 0x70, 0x47, 0xa5, 0x7f, 0x40, 0x5c, 0xf2, 0x1c, 0x71, 0xff, + 0x88, 0x84, 0x6c, 0x24, 0xbe, 0x77, 0x9c, 0x36, 0xac, 0xf8, 0x1a, 0xc9, 0x93, 0xcc, 0x43, 0xbe, + 0xaf, 0xe3, 0xd4, 0x3a, 0x4a, 0x78, 0xce, 0x0e, 0x7c, 0xdf, 0xdc, 0x85, 0xb5, 0x52, 0x87, 0xab, + 0x7a, 0xaa, 0x34, 0x2b, 0xb5, 0x56, 0xae, 0xa6, 0xab, 0x4c, 0xec, 0x7f, 0x19, 0xb0, 0xf6, 0x49, + 0xc0, 0xfa, 0x28, 0x38, 0x0b, 0x90, 0x18, 0xaa, 0xd6, 0x1b, 0xab, 0xf2, 0x70, 0x92, 0xcd, 0xbc, + 0x0e, 0x6f, 0xe6, 0xf2, 0x28, 0x33, 0xcd, 0x42, 0x1f, 0xc1, 0x7a, 0x31, 0x85, 0x45, 0x17, 0xe8, + 0xdb, 0x1c, 0x6e, 0xbc, 0xf8, 0x6e, 0x67, 0x35, 0x6f, 0xb6, 0x9e, 0xee, 0x88, 0x23, 0x77, 0x15, + 0x4f, 0x08, 0x7c, 0xb3, 0x0d, 0x4d, 0xda, 0xc7, 0x9e, 0x20, 0xcf, 0xbc, 0x30, 0x1e, 0xe9, 0x06, + 0xaa, 0xbb, 0x0d, 0xda, 0xc7, 0x67, 0xe4, 0xd9, 0xa3, 0x78, 0x64, 0xbe, 0x0f, 0x6f, 0xe6, 0xdb, + 0xd6, 0x4b, 0x50, 0xe0, 0x29, 0x7b, 0x95, 0x0e, 0xae, 0xfb, 0x69, 0xd9, 0xdd, 0xc8, 0x4f, 0x2f, + 0x50, 0xa0, 0x9c, 0x1d, 0xf8, 0x3e, 0xb7, 0x5f, 0x2e, 0xc0, 0xe2, 0x29, 0xe2, 0x68, 0x24, 0xcc, + 0x73, 0x58, 0x95, 0x64, 0x14, 0x05, 0x48, 0x12, 0x2f, 0x65, 0xf8, 0xec, 0xa6, 0xef, 0x6a, 0xe6, + 0xaf, 0x6e, 0x46, 0xa7, 0xb2, 0x0b, 0x93, 0x3d, 0xa7, 0xa7, 0xa5, 0x67, 0x12, 0x49, 0xe2, 0xb6, + 0x72, 0x8c, 0x54, 0x68, 0x7e, 0x00, 0x96, 0xe4, 0xb1, 0x90, 0x25, 0xf7, 0x96, 0xa4, 0x93, 0xd6, + 0xf2, 0xcd, 0xfc, 0x3c, 0xa5, 0xab, 0x82, 0x6c, 0xae, 0xa7, 0xd9, 0xda, 0xf7, 0xa1, 0xd9, 0x33, + 0xd8, 0x50, 0x3b, 0x6a, 0x1a, 0xb3, 0x3e, 0x3b, 0xe6, 0xba, 0xb2, 0x9f, 0x04, 0xfd, 0x1c, 0xcc, + 0x44, 0xe0, 0x69, 0xcc, 0x85, 0xd7, 0x88, 0x33, 0x11, 0x78, 0x12, 0xd2, 0x87, 0x6d, 0xa1, 0x9a, + 0xcf, 0x1b, 0x11, 0xa9, 0x49, 0x3b, 0x0a, 0x48, 0x48, 0xc5, 0x30, 0x07, 0x5f, 0x9c, 0x1d, 0x7c, + 0x4b, 0x03, 0x7d, 0xa6, 0x70, 0xdc, 0x1c, 0x26, 0xf3, 0xd2, 0x83, 0xf6, 0xf5, 0x5e, 0x8a, 0x02, + 0xdd, 0xd2, 0x05, 0xfa, 0xc1, 0x35, 0x10, 0x45, 0x95, 0x04, 0xbc, 0x53, 0x59, 0x2e, 0x6a, 0xaa, + 0x3d, 0x3d, 0x50, 0x1e, 0x27, 0x03, 0xc5, 0xc0, 0x28, 0xdd, 0x33, 0x84, 0x14, 0x0b, 0x32, 0x63, + 0x0f, 0xf5, 0xde, 0x29, 0x98, 0xa3, 0xc7, 0x68, 0x98, 0xbd, 0x22, 0xec, 0x72, 0x07, 0x15, 0x1c, + 0xe1, 0x56, 0xb0, 0x3e, 0x26, 0x44, 0x4d, 0x73, 0x65, 0x0f, 0x91, 0x88, 0xe1, 0xa1, 0xde, 0x93, + 0x35, 0xb7, 0x55, 0xec, 0x9c, 0xfb, 0x4a, 0xfa, 0xb0, 0xbe, 0xb4, 0xb4, 0xd6, 0xb0, 0x7f, 0x02, + 0x0d, 0x3d, 0xcc, 0x07, 0xf8, 0x52, 0x98, 0xdb, 0xd0, 0x50, 0x53, 0x41, 0x84, 0x20, 0xc2, 0x32, + 0x34, 0x07, 0x94, 0x02, 0x5b, 0xc2, 0xd6, 0x4d, 0xaf, 0x2d, 0x61, 0x3e, 0x81, 0x5b, 0x11, 0xd1, + 0x4f, 0x01, 0x6d, 0xd8, 0xdc, 0xff, 0xd0, 0x99, 0xe1, 0xe1, 0xeb, 0xdc, 0x04, 0xe8, 0xe6, 0x68, + 0x36, 0x2f, 0xdf, 0x78, 0x53, 0xcb, 0x46, 0x98, 0x17, 0xd3, 0x4e, 0x7f, 0xf9, 0x5a, 0x4e, 0xa7, + 0xf0, 0x4a, 0x9f, 0xef, 0x42, 0xf3, 0x20, 0xbd, 0xf6, 0xa7, 0x54, 0xc8, 0xab, 0x69, 0x59, 0xae, + 0xa6, 0xe5, 0x21, 0xb4, 0xb2, 0xc5, 0x79, 0xce, 0x34, 0x21, 0x99, 0x3f, 0x04, 0xc8, 0x36, 0xae, + 0x22, 0xb2, 0x94, 0xb2, 0x1b, 0x99, 0xe4, 0xd8, 0x9f, 0xd8, 0x75, 0xf3, 0x13, 0xbb, 0xce, 0x76, + 0x61, 0xf5, 0x42, 0xe0, 0x5f, 0xe5, 0xaf, 0xaa, 0xc7, 0x91, 0x30, 0xdf, 0x80, 0x45, 0x35, 0x43, + 0x19, 0x50, 0xdd, 0x5d, 0x48, 0x04, 0x3e, 0xd6, 0xac, 0x5d, 0xbe, 0xdc, 0x58, 0xe4, 0x51, 0x5f, + 0x58, 0xf3, 0x9d, 0xda, 0x6e, 0xdd, 0x6d, 0xc5, 0xa5, 0xf9, 0xb1, 0x2f, 0xec, 0x5f, 0x43, 0xb3, + 0x02, 0x68, 0xb6, 0x60, 0xbe, 0xc0, 0x9a, 0xa7, 0xbe, 0x79, 0x0f, 0xb6, 0x4a, 0xa0, 0x49, 0x1a, + 0x4e, 0x11, 0x1b, 0xee, 0xed, 0x42, 0x61, 0x82, 0x89, 0x85, 0xfd, 0x18, 0x36, 0x8f, 0xcb, 0xa1, + 0x2f, 0x48, 0x7e, 0xe2, 0x86, 0xc6, 0xe4, 0x36, 0xdf, 0x86, 0x46, 0xf1, 0xe7, 0x89, 0xbe, 0x7d, + 0xdd, 0x2d, 0x05, 0xf6, 0x08, 0xd6, 0x2e, 0x04, 0x3e, 0x23, 0xa1, 0x5f, 0x82, 0xdd, 0x90, 0x80, + 0xc3, 0x69, 0xa0, 0x99, 0x9f, 0xbf, 0xa5, 0x3b, 0x06, 0x5b, 0x17, 0x28, 0xa0, 0x3e, 0x92, 0x8c, + 0x9f, 0x11, 0x99, 0x2e, 0xe0, 0x53, 0x84, 0x2f, 0x89, 0x14, 0xa6, 0x0b, 0xf5, 0x80, 0x0a, 0x99, + 0x75, 0xd6, 0x07, 0x37, 0x76, 0x56, 0xb2, 0xe7, 0xdc, 0x04, 0x72, 0x84, 0x24, 0xca, 0x66, 0x57, + 0x63, 0xd9, 0x3f, 0x86, 0x8d, 0xcf, 0x90, 0x8c, 0x39, 0xf1, 0x27, 0x6a, 0xbc, 0x06, 0x35, 0x55, + 0x3f, 0x43, 0xd7, 0x4f, 0x7d, 0xaa, 0xf7, 0x80, 0x75, 0xff, 0x8b, 0x88, 0x71, 0x49, 0xfc, 0x2b, + 0x19, 0x79, 0x45, 0x7a, 0x2f, 0x61, 0x43, 0x25, 0x4b, 0x90, 0xd0, 0xf7, 0x8a, 0x7b, 0xa6, 0x75, + 0x6c, 0xee, 0xff, 0x62, 0xa6, 0xe9, 0x98, 0x76, 0x97, 0x5d, 0x60, 0x3d, 0x99, 0x92, 0x0b, 0xfb, + 0x0f, 0x06, 0x58, 0x27, 0x64, 0x7c, 0x20, 0x04, 0x1d, 0x84, 0x23, 0x12, 0x4a, 0xc5, 0x81, 0x08, + 0x13, 0xf5, 0x69, 0xbe, 0x05, 0x2b, 0xc5, 0xce, 0xd5, 0xab, 0xd6, 0xd0, 0xab, 0x76, 0x39, 0x17, + 0xaa, 0x01, 0x33, 0xef, 0x01, 0x44, 0x9c, 0x24, 0x1e, 0xf6, 0x2e, 0xc9, 0x38, 0xab, 0xe2, 0x76, + 0x75, 0x85, 0xa6, 0x7f, 0x3c, 0x3a, 0xa7, 0x71, 0x3f, 0xa0, 0xf8, 0x84, 0x8c, 0xdd, 0x25, 0xa5, + 0xdf, 0x3b, 0x21, 0x63, 0xf5, 0x26, 0x8a, 0xd8, 0x73, 0xc2, 0xf5, 0xde, 0xab, 0xb9, 0xe9, 0x0f, + 0xfb, 0x8f, 0x06, 0xdc, 0x2e, 0xca, 0x91, 0xb7, 0xeb, 0x69, 0xdc, 0x57, 0x16, 0xaf, 0xc8, 0xdb, + 0x95, 0x68, 0xe7, 0xaf, 0x89, 0xf6, 0x23, 0x58, 0x2e, 0x06, 0x44, 0xc5, 0x5b, 0x9b, 0x21, 0xde, + 0x66, 0x6e, 0x71, 0x42, 0xc6, 0xf6, 0xef, 0x2a, 0xb1, 0x1d, 0x8e, 0x2b, 0xdc, 0xc7, 0xff, 0x4b, + 0x6c, 0x85, 0xdb, 0x6a, 0x6c, 0xb8, 0x6a, 0x7f, 0xe5, 0x02, 0xb5, 0xab, 0x17, 0xb0, 0xff, 0x6c, + 0xc0, 0x66, 0xd5, 0xab, 0x38, 0x67, 0xa7, 0x3c, 0x0e, 0xc9, 0xab, 0xbc, 0x97, 0xe3, 0x37, 0x5f, + 0x1d, 0xbf, 0x27, 0xd0, 0x9a, 0x08, 0x4a, 0x64, 0xd9, 0xf8, 0xd9, 0x4c, 0x3d, 0x56, 0x61, 0x57, + 0x77, 0xa5, 0x7a, 0x0f, 0x61, 0xff, 0xd5, 0x80, 0xf5, 0x3c, 0xc6, 0x22, 0x59, 0xe6, 0x4f, 0xc1, + 0x2c, 0xae, 0x57, 0xbe, 0xde, 0xd2, 0x96, 0x5a, 0xcb, 0x4f, 0xf2, 0xa7, 0x5b, 0xd9, 0x1a, 0xf3, + 0x95, 0xd6, 0x30, 0x3f, 0x85, 0x8d, 0x22, 0xe4, 0x48, 0x17, 0x68, 0xe6, 0x2a, 0x16, 0xef, 0xd3, + 0x42, 0x74, 0xf8, 0xe4, 0x9b, 0x17, 0x6d, 0xe3, 0xdb, 0x17, 0x6d, 0xe3, 0x9f, 0x2f, 0xda, 0xc6, + 0x97, 0x2f, 0xdb, 0x73, 0xdf, 0xbe, 0x6c, 0xcf, 0xfd, 0xfd, 0x65, 0x7b, 0xee, 0x37, 0x1f, 0x0e, + 0xa8, 0x1c, 0xc6, 0x7d, 0x07, 0xb3, 0x51, 0x37, 0xfb, 0x0f, 0x46, 0x99, 0x93, 0xf7, 0x8a, 0x7f, + 0xef, 0x24, 0x3f, 0xef, 0x7e, 0x31, 0xf9, 0xcf, 0x23, 0x39, 0x8e, 0x88, 0xe8, 0x2f, 0x6a, 0xf6, + 0x7a, 0xff, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xae, 0x39, 0x65, 0x6d, 0x12, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -1623,6 +1629,11 @@ func (m *ConsumerAdditionProposal) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if m.Top_N != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x78 + } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) copy(dAtA[i:], m.DistributionTransmissionChannel) @@ -2777,6 +2788,9 @@ func (m *ConsumerAdditionProposal) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovProvider(uint64(m.Top_N)) + } return n } @@ -3673,6 +3687,25 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { } m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:])