From 98580347b78085d0c4b2fe2afa7f57ee91d60e7c Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Tue, 18 Oct 2022 22:36:13 +0700 Subject: [PATCH 001/294] Add test for contract (#1053) * add test close IBC different contract ibc channel * fix test send ibc diff channel contract handle * remove unused comment * remove expose func HandleContractResponse * correct comment for test scenario * fix nit --- x/wasm/ibctesting/chain.go | 35 ++++++++++++++ x/wasm/relay_test.go | 97 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index c2f6f142a9..8d0adfb72a 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -273,6 +273,41 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { return r, nil } +func (chain *TestChain) SendMsgsExpPass(expPass bool, msgs ...sdk.Msg) (*sdk.Result, error) { + // ensure the chain has the latest time + chain.Coordinator.UpdateTimeForChain(chain) + + _, r, err := app.SignAndDeliver( + chain.t, + chain.TxConfig, + chain.App.BaseApp, + chain.GetContext().BlockHeader(), + msgs, + chain.ChainID, + []uint64{chain.SenderAccount.GetAccountNumber()}, + []uint64{chain.SenderAccount.GetSequence()}, + true, expPass, chain.SenderPrivKey, + ) + if err != nil { + return nil, err + } + + // SignAndDeliver calls app.Commit() + chain.NextBlock() + + // increment sequence for successful transaction execution + err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) + if err != nil { + return nil, err + } + + chain.Coordinator.IncrementTime() + + chain.captureIBCEvents(r) + + return r, nil +} + func (chain *TestChain) captureIBCEvents(r *sdk.Result) { toSend := getSendPackets(r.Events) if len(toSend) > 0 { diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index 63e4bdc467..c1cff76c5b 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -399,6 +399,66 @@ func TestContractHandlesChannelClose(t *testing.T) { assert.True(t, myContractB.closeCalled) } +func TestContractHandlesChannelCloseNotOwned(t *testing.T) { + // scenario: given two chains, + // with a contract A1, A2 on chain A, contract B on chain B + // contract A2 try to close ibc channel that create between A1 and B + + myContractA1 := &closeChannelContract{} + myContractA2 := &closeChannelContract{} + myContractB := &closeChannelContract{} + + var ( + chainAOpts = []wasmkeeper.Option{ + wasmkeeper.WithWasmEngine( + wasmtesting.NewIBCContractMockWasmer(myContractA1)), + wasmkeeper.WithWasmEngine( + wasmtesting.NewIBCContractMockWasmer(myContractA2)), + } + chainBOpts = []wasmkeeper.Option{ + wasmkeeper.WithWasmEngine( + wasmtesting.NewIBCContractMockWasmer(myContractB)), + } + coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts, chainBOpts) + + chainA = coordinator.GetChain(wasmibctesting.GetChainID(0)) + chainB = coordinator.GetChain(wasmibctesting.GetChainID(1)) + ) + + coordinator.CommitBlock(chainA, chainB) + myContractAddrA1 := chainA.SeedNewContractInstance() + myContractAddrA2 := chainA.SeedNewContractInstance() + _ = chainB.SeedNewContractInstance() // skip one instance + _ = chainB.SeedNewContractInstance() // skip one instance + myContractAddrB := chainB.SeedNewContractInstance() + + path := wasmibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: chainA.ContractInfo(myContractAddrA1).IBCPortID, + Version: ibctransfertypes.Version, + Order: channeltypes.UNORDERED, + } + path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: chainB.ContractInfo(myContractAddrB).IBCPortID, + Version: ibctransfertypes.Version, + Order: channeltypes.UNORDERED, + } + coordinator.SetupConnections(path) + coordinator.CreateChannels(path) + + closeIBCChannelMsg := &types.MsgExecuteContract{ + Sender: chainA.SenderAccount.GetAddress().String(), + Contract: myContractAddrA2.String(), + Msg: closeIBCChannel{ + ChannelID: path.EndpointA.ChannelID, + }.GetBytes(), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + } + + _, err := chainA.SendMsgsExpPass(false, closeIBCChannelMsg) + require.Error(t, err) +} + var _ wasmtesting.IBCContractCallbacks = &captureCloseContract{} // contract that sets a flag on IBC channel close only. @@ -497,6 +557,43 @@ func (c *sendEmulatedIBCTransferContract) IBCPacketTimeout(codeID wasmvm.Checksu return &wasmvmtypes.IBCBasicResponse{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{Bank: returnTokens}}}}, 0, nil } +var _ wasmtesting.IBCContractCallbacks = &closeChannelContract{} + +type closeChannelContract struct { + contractStub + t *testing.T +} + +func (c *closeChannelContract) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { + return &wasmvmtypes.IBCBasicResponse{}, 1, nil +} + +func (s *closeChannelContract) Execute(code wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, executeMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) { + var in closeIBCChannel + if err := json.Unmarshal(executeMsg, &in); err != nil { + return nil, 0, err + } + ibcMsg := &wasmvmtypes.IBCMsg{ + CloseChannel: &wasmvmtypes.CloseChannelMsg{ + ChannelID: in.ChannelID, + }, + } + + return &wasmvmtypes.Response{Messages: []wasmvmtypes.SubMsg{{ReplyOn: wasmvmtypes.ReplyNever, Msg: wasmvmtypes.CosmosMsg{IBC: ibcMsg}}}}, 0, nil +} + +type closeIBCChannel struct { + ChannelID string +} + +func (g closeIBCChannel) GetBytes() types.RawContractMessage { + b, err := json.Marshal(g) + if err != nil { + panic(err) + } + return b +} + // custom contract execute payload type startTransfer struct { ChannelID string From 2abf812a906b35db2d6df52a5ed869fba8cc7180 Mon Sep 17 00:00:00 2001 From: vuong <56973102+vuong177@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:30:27 +0700 Subject: [PATCH 002/294] Permission (#1050) * move subset check into 'CanCreateCode' * testing * fix logic * minor * Code feedback * clean test * Revert "clean test" This reverts commit a59be56b5734fd5153d81d38c41ae91599e3faaf. * Revert test and make all pass * Cover instantiation config with tests * Add gov policy for sanity check * Test with gov policy for sanity check Co-authored-by: Alex Peters --- x/wasm/keeper/authz_policy.go | 21 ++++- x/wasm/keeper/authz_policy_test.go | 134 ++++++++++++++++++----------- x/wasm/keeper/keeper.go | 14 +-- x/wasm/keeper/keeper_test.go | 33 ++++--- 4 files changed, 130 insertions(+), 72 deletions(-) diff --git a/x/wasm/keeper/authz_policy.go b/x/wasm/keeper/authz_policy.go index 1a222719a8..19f5320a9e 100644 --- a/x/wasm/keeper/authz_policy.go +++ b/x/wasm/keeper/authz_policy.go @@ -6,8 +6,19 @@ import ( "github.com/CosmWasm/wasmd/x/wasm/types" ) +// ChainAccessConfigs chain settings +type ChainAccessConfigs struct { + Upload types.AccessConfig + Instantiate types.AccessConfig +} + +// NewChainAccessConfigs constructor +func NewChainAccessConfigs(upload types.AccessConfig, instantiate types.AccessConfig) ChainAccessConfigs { + return ChainAccessConfigs{Upload: upload, Instantiate: instantiate} +} + type AuthorizationPolicy interface { - CanCreateCode(c types.AccessConfig, creator sdk.AccAddress) bool + CanCreateCode(chainConfigs ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool CanInstantiateContract(c types.AccessConfig, actor sdk.AccAddress) bool CanModifyContract(admin, actor sdk.AccAddress) bool CanModifyCodeAccessConfig(creator, actor sdk.AccAddress, isSubset bool) bool @@ -15,8 +26,9 @@ type AuthorizationPolicy interface { type DefaultAuthorizationPolicy struct{} -func (p DefaultAuthorizationPolicy) CanCreateCode(config types.AccessConfig, actor sdk.AccAddress) bool { - return config.Allowed(actor) +func (p DefaultAuthorizationPolicy) CanCreateCode(chainConfigs ChainAccessConfigs, actor sdk.AccAddress, contractConfig types.AccessConfig) bool { + return chainConfigs.Upload.Allowed(actor) && + contractConfig.IsSubset(chainConfigs.Instantiate) } func (p DefaultAuthorizationPolicy) CanInstantiateContract(config types.AccessConfig, actor sdk.AccAddress) bool { @@ -33,7 +45,8 @@ func (p DefaultAuthorizationPolicy) CanModifyCodeAccessConfig(creator, actor sdk type GovAuthorizationPolicy struct{} -func (p GovAuthorizationPolicy) CanCreateCode(types.AccessConfig, sdk.AccAddress) bool { +// CanCreateCode implements AuthorizationPolicy.CanCreateCode to allow gov actions. Always returns true. +func (p GovAuthorizationPolicy) CanCreateCode(ChainAccessConfigs, sdk.AccAddress, types.AccessConfig) bool { return true } diff --git a/x/wasm/keeper/authz_policy_test.go b/x/wasm/keeper/authz_policy_test.go index acc9cb346c..f39cc9d1b3 100644 --- a/x/wasm/keeper/authz_policy_test.go +++ b/x/wasm/keeper/authz_policy_test.go @@ -13,50 +13,68 @@ func TestDefaultAuthzPolicyCanCreateCode(t *testing.T) { myActorAddress := RandomAccountAddress(t) otherAddress := RandomAccountAddress(t) specs := map[string]struct { - config types.AccessConfig - actor sdk.AccAddress - exp bool - panics bool + chainConfigs ChainAccessConfigs + contractInstConf types.AccessConfig + actor sdk.AccAddress + exp bool + panics bool }{ - "nobody": { - config: types.AllowNobody, - exp: false, - }, - "everybody": { - config: types.AllowEverybody, - exp: true, - }, - "only address - same": { - config: types.AccessTypeOnlyAddress.With(myActorAddress), - exp: true, - }, - "only address - different": { - config: types.AccessTypeOnlyAddress.With(otherAddress), - exp: false, - }, - "any address - included": { - config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), - exp: true, - }, - "any address - not included": { - config: types.AccessTypeAnyOfAddresses.With(otherAddress), - exp: false, - }, - "undefined config - panics": { - config: types.AccessConfig{}, - panics: true, + "upload nobody": { + chainConfigs: NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: false, + }, + "upload everybody": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: true, + }, + "upload only address - same": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeOnlyAddress.With(myActorAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: true, + }, + "upload only address - different": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeOnlyAddress.With(otherAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: false, + }, + "upload any address - included": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: true, + }, + "upload any address - not included": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, + exp: false, + }, + "contract config - subtype": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress), + exp: true, + }, + "contract config - not subtype": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), + contractInstConf: types.AllowEverybody, + exp: false, + }, + "upload undefined config - panics": { + chainConfigs: NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), + contractInstConf: types.AllowEverybody, + panics: true, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { policy := DefaultAuthorizationPolicy{} if !spec.panics { - got := policy.CanCreateCode(spec.config, myActorAddress) + got := policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf) assert.Equal(t, spec.exp, got) return } assert.Panics(t, func() { - policy.CanCreateCode(spec.config, myActorAddress) + policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf) }) }) } @@ -184,35 +202,51 @@ func TestGovAuthzPolicyCanCreateCode(t *testing.T) { myActorAddress := RandomAccountAddress(t) otherAddress := RandomAccountAddress(t) specs := map[string]struct { - config types.AccessConfig - actor sdk.AccAddress + chainConfigs ChainAccessConfigs + contractInstConf types.AccessConfig + actor sdk.AccAddress }{ - "nobody": { - config: types.AllowNobody, + "upload nobody": { + chainConfigs: NewChainAccessConfigs(types.AllowNobody, types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "everybody": { - config: types.AllowEverybody, + "upload everybody": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "only address - same": { - config: types.AccessTypeOnlyAddress.With(myActorAddress), + "upload only address - same": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeOnlyAddress.With(myActorAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "only address - different": { - config: types.AccessTypeOnlyAddress.With(otherAddress), + "upload only address - different": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeOnlyAddress.With(otherAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "any address - included": { - config: types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), + "upload any address - included": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress, myActorAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "any address - not included": { - config: types.AccessTypeAnyOfAddresses.With(otherAddress), + "upload any address - not included": { + chainConfigs: NewChainAccessConfigs(types.AccessTypeAnyOfAddresses.With(otherAddress), types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, - "undefined config - panics": { - config: types.AccessConfig{}, + "contract config - subtype": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowEverybody), + contractInstConf: types.AccessTypeAnyOfAddresses.With(myActorAddress), + }, + "contract config - not subtype": { + chainConfigs: NewChainAccessConfigs(types.AllowEverybody, types.AllowNobody), + contractInstConf: types.AllowEverybody, + }, + "upload undefined config - not panics": { + chainConfigs: NewChainAccessConfigs(types.AccessConfig{}, types.AllowEverybody), + contractInstConf: types.AllowEverybody, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { policy := GovAuthorizationPolicy{} - got := policy.CanCreateCode(spec.config, myActorAddress) + got := policy.CanCreateCode(spec.chainConfigs, myActorAddress, spec.contractInstConf) assert.True(t, got) }) } diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index f29f6e18ed..6fbb6640bf 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -187,16 +187,18 @@ func (k Keeper) create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte, return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "cannot be nil") } - if !authZ.CanCreateCode(k.getUploadAccessConfig(ctx), creator) { - return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") - } // figure out proper instantiate access defaultAccessConfig := k.getInstantiateAccessConfig(ctx).With(creator) if instantiateAccess == nil { instantiateAccess = &defaultAccessConfig - } else if !instantiateAccess.IsSubset(defaultAccessConfig) { - // we enforce this must be subset of default upload access - return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "instantiate access must be subset of default upload access") + } + chainConfigs := ChainAccessConfigs{ + Instantiate: defaultAccessConfig, + Upload: k.getUploadAccessConfig(ctx), + } + + if !authZ.CanCreateCode(chainConfigs, creator, *instantiateAccess) { + return 0, checksum, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "can not create code") } if ioutils.IsGzip(wasmCode) { diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index 947edd27c3..ddc11aadc4 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -138,39 +138,48 @@ func TestCreateStoresInstantiatePermission(t *testing.T) { func TestCreateWithParamPermissions(t *testing.T) { ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) - keeper := keepers.ContractKeeper - deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...) otherAddr := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...) specs := map[string]struct { - srcPermission types.AccessConfig - expError *sdkerrors.Error + policy AuthorizationPolicy + chainUpload types.AccessConfig + expError *sdkerrors.Error }{ "default": { - srcPermission: types.DefaultUploadAccess, + policy: DefaultAuthorizationPolicy{}, + chainUpload: types.DefaultUploadAccess, }, "everybody": { - srcPermission: types.AllowEverybody, + policy: DefaultAuthorizationPolicy{}, + chainUpload: types.AllowEverybody, }, "nobody": { - srcPermission: types.AllowNobody, - expError: sdkerrors.ErrUnauthorized, + policy: DefaultAuthorizationPolicy{}, + chainUpload: types.AllowNobody, + expError: sdkerrors.ErrUnauthorized, }, "onlyAddress with matching address": { - srcPermission: types.AccessTypeOnlyAddress.With(creator), + policy: DefaultAuthorizationPolicy{}, + chainUpload: types.AccessTypeOnlyAddress.With(creator), }, "onlyAddress with non matching address": { - srcPermission: types.AccessTypeOnlyAddress.With(otherAddr), - expError: sdkerrors.ErrUnauthorized, + policy: DefaultAuthorizationPolicy{}, + chainUpload: types.AccessTypeOnlyAddress.With(otherAddr), + expError: sdkerrors.ErrUnauthorized, + }, + "gov: always allowed": { + policy: GovAuthorizationPolicy{}, + chainUpload: types.AllowNobody, }, } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { params := types.DefaultParams() - params.CodeUploadAccess = spec.srcPermission + params.CodeUploadAccess = spec.chainUpload keepers.WasmKeeper.SetParams(ctx, params) + keeper := NewPermissionedKeeper(keepers.WasmKeeper, spec.policy) _, _, err := keeper.Create(ctx, creator, hackatomWasm, nil) require.True(t, spec.expError.Is(err), err) if spec.expError != nil { From 6d67d5b4f759fb270c1bceaaafc76d89c618237b Mon Sep 17 00:00:00 2001 From: vuong <56973102+vuong177@users.noreply.github.com> Date: Fri, 21 Oct 2022 00:04:41 +0700 Subject: [PATCH 003/294] Get Contracts by Creator Address (#1021) * add query to query.proto * add ContractsByCreatorPrefix in keys.go * add ContractCreatorThirdIndex to keeper.go * add querier * cli * fix test * linting * add key test * no need to change creator when migrate * add query test * minor * add migrate logic * add more test * register migration * minor * Update x/wasm/client/cli/query.go Co-authored-by: Alexander Peters * nits * remove IterateAllContract * Update x/wasm/keeper/genesis_test.go Co-authored-by: Alexander Peters * nit * nit: func name * change key * improve TestIteratorContractByCreator * fix test * use IterateContractInfo in migrate2to3 * minor * move key * improve test case * add pagReq in ContractsByCreator query * ordering query * add migrate test * Make ContractsByCreator plural; formatting and minor updates * Comment why AbsoluteTxPositionLen makes sense * Migrate 1 to 2 * Set module version Co-authored-by: Alexander Peters Co-authored-by: khanh-notional <50263489+catShaark@users.noreply.github.com> --- docs/proto/proto-docs.md | 37 ++ proto/cosmwasm/wasm/v1/query.proto | 25 ++ x/wasm/client/cli/query.go | 40 ++ x/wasm/keeper/genesis_test.go | 3 + x/wasm/keeper/keeper.go | 24 +- x/wasm/keeper/keeper_test.go | 92 +++- x/wasm/keeper/migrate_test.go | 61 +++ x/wasm/keeper/migrations.go | 27 ++ x/wasm/keeper/querier.go | 29 ++ x/wasm/keeper/querier_test.go | 104 +++++ x/wasm/module.go | 8 +- x/wasm/module_integration_test.go | 2 +- x/wasm/types/exported_keepers.go | 1 + x/wasm/types/keys.go | 21 + x/wasm/types/keys_test.go | 60 +++ x/wasm/types/query.pb.go | 659 +++++++++++++++++++++++++---- x/wasm/types/query.pb.gw.go | 112 ++++- 17 files changed, 1221 insertions(+), 84 deletions(-) create mode 100644 x/wasm/keeper/migrate_test.go create mode 100644 x/wasm/keeper/migrations.go diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index add638f07f..d6e5aee1d6 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -73,6 +73,8 @@ - [QueryContractInfoResponse](#cosmwasm.wasm.v1.QueryContractInfoResponse) - [QueryContractsByCodeRequest](#cosmwasm.wasm.v1.QueryContractsByCodeRequest) - [QueryContractsByCodeResponse](#cosmwasm.wasm.v1.QueryContractsByCodeResponse) + - [QueryContractsByCreatorRequest](#cosmwasm.wasm.v1.QueryContractsByCreatorRequest) + - [QueryContractsByCreatorResponse](#cosmwasm.wasm.v1.QueryContractsByCreatorResponse) - [QueryParamsRequest](#cosmwasm.wasm.v1.QueryParamsRequest) - [QueryParamsResponse](#cosmwasm.wasm.v1.QueryParamsResponse) - [QueryPinnedCodesRequest](#cosmwasm.wasm.v1.QueryPinnedCodesRequest) @@ -1131,6 +1133,40 @@ Query/ContractsByCode RPC method + + +### QueryContractsByCreatorRequest +QueryContractsByCreatorRequest is the request type for the +Query/ContractsByCreator RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `creator_address` | [string](#string) | | CreatorAddress is the address of contract creator | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | Pagination defines an optional pagination for the request. | + + + + + + + + +### QueryContractsByCreatorResponse +QueryContractsByCreatorResponse is the response type for the +Query/ContractsByCreator RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract_addresses` | [string](#string) | repeated | ContractAddresses result set | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | Pagination defines the pagination in the response. | + + + + + + ### QueryParamsRequest @@ -1278,6 +1314,7 @@ Query provides defines the gRPC querier service | `Codes` | [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest) | [QueryCodesResponse](#cosmwasm.wasm.v1.QueryCodesResponse) | Codes gets the metadata for all stored wasm codes | GET|/cosmwasm/wasm/v1/code| | `PinnedCodes` | [QueryPinnedCodesRequest](#cosmwasm.wasm.v1.QueryPinnedCodesRequest) | [QueryPinnedCodesResponse](#cosmwasm.wasm.v1.QueryPinnedCodesResponse) | PinnedCodes gets the pinned code ids | GET|/cosmwasm/wasm/v1/codes/pinned| | `Params` | [QueryParamsRequest](#cosmwasm.wasm.v1.QueryParamsRequest) | [QueryParamsResponse](#cosmwasm.wasm.v1.QueryParamsResponse) | Params gets the module params | GET|/cosmwasm/wasm/v1/codes/params| +| `ContractsByCreator` | [QueryContractsByCreatorRequest](#cosmwasm.wasm.v1.QueryContractsByCreatorRequest) | [QueryContractsByCreatorResponse](#cosmwasm.wasm.v1.QueryContractsByCreatorResponse) | ContractsByCreator gets the contracts by creator | GET|/cosmwasm/wasm/v1/contracts/creator/{creator_address}| diff --git a/proto/cosmwasm/wasm/v1/query.proto b/proto/cosmwasm/wasm/v1/query.proto index 41d959d800..ffe48d2429 100644 --- a/proto/cosmwasm/wasm/v1/query.proto +++ b/proto/cosmwasm/wasm/v1/query.proto @@ -63,6 +63,13 @@ service Query { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/cosmwasm/wasm/v1/codes/params"; } + + // ContractsByCreator gets the contracts by creator + rpc ContractsByCreator(QueryContractsByCreatorRequest) + returns (QueryContractsByCreatorResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contracts/creator/{creator_address}"; + } } // QueryContractInfoRequest is the request type for the Query/ContractInfo RPC @@ -236,3 +243,21 @@ message QueryParamsResponse { // params defines the parameters of the module. Params params = 1 [ (gogoproto.nullable) = false ]; } + +// QueryContractsByCreatorRequest is the request type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorRequest { + // CreatorAddress is the address of contract creator + string creator_address = 1; + // Pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractsByCreatorResponse is the response type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorResponse { + // ContractAddresses result set + repeated string contract_addresses = 1; + // Pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} \ No newline at end of file diff --git a/x/wasm/client/cli/query.go b/x/wasm/client/cli/query.go index b847b3d843..8d13a1192a 100644 --- a/x/wasm/client/cli/query.go +++ b/x/wasm/client/cli/query.go @@ -41,6 +41,7 @@ func GetQueryCmd() *cobra.Command { GetCmdLibVersion(), GetCmdQueryParams(), GetCmdBuildAddress(), + GetCmdListContractsByCreator(), ) return queryCmd } @@ -528,6 +529,45 @@ func GetCmdListPinnedCode() *cobra.Command { return cmd } +// GetCmdListContractsByCreator lists all contracts by creator +func GetCmdListContractsByCreator() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-contracts-by-creator [creator]", + Short: "List all contracts by creator", + Long: "\t\tLong: List all contracts by creator,\n", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + _, err = sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + pageReq, err := client.ReadPageRequest(withPageKeyDecoded(cmd.Flags())) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.ContractsByCreator( + context.Background(), + &types.QueryContractsByCreatorRequest{ + CreatorAddress: args[0], + Pagination: pageReq, + }, + ) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + type argumentDecoder struct { // dec is the default decoder dec func(string) ([]byte, error) diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index aee7ad009e..1d8f29a40f 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -110,7 +110,9 @@ func TestGenesisExportImport(t *testing.T) { // reset contract code index in source DB for comparison with dest DB wasmKeeper.IterateContractInfo(srcCtx, func(address sdk.AccAddress, info wasmTypes.ContractInfo) bool { + creatorAddress := sdk.MustAccAddressFromBech32(info.Creator) wasmKeeper.removeFromContractCodeSecondaryIndex(srcCtx, address, wasmKeeper.getLastContractHistoryEntry(srcCtx, address)) + prefixStore := prefix.NewStore(srcCtx.KVStore(wasmKeeper.storeKey), types.GetContractCodeHistoryElementPrefix(address)) iter := prefixStore.Iterator(nil, nil) @@ -121,6 +123,7 @@ func TestGenesisExportImport(t *testing.T) { newHistory := x.ResetFromGenesis(dstCtx) wasmKeeper.storeContractInfo(srcCtx, address, x) wasmKeeper.addToContractCodeSecondaryIndex(srcCtx, address, newHistory) + wasmKeeper.addToContractCreatorSecondaryIndex(srcCtx, creatorAddress, newHistory.Updated, address) wasmKeeper.appendToContractHistory(srcCtx, address, newHistory) iter.Close() return false diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 6fbb6640bf..93dad3f5b4 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -380,6 +380,7 @@ func (k Keeper) instantiate( // store contract before dispatch so that contract could be called back historyEntry := contractInfo.InitialHistory(initMsg) k.addToContractCodeSecondaryIndex(ctx, contractAddress, historyEntry) + k.addToContractCreatorSecondaryIndex(ctx, creator, historyEntry.Updated, contractAddress) k.appendToContractHistory(ctx, contractAddress, historyEntry) k.storeContractInfo(ctx, contractAddress, &contractInfo) @@ -491,7 +492,6 @@ func (k Keeper) migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller if err != nil { return nil, sdkerrors.Wrap(types.ErrMigrationFailed, err.Error()) } - // delete old secondary index entry k.removeFromContractCodeSecondaryIndex(ctx, contractAddress, k.getLastContractHistoryEntry(ctx, contractAddress)) // persist migration updates @@ -598,6 +598,23 @@ func (k Keeper) removeFromContractCodeSecondaryIndex(ctx sdk.Context, contractAd ctx.KVStore(k.storeKey).Delete(types.GetContractByCreatedSecondaryIndexKey(contractAddress, entry)) } +// addToContractCreatorSecondaryIndex adds element to the index for contracts-by-creator queries +func (k Keeper) addToContractCreatorSecondaryIndex(ctx sdk.Context, creatorAddress sdk.AccAddress, position *types.AbsoluteTxPosition, contractAddress sdk.AccAddress) { + store := ctx.KVStore(k.storeKey) + store.Set(types.GetContractByCreatorSecondaryIndexKey(creatorAddress, position.Bytes(), contractAddress), []byte{}) +} + +// IterateContractsByCreator iterates over all contracts with given creator address in order of creation time asc. +func (k Keeper) IterateContractsByCreator(ctx sdk.Context, creator sdk.AccAddress, cb func(address sdk.AccAddress) bool) { + prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractsByCreatorPrefix(creator)) + for iter := prefixStore.Iterator(nil, nil); iter.Valid(); iter.Next() { + key := iter.Key() + if cb(key[types.AbsoluteTxPositionLen:]) { + return + } + } +} + // IterateContractsByCode iterates over all contracts with given codeID ASC on code update time. func (k Keeper) IterateContractsByCode(ctx sdk.Context, codeID uint64, cb func(address sdk.AccAddress) bool) { prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.GetContractByCodeIDSecondaryIndexPrefix(codeID)) @@ -1053,10 +1070,15 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c * return sdkerrors.Wrapf(types.ErrDuplicate, "contract: %s", contractAddr) } + creatorAddress, err := sdk.AccAddressFromBech32(c.Creator) + if err != nil { + return err + } historyEntry := c.ResetFromGenesis(ctx) k.appendToContractHistory(ctx, contractAddr, historyEntry) k.storeContractInfo(ctx, contractAddr, c) k.addToContractCodeSecondaryIndex(ctx, contractAddr, historyEntry) + k.addToContractCreatorSecondaryIndex(ctx, creatorAddress, historyEntry.Updated, contractAddr) return k.importContractState(ctx, contractAddr, state) } diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index ddc11aadc4..98136f5204 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -409,7 +409,7 @@ func TestInstantiate(t *testing.T) { gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x1964f), gasAfter-gasBefore) + require.Equal(t, uint64(0x1a7bb), gasAfter-gasBefore) } // ensure it is stored properly @@ -2197,3 +2197,93 @@ func TestCoinBurnerPruneBalances(t *testing.T) { }) } } + +func TestIteratorAllContract(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) + example1 := InstantiateHackatomExampleContract(t, ctx, keepers) + example2 := InstantiateHackatomExampleContract(t, ctx, keepers) + example3 := InstantiateHackatomExampleContract(t, ctx, keepers) + example4 := InstantiateHackatomExampleContract(t, ctx, keepers) + + var allContract []string + keepers.WasmKeeper.IterateContractInfo(ctx, func(addr sdk.AccAddress, _ types.ContractInfo) bool { + allContract = append(allContract, addr.String()) + return false + }) + + // IterateContractInfo not ordering + expContracts := []string{example4.Contract.String(), example2.Contract.String(), example1.Contract.String(), example3.Contract.String()} + require.Equal(t, allContract, expContracts) +} + +func TestIteratorContractByCreator(t *testing.T) { + // setup test + parentCtx, keepers := CreateTestInput(t, false, AvailableCapabilities) + keeper := keepers.ContractKeeper + + depositFund := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000)) + topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 5000)) + creator := DeterministicAccountAddress(t, 1) + keepers.Faucet.Fund(parentCtx, creator, depositFund.Add(depositFund...)...) + mockAddress1 := keepers.Faucet.NewFundedRandomAccount(parentCtx, topUp...) + mockAddress2 := keepers.Faucet.NewFundedRandomAccount(parentCtx, topUp...) + mockAddress3 := keepers.Faucet.NewFundedRandomAccount(parentCtx, topUp...) + + contract1ID, _, err := keeper.Create(parentCtx, creator, hackatomWasm, nil) + contract2ID, _, err := keeper.Create(parentCtx, creator, hackatomWasm, nil) + + require.NoError(t, err) + + initMsgBz := HackatomExampleInitMsg{ + Verifier: mockAddress1, + Beneficiary: mockAddress1, + }.GetBytes(t) + + depositContract := sdk.NewCoins(sdk.NewCoin("denom", sdk.NewInt(1_000))) + + gotAddr1, _, _ := keepers.ContractKeeper.Instantiate(parentCtx, contract1ID, mockAddress1, nil, initMsgBz, "label", depositContract) + ctx := parentCtx.WithBlockHeight(parentCtx.BlockHeight() + 1) + gotAddr2, _, _ := keepers.ContractKeeper.Instantiate(ctx, contract1ID, mockAddress2, nil, initMsgBz, "label", depositContract) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + gotAddr3, _, _ := keepers.ContractKeeper.Instantiate(ctx, contract1ID, gotAddr1, nil, initMsgBz, "label", depositContract) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + gotAddr4, _, _ := keepers.ContractKeeper.Instantiate(ctx, contract2ID, mockAddress2, nil, initMsgBz, "label", depositContract) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + gotAddr5, _, _ := keepers.ContractKeeper.Instantiate(ctx, contract2ID, mockAddress2, nil, initMsgBz, "label", depositContract) + + specs := map[string]struct { + creatorAddr sdk.AccAddress + contractsAddr []string + }{ + "single contract": { + creatorAddr: mockAddress1, + contractsAddr: []string{gotAddr1.String()}, + }, + "multiple contracts": { + creatorAddr: mockAddress2, + contractsAddr: []string{gotAddr2.String(), gotAddr4.String(), gotAddr5.String()}, + }, + "contractAdress": { + creatorAddr: gotAddr1, + contractsAddr: []string{gotAddr3.String()}, + }, + "no contracts- unknown": { + creatorAddr: mockAddress3, + contractsAddr: nil, + }, + } + + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + var allContract []string + keepers.WasmKeeper.IterateContractsByCreator(parentCtx, spec.creatorAddr, func(addr sdk.AccAddress) bool { + allContract = append(allContract, addr.String()) + return false + }) + require.Equal(t, + allContract, + spec.contractsAddr, + ) + }) + } +} diff --git a/x/wasm/keeper/migrate_test.go b/x/wasm/keeper/migrate_test.go new file mode 100644 index 0000000000..3b762c49d0 --- /dev/null +++ b/x/wasm/keeper/migrate_test.go @@ -0,0 +1,61 @@ +package keeper + +import ( + "bytes" + "encoding/json" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestMigrate1To2(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) + wasmKeeper := keepers.WasmKeeper + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) + creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) + keepers.Faucet.Fund(ctx, creator, deposit...) + example := StoreHackatomExampleContract(t, ctx, keepers) + + initMsg := HackatomExampleInitMsg{ + Verifier: RandomAccountAddress(t), + Beneficiary: RandomAccountAddress(t), + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + em := sdk.NewEventManager() + + // create with no balance is also legal + gotContractAddr1, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), example.CodeID, creator, nil, initMsgBz, "demo contract 1", nil) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + gotContractAddr2, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), example.CodeID, creator, nil, initMsgBz, "demo contract 1", nil) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) + gotContractAddr3, _, err := keepers.ContractKeeper.Instantiate(ctx.WithEventManager(em), example.CodeID, creator, nil, initMsgBz, "demo contract 1", nil) + + info1 := wasmKeeper.GetContractInfo(ctx, gotContractAddr1) + info2 := wasmKeeper.GetContractInfo(ctx, gotContractAddr2) + info3 := wasmKeeper.GetContractInfo(ctx, gotContractAddr3) + + // remove key + ctx.KVStore(wasmKeeper.storeKey).Delete(types.GetContractByCreatorSecondaryIndexKey(creator, info1.Created.Bytes(), gotContractAddr1)) + ctx.KVStore(wasmKeeper.storeKey).Delete(types.GetContractByCreatorSecondaryIndexKey(creator, info2.Created.Bytes(), gotContractAddr2)) + ctx.KVStore(wasmKeeper.storeKey).Delete(types.GetContractByCreatorSecondaryIndexKey(creator, info3.Created.Bytes(), gotContractAddr3)) + + // migrator + migrator := NewMigrator(*wasmKeeper) + migrator.Migrate1to2(ctx) + + // check new store + var allContract []string + wasmKeeper.IterateContractsByCreator(ctx, creator, func(addr sdk.AccAddress) bool { + allContract = append(allContract, addr.String()) + return false + }) + + require.Equal(t, []string{gotContractAddr1.String(), gotContractAddr2.String(), gotContractAddr3.String()}, allContract) +} diff --git a/x/wasm/keeper/migrations.go b/x/wasm/keeper/migrations.go new file mode 100644 index 0000000000..ffb80cc2ed --- /dev/null +++ b/x/wasm/keeper/migrations.go @@ -0,0 +1,27 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +// Migrator is a struct for handling in-place store migrations. +type Migrator struct { + keeper Keeper +} + +// NewMigrator returns a new Migrator. +func NewMigrator(keeper Keeper) Migrator { + return Migrator{keeper: keeper} +} + +// Migrate1to2 migrates from version 1 to 2. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + m.keeper.IterateContractInfo(ctx, func(contractAddr sdk.AccAddress, contractInfo types.ContractInfo) bool { + creator := sdk.MustAccAddressFromBech32(contractInfo.Creator) + m.keeper.addToContractCreatorSecondaryIndex(ctx, creator, contractInfo.Created, contractAddr) + return false + }) + return nil +} diff --git a/x/wasm/keeper/querier.go b/x/wasm/keeper/querier.go index 8cd882c7a8..9b23c68d96 100644 --- a/x/wasm/keeper/querier.go +++ b/x/wasm/keeper/querier.go @@ -318,3 +318,32 @@ func (q grpcQuerier) Params(c context.Context, req *types.QueryParamsRequest) (* params := q.keeper.GetParams(ctx) return &types.QueryParamsResponse{Params: params}, nil } + +func (q grpcQuerier) ContractsByCreator(c context.Context, req *types.QueryContractsByCreatorRequest) (*types.QueryContractsByCreatorResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + ctx := sdk.UnwrapSDKContext(c) + contracts := make([]string, 0) + + creatorAddress, err := sdk.AccAddressFromBech32(req.CreatorAddress) + if err != nil { + return nil, err + } + prefixStore := prefix.NewStore(ctx.KVStore(q.storeKey), types.GetContractsByCreatorPrefix(creatorAddress)) + pageRes, err := query.FilteredPaginate(prefixStore, req.Pagination, func(key []byte, _ []byte, accumulate bool) (bool, error) { + if accumulate { + accAddres := sdk.AccAddress(key[types.AbsoluteTxPositionLen:]) + contracts = append(contracts, accAddres.String()) + } + return true, nil + }) + if err != nil { + return nil, err + } + + return &types.QueryContractsByCreatorResponse{ + ContractAddresses: contracts, + Pagination: pageRes, + }, nil +} diff --git a/x/wasm/keeper/querier_test.go b/x/wasm/keeper/querier_test.go index f4341d169d..52a17d0e11 100644 --- a/x/wasm/keeper/querier_test.go +++ b/x/wasm/keeper/querier_test.go @@ -802,6 +802,110 @@ func TestQueryCodeInfoList(t *testing.T) { require.EqualValues(t, allCodesResponse, got.CodeInfos) } +func TestQueryContractsByCreatorList(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) + + deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 1000000)) + topUp := sdk.NewCoins(sdk.NewInt64Coin("denom", 500)) + creator := keepers.Faucet.NewFundedRandomAccount(ctx, deposit...) + anyAddr := keepers.Faucet.NewFundedRandomAccount(ctx, topUp...) + + wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") + require.NoError(t, err) + + codeID, _, err := keepers.ContractKeeper.Create(ctx, creator, wasmCode, nil) + require.NoError(t, err) + + _, _, bob := keyPubAddr() + initMsg := HackatomExampleInitMsg{ + Verifier: anyAddr, + Beneficiary: bob, + } + initMsgBz, err := json.Marshal(initMsg) + require.NoError(t, err) + + // manage some realistic block settings + var h int64 = 10 + setBlock := func(ctx sdk.Context, height int64) sdk.Context { + ctx = ctx.WithBlockHeight(height) + meter := sdk.NewGasMeter(1000000) + ctx = ctx.WithGasMeter(meter) + ctx = ctx.WithBlockGasMeter(meter) + return ctx + } + + var allExpecedContracts []string + // create 10 contracts with real block/gas setup + for i := 0; i < 10; i++ { + ctx = setBlock(ctx, h) + h++ + contract, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, initMsgBz, fmt.Sprintf("contract %d", i), topUp) + allExpecedContracts = append(allExpecedContracts, contract.String()) + require.NoError(t, err) + } + + specs := map[string]struct { + srcQuery *types.QueryContractsByCreatorRequest + expContractAddr []string + expErr error + }{ + "query all": { + srcQuery: &types.QueryContractsByCreatorRequest{ + CreatorAddress: creator.String(), + }, + expContractAddr: allExpecedContracts, + expErr: nil, + }, + "with pagination offset": { + srcQuery: &types.QueryContractsByCreatorRequest{ + CreatorAddress: creator.String(), + Pagination: &query.PageRequest{ + Offset: 1, + }, + }, + expContractAddr: allExpecedContracts[1:], + expErr: nil, + }, + "with pagination limit": { + srcQuery: &types.QueryContractsByCreatorRequest{ + CreatorAddress: creator.String(), + Pagination: &query.PageRequest{ + Limit: 1, + }, + }, + expContractAddr: allExpecedContracts[0:1], + expErr: nil, + }, + "nil creator": { + srcQuery: &types.QueryContractsByCreatorRequest{ + Pagination: &query.PageRequest{}, + }, + expContractAddr: allExpecedContracts, + expErr: errors.New("empty address string is not allowed"), + }, + "nil req": { + srcQuery: nil, + expContractAddr: allExpecedContracts, + expErr: status.Error(codes.InvalidArgument, "empty request"), + }, + } + + q := Querier(keepers.WasmKeeper) + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + got, err := q.ContractsByCreator(sdk.WrapSDKContext(ctx), spec.srcQuery) + + if spec.expErr != nil { + require.Equal(t, spec.expErr, err) + return + } + require.NoError(t, err) + require.NotNil(t, got) + assert.Equal(t, spec.expContractAddr, got.ContractAddresses) + }) + } +} + func fromBase64(s string) []byte { r, err := base64.StdEncoding.DecodeString(s) if err != nil { diff --git a/x/wasm/module.go b/x/wasm/module.go index 956887dabe..a52dc1bf0b 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -115,7 +115,7 @@ type AppModule struct { // module. It should be incremented on each consensus-breaking change // introduced by the module. To avoid wrong/empty versions, the initial version // should be set to 1. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } // NewAppModule creates a new AppModule object func NewAppModule( @@ -138,6 +138,12 @@ func NewAppModule( func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(keeper.NewDefaultPermissionKeeper(am.keeper))) types.RegisterQueryServer(cfg.QueryServer(), NewQuerier(am.keeper)) + + m := keeper.NewMigrator(*am.keeper) + err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + if err != nil { + panic(err) + } } func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier { //nolint:staticcheck diff --git a/x/wasm/module_integration_test.go b/x/wasm/module_integration_test.go index 0cbec6641f..bdce6cf34f 100644 --- a/x/wasm/module_integration_test.go +++ b/x/wasm/module_integration_test.go @@ -27,5 +27,5 @@ func TestModuleMigrations(t *testing.T) { gotVM, err := wasmApp.ModuleManager().RunMigrations(ctx, wasmApp.ModuleConfigurator(), fromVM) // then require.NoError(t, err) - assert.Equal(t, uint64(1), gotVM[wasm.ModuleName]) + assert.Equal(t, uint64(2), gotVM[wasm.ModuleName]) } diff --git a/x/wasm/types/exported_keepers.go b/x/wasm/types/exported_keepers.go index e68df8ee7b..dcf97cb2cc 100644 --- a/x/wasm/types/exported_keepers.go +++ b/x/wasm/types/exported_keepers.go @@ -14,6 +14,7 @@ type ViewKeeper interface { HasContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) bool GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *ContractInfo IterateContractInfo(ctx sdk.Context, cb func(sdk.AccAddress, ContractInfo) bool) + IterateContractsByCreator(ctx sdk.Context, creator sdk.AccAddress, cb func(address sdk.AccAddress) bool) IterateContractsByCode(ctx sdk.Context, codeID uint64, cb func(address sdk.AccAddress) bool) IterateContractState(ctx sdk.Context, contractAddress sdk.AccAddress, cb func(key, value []byte) bool) GetCodeInfo(ctx sdk.Context, codeID uint64) *CodeInfo diff --git a/x/wasm/types/keys.go b/x/wasm/types/keys.go index fb636ef4f3..95078e1445 100644 --- a/x/wasm/types/keys.go +++ b/x/wasm/types/keys.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" ) const ( @@ -31,6 +32,7 @@ var ( ContractByCodeIDAndCreatedSecondaryIndexPrefix = []byte{0x06} PinnedCodeIndexPrefix = []byte{0x07} TXCounterPrefix = []byte{0x08} + ContractsByCreatorPrefix = []byte{0x09} KeyLastCodeID = append(SequenceKeyPrefix, []byte("lastCodeId")...) KeyLastInstanceID = append(SequenceKeyPrefix, []byte("lastContractId")...) @@ -47,6 +49,12 @@ func GetContractAddressKey(addr sdk.AccAddress) []byte { return append(ContractKeyPrefix, addr...) } +// GetContractsByCreatorPrefix returns the contracts by creator prefix for the WASM contract instance +func GetContractsByCreatorPrefix(addr sdk.AccAddress) []byte { + bz := address.MustLengthPrefix(addr) + return append(ContractsByCreatorPrefix, bz...) +} + // GetContractStorePrefix returns the store prefix for the WASM contract instance func GetContractStorePrefix(addr sdk.AccAddress) []byte { return append(ContractStorePrefix, addr...) @@ -75,6 +83,19 @@ func GetContractByCodeIDSecondaryIndexPrefix(codeID uint64) []byte { return r } +// GetContractByCreatorSecondaryIndexKey returns the key for the second index: `` +func GetContractByCreatorSecondaryIndexKey(bz []byte, position []byte, contractAddr sdk.AccAddress) []byte { + prefixBytes := GetContractsByCreatorPrefix(bz) + lenPrefixBytes := len(prefixBytes) + r := make([]byte, lenPrefixBytes+AbsoluteTxPositionLen+len(contractAddr)) + + copy(r[:lenPrefixBytes], prefixBytes) + copy(r[lenPrefixBytes:lenPrefixBytes+AbsoluteTxPositionLen], position) + copy(r[lenPrefixBytes+AbsoluteTxPositionLen:], contractAddr) + + return r +} + // GetContractCodeHistoryElementKey returns the key a contract code history entry: `` func GetContractCodeHistoryElementKey(contractAddr sdk.AccAddress, pos uint64) []byte { prefix := GetContractCodeHistoryElementPrefix(contractAddr) diff --git a/x/wasm/types/keys_test.go b/x/wasm/types/keys_test.go index 552703fea0..3db6bbadfe 100644 --- a/x/wasm/types/keys_test.go +++ b/x/wasm/types/keys_test.go @@ -85,3 +85,63 @@ func TestGetContractByCreatedSecondaryIndexKey(t *testing.T) { } assert.Equal(t, exp, got) } + +func TestGetContractByCreatorSecondaryIndexKey(t *testing.T) { + creatorAddr := bytes.Repeat([]byte{4}, 20) + e := ContractCodeHistoryEntry{ + CodeID: 1, + Updated: &AbsoluteTxPosition{2 + 1<<(8*7), 3 + 1<<(8*7)}, + } + + // test that contract addresses of 20 length are still supported + contractAddr := bytes.Repeat([]byte{4}, 20) + got := GetContractByCreatorSecondaryIndexKey(creatorAddr, e.Updated.Bytes(), contractAddr) + exp := []byte{ + 9, // prefix + 20, // creator address length + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // creator address with fixed length prefix + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 0, 0, 0, 0, 0, 0, 2, // height + 1, 0, 0, 0, 0, 0, 0, 3, // index + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // address 20 bytes + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + } + assert.Equal(t, exp, got) + + // test that contract addresses of 32 length are still supported + contractAddr = bytes.Repeat([]byte{4}, 32) + got = GetContractByCreatorSecondaryIndexKey(creatorAddr, e.Updated.Bytes(), contractAddr) + exp = []byte{ + 9, // prefix + 20, // creator address length + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // creator address with fixed length prefix + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 0, 0, 0, 0, 0, 0, 2, // height + 1, 0, 0, 0, 0, 0, 0, 3, // index + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // address 32 bytes + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + } + + // test that creator is contract addresses of 32 length + contractAddr = bytes.Repeat([]byte{4}, 32) + creatorAddr = bytes.Repeat([]byte{8}, 32) + got = GetContractByCreatorSecondaryIndexKey(creatorAddr, e.Updated.Bytes(), contractAddr) + exp = []byte{ + 9, // prefix + 32, // creator address length + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // creator address is a contract address + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, + 1, 0, 0, 0, 0, 0, 0, 2, // height + 1, 0, 0, 0, 0, 0, 0, 3, // index + + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // address 32 bytes + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, + } + assert.Equal(t, exp, got) +} diff --git a/x/wasm/types/query.pb.go b/x/wasm/types/query.pb.go index dea3e53b01..bb08b7571c 100644 --- a/x/wasm/types/query.pb.go +++ b/x/wasm/types/query.pb.go @@ -987,6 +987,100 @@ func (m *QueryParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo +// QueryContractsByCreatorRequest is the request type for the +// Query/ContractsByCreator RPC method. +type QueryContractsByCreatorRequest struct { + // CreatorAddress is the address of contract creator + CreatorAddress string `protobuf:"bytes,1,opt,name=creator_address,json=creatorAddress,proto3" json:"creator_address,omitempty"` + // Pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryContractsByCreatorRequest) Reset() { *m = QueryContractsByCreatorRequest{} } +func (m *QueryContractsByCreatorRequest) String() string { return proto.CompactTextString(m) } +func (*QueryContractsByCreatorRequest) ProtoMessage() {} +func (*QueryContractsByCreatorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_9677c207036b9f2b, []int{21} +} + +func (m *QueryContractsByCreatorRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *QueryContractsByCreatorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryContractsByCreatorRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *QueryContractsByCreatorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryContractsByCreatorRequest.Merge(m, src) +} + +func (m *QueryContractsByCreatorRequest) XXX_Size() int { + return m.Size() +} + +func (m *QueryContractsByCreatorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryContractsByCreatorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryContractsByCreatorRequest proto.InternalMessageInfo + +// QueryContractsByCreatorResponse is the response type for the +// Query/ContractsByCreator RPC method. +type QueryContractsByCreatorResponse struct { + // ContractAddresses result set + ContractAddresses []string `protobuf:"bytes,1,rep,name=contract_addresses,json=contractAddresses,proto3" json:"contract_addresses,omitempty"` + // Pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryContractsByCreatorResponse) Reset() { *m = QueryContractsByCreatorResponse{} } +func (m *QueryContractsByCreatorResponse) String() string { return proto.CompactTextString(m) } +func (*QueryContractsByCreatorResponse) ProtoMessage() {} +func (*QueryContractsByCreatorResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9677c207036b9f2b, []int{22} +} + +func (m *QueryContractsByCreatorResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *QueryContractsByCreatorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryContractsByCreatorResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *QueryContractsByCreatorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryContractsByCreatorResponse.Merge(m, src) +} + +func (m *QueryContractsByCreatorResponse) XXX_Size() int { + return m.Size() +} + +func (m *QueryContractsByCreatorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryContractsByCreatorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryContractsByCreatorResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*QueryContractInfoRequest)(nil), "cosmwasm.wasm.v1.QueryContractInfoRequest") proto.RegisterType((*QueryContractInfoResponse)(nil), "cosmwasm.wasm.v1.QueryContractInfoResponse") @@ -1009,90 +1103,98 @@ func init() { proto.RegisterType((*QueryPinnedCodesResponse)(nil), "cosmwasm.wasm.v1.QueryPinnedCodesResponse") proto.RegisterType((*QueryParamsRequest)(nil), "cosmwasm.wasm.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "cosmwasm.wasm.v1.QueryParamsResponse") + proto.RegisterType((*QueryContractsByCreatorRequest)(nil), "cosmwasm.wasm.v1.QueryContractsByCreatorRequest") + proto.RegisterType((*QueryContractsByCreatorResponse)(nil), "cosmwasm.wasm.v1.QueryContractsByCreatorResponse") } func init() { proto.RegisterFile("cosmwasm/wasm/v1/query.proto", fileDescriptor_9677c207036b9f2b) } var fileDescriptor_9677c207036b9f2b = []byte{ - // 1245 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0x3d, 0xa9, 0xe3, 0x1f, 0x93, 0xa0, 0x9a, 0xa1, 0x24, 0xc6, 0xa4, 0xbb, 0xd1, 0x52, - 0x42, 0x9a, 0x86, 0x5d, 0x92, 0x26, 0x14, 0x90, 0x10, 0xaa, 0x53, 0x68, 0x12, 0x29, 0x52, 0xba, - 0x15, 0xaa, 0x44, 0x0f, 0xd1, 0xd8, 0x3b, 0x71, 0x56, 0x8a, 0x77, 0x9c, 0x9d, 0x49, 0x52, 0x2b, - 0x0a, 0xa0, 0x4a, 0x48, 0x1c, 0x10, 0x20, 0x21, 0x8e, 0x08, 0x0e, 0xa8, 0x70, 0x86, 0x1b, 0x7f, - 0x41, 0x8e, 0x91, 0xb8, 0x70, 0xb2, 0xc0, 0xe1, 0x80, 0xf2, 0x27, 0xf4, 0x84, 0x76, 0x76, 0xd6, - 0xd9, 0xb5, 0xbd, 0xb1, 0x53, 0x59, 0xbd, 0x58, 0xfb, 0xe3, 0xbd, 0x37, 0x9f, 0xf7, 0x9d, 0xb7, - 0x6f, 0x9e, 0x0c, 0x27, 0xca, 0x94, 0x55, 0xf7, 0x31, 0xab, 0x1a, 0xe2, 0x67, 0x6f, 0xce, 0xd8, - 0xd9, 0x25, 0x6e, 0x5d, 0xaf, 0xb9, 0x94, 0x53, 0x94, 0x0b, 0xde, 0xea, 0xe2, 0x67, 0x6f, 0xae, - 0x70, 0xa5, 0x42, 0x2b, 0x54, 0xbc, 0x34, 0xbc, 0x2b, 0xdf, 0xae, 0xd0, 0x19, 0x85, 0xd7, 0x6b, - 0x84, 0x05, 0x6f, 0x2b, 0x94, 0x56, 0xb6, 0x89, 0x81, 0x6b, 0xb6, 0x81, 0x1d, 0x87, 0x72, 0xcc, - 0x6d, 0xea, 0x04, 0x6f, 0x67, 0x3c, 0x5f, 0xca, 0x8c, 0x12, 0x66, 0xc4, 0x5f, 0xdc, 0xd8, 0x9b, - 0x2b, 0x11, 0x8e, 0xe7, 0x8c, 0x1a, 0xae, 0xd8, 0x8e, 0x30, 0xf6, 0x6d, 0xb5, 0x05, 0x98, 0xbf, - 0xe7, 0x59, 0x2c, 0x51, 0x87, 0xbb, 0xb8, 0xcc, 0x57, 0x9c, 0x4d, 0x6a, 0x92, 0x9d, 0x5d, 0xc2, - 0x38, 0xca, 0xc3, 0x34, 0xb6, 0x2c, 0x97, 0x30, 0x96, 0x07, 0x93, 0x60, 0x3a, 0x6b, 0x06, 0xb7, - 0xda, 0xd7, 0x00, 0xbe, 0xd2, 0xc5, 0x8d, 0xd5, 0xa8, 0xc3, 0x48, 0xbc, 0x1f, 0xba, 0x07, 0x5f, - 0x28, 0x4b, 0x8f, 0x0d, 0xdb, 0xd9, 0xa4, 0xf9, 0xa1, 0x49, 0x30, 0x3d, 0x32, 0xaf, 0xe8, 0xed, - 0xaa, 0xe8, 0xe1, 0xc0, 0xc5, 0xd1, 0xa3, 0x86, 0x9a, 0x38, 0x6e, 0xa8, 0xe0, 0xb4, 0xa1, 0x26, - 0xcc, 0xd1, 0x72, 0xe8, 0xdd, 0x7b, 0xc9, 0xff, 0x7e, 0x52, 0x81, 0xf6, 0x19, 0x7c, 0x35, 0xc2, - 0xb3, 0x6c, 0x33, 0x4e, 0xdd, 0x7a, 0xcf, 0x4c, 0xd0, 0x47, 0x10, 0x9e, 0x69, 0x22, 0x71, 0xa6, - 0x74, 0x5f, 0x40, 0xdd, 0x13, 0x50, 0xf7, 0x77, 0x4f, 0x0a, 0xa8, 0xaf, 0xe3, 0x0a, 0x91, 0x51, - 0xcd, 0x90, 0xa7, 0xf6, 0x3b, 0x80, 0x13, 0xdd, 0x09, 0xa4, 0x28, 0xab, 0x30, 0x4d, 0x1c, 0xee, - 0xda, 0xc4, 0x43, 0xb8, 0x34, 0x3d, 0x32, 0x3f, 0x13, 0x9f, 0xf4, 0x12, 0xb5, 0x88, 0xf4, 0xff, - 0xd0, 0xe1, 0x6e, 0xbd, 0x98, 0xf4, 0x04, 0x30, 0x83, 0x00, 0xe8, 0x6e, 0x17, 0xe8, 0x37, 0x7a, - 0x42, 0xfb, 0x20, 0x11, 0xea, 0x4f, 0xdb, 0x64, 0x63, 0xc5, 0xba, 0xb7, 0x76, 0x20, 0xdb, 0x38, - 0x4c, 0x97, 0xa9, 0x45, 0x36, 0x6c, 0x4b, 0xc8, 0x96, 0x34, 0x53, 0xde, 0xed, 0x8a, 0x35, 0x30, - 0xd5, 0xbe, 0x68, 0x57, 0xad, 0x05, 0x20, 0x55, 0x9b, 0x80, 0xd9, 0x60, 0xb7, 0x7d, 0xdd, 0xb2, - 0xe6, 0xd9, 0x83, 0xc1, 0xe9, 0xf0, 0x79, 0xc0, 0x71, 0x7b, 0x7b, 0x3b, 0x40, 0xb9, 0xcf, 0x31, - 0x27, 0xcf, 0xaf, 0x80, 0x7e, 0x04, 0xf0, 0x6a, 0x0c, 0x82, 0xd4, 0x62, 0x11, 0xa6, 0xaa, 0xd4, - 0x22, 0xdb, 0x41, 0x01, 0x8d, 0x77, 0x16, 0xd0, 0x9a, 0xf7, 0x5e, 0x56, 0x8b, 0x34, 0x1e, 0x9c, - 0x48, 0x0f, 0xa4, 0x46, 0x26, 0xde, 0xbf, 0xa0, 0x46, 0x57, 0x21, 0x14, 0x6b, 0x6c, 0x58, 0x98, - 0x63, 0x81, 0x30, 0x6a, 0x66, 0xc5, 0x93, 0x3b, 0x98, 0x63, 0xed, 0xa6, 0xcc, 0xbc, 0x33, 0xb0, - 0xcc, 0x1c, 0xc1, 0xa4, 0xf0, 0x04, 0xc2, 0x53, 0x5c, 0x6b, 0x3b, 0x50, 0x11, 0x4e, 0xf7, 0xab, - 0xd8, 0xe5, 0x17, 0xe4, 0x59, 0xec, 0xe4, 0x29, 0x8e, 0x3d, 0x6d, 0xa8, 0x28, 0x44, 0xb0, 0x46, - 0x18, 0xf3, 0x94, 0x08, 0x71, 0xae, 0x41, 0x35, 0x76, 0x49, 0x49, 0x3a, 0x13, 0x26, 0x8d, 0x8d, - 0xe9, 0x67, 0x70, 0x03, 0xe6, 0x64, 0xed, 0xf7, 0xfe, 0xe2, 0xb4, 0x1f, 0x86, 0x60, 0xce, 0x33, - 0x8c, 0x34, 0xda, 0xeb, 0x6d, 0xd6, 0xc5, 0x5c, 0xb3, 0xa1, 0xa6, 0x84, 0xd9, 0x9d, 0xd3, 0x86, - 0x3a, 0x64, 0x5b, 0xad, 0x2f, 0x36, 0x0f, 0xd3, 0x65, 0x97, 0x60, 0x4e, 0x5d, 0x91, 0x6f, 0xd6, - 0x0c, 0x6e, 0xd1, 0xc7, 0x30, 0xeb, 0xe1, 0x6c, 0x6c, 0x61, 0xb6, 0x95, 0xbf, 0x24, 0xb8, 0xdf, - 0x79, 0xda, 0x50, 0x17, 0x2a, 0x36, 0xdf, 0xda, 0x2d, 0xe9, 0x65, 0x5a, 0x35, 0x38, 0x71, 0x2c, - 0xe2, 0x56, 0x6d, 0x87, 0x87, 0x2f, 0xb7, 0xed, 0x12, 0x33, 0x4a, 0x75, 0x4e, 0x98, 0xbe, 0x4c, - 0x1e, 0x15, 0xbd, 0x0b, 0x33, 0xe3, 0x85, 0x5a, 0xc6, 0x6c, 0x0b, 0x3d, 0x84, 0x63, 0xb6, 0xc3, - 0x38, 0x76, 0xb8, 0x8d, 0x39, 0xd9, 0xa8, 0x79, 0x4e, 0x8c, 0x79, 0x25, 0x98, 0x8a, 0xeb, 0xf9, - 0xb7, 0xcb, 0x65, 0xc2, 0xd8, 0x12, 0x75, 0x36, 0xed, 0x8a, 0x2c, 0xe2, 0x97, 0x43, 0x31, 0xd6, - 0x5b, 0x21, 0xfc, 0xa6, 0xbf, 0x9a, 0xcc, 0x24, 0x73, 0xc3, 0xab, 0xc9, 0xcc, 0x70, 0x2e, 0xa5, - 0x3d, 0x06, 0xf0, 0xc5, 0x90, 0x9a, 0x52, 0xa0, 0x15, 0xaf, 0x7d, 0x78, 0x02, 0x79, 0x67, 0x0d, - 0x10, 0xeb, 0x6a, 0xdd, 0xda, 0x6e, 0x54, 0xd7, 0x62, 0xa6, 0x75, 0xd6, 0x64, 0xca, 0xf2, 0x1d, - 0x9a, 0x90, 0x3b, 0xeb, 0x57, 0x4b, 0xe6, 0xb4, 0xa1, 0x8a, 0x7b, 0x7f, 0x2f, 0xe5, 0x29, 0xf4, - 0x30, 0xc4, 0xc0, 0x82, 0x2d, 0x8d, 0x36, 0x08, 0xf0, 0xcc, 0x0d, 0xe2, 0x09, 0x80, 0x28, 0x1c, - 0x5d, 0xa6, 0x78, 0x17, 0xc2, 0x56, 0x8a, 0x41, 0x67, 0xe8, 0x27, 0x47, 0x5f, 0xdf, 0x6c, 0x90, - 0xdf, 0x00, 0xfb, 0x04, 0x86, 0xe3, 0x82, 0x73, 0xdd, 0x76, 0x1c, 0x62, 0x9d, 0xa3, 0xc5, 0xb3, - 0x37, 0xcb, 0x6f, 0x80, 0x1c, 0x5b, 0x22, 0x6b, 0xb4, 0xbe, 0xc1, 0x8c, 0xfc, 0x2a, 0x7c, 0x3d, - 0x92, 0xc5, 0xcb, 0x5e, 0xae, 0xcd, 0x86, 0x9a, 0xf6, 0x3f, 0x0d, 0x66, 0xa6, 0xfd, 0xaf, 0x62, - 0x80, 0x49, 0x5f, 0x91, 0x9b, 0xb3, 0x8e, 0x5d, 0x5c, 0x0d, 0xf2, 0xd5, 0xd6, 0xe0, 0x4b, 0x91, - 0xa7, 0x92, 0xf0, 0x6d, 0x98, 0xaa, 0x89, 0x27, 0xb2, 0x1c, 0xf2, 0x9d, 0xfb, 0xe5, 0x7b, 0x04, - 0xad, 0xdc, 0xb7, 0x9e, 0xff, 0x72, 0x14, 0x0e, 0x8b, 0x78, 0xe8, 0x7b, 0x00, 0x47, 0xc3, 0x23, - 0x12, 0xea, 0x32, 0x4d, 0xc4, 0xcd, 0x75, 0x85, 0x1b, 0x7d, 0xd9, 0xfa, 0xac, 0xda, 0xec, 0xe3, - 0x3f, 0xff, 0xfd, 0x6e, 0x68, 0x0a, 0x5d, 0x33, 0x3a, 0x26, 0xd2, 0xe0, 0x20, 0x36, 0x0e, 0x64, - 0x63, 0x3d, 0x44, 0x4f, 0x00, 0xbc, 0xdc, 0x36, 0x01, 0xa1, 0x37, 0x7b, 0x2c, 0x17, 0x9d, 0xd5, - 0x0a, 0x7a, 0xbf, 0xe6, 0x12, 0x70, 0x41, 0x00, 0xea, 0x68, 0xb6, 0x1f, 0x40, 0x63, 0x4b, 0x42, - 0xfd, 0x1c, 0x02, 0x95, 0x43, 0x47, 0x4f, 0xd0, 0xe8, 0x74, 0xd4, 0x13, 0xb4, 0x6d, 0x96, 0xd1, - 0xe6, 0x05, 0xe8, 0x2c, 0x9a, 0xe9, 0x06, 0x6a, 0x11, 0xe3, 0x40, 0x56, 0xed, 0xa1, 0x71, 0x36, - 0xe1, 0xfc, 0x02, 0x60, 0xae, 0x7d, 0x20, 0x40, 0x71, 0x0b, 0xc7, 0x0c, 0x2f, 0x05, 0xa3, 0x6f, - 0xfb, 0x7e, 0x48, 0x3b, 0x24, 0x65, 0x02, 0xea, 0x37, 0x00, 0x73, 0xed, 0x07, 0x78, 0x2c, 0x69, - 0xcc, 0x08, 0x11, 0x4b, 0x1a, 0x37, 0x19, 0x68, 0xef, 0x0b, 0xd2, 0x5b, 0x68, 0xb1, 0x2f, 0x52, - 0x17, 0xef, 0x1b, 0x07, 0x67, 0x27, 0xff, 0x21, 0xfa, 0x03, 0x40, 0xd4, 0x79, 0x9a, 0xa3, 0xb7, - 0x62, 0x30, 0x62, 0x67, 0x8d, 0xc2, 0xdc, 0x05, 0x3c, 0x24, 0xfa, 0x07, 0x02, 0xfd, 0x5d, 0x74, - 0xab, 0x3f, 0x91, 0xbd, 0x40, 0x51, 0xf8, 0x3a, 0x4c, 0x8a, 0xb2, 0xd5, 0x62, 0xeb, 0xf0, 0xac, - 0x56, 0x5f, 0x3b, 0xd7, 0x46, 0x12, 0x4d, 0x0b, 0x22, 0x0d, 0x4d, 0xf6, 0x2a, 0x50, 0xe4, 0xc2, - 0x61, 0xd1, 0x73, 0xd1, 0x79, 0x71, 0x83, 0x2e, 0x58, 0xb8, 0x76, 0xbe, 0x91, 0x5c, 0x5d, 0x11, - 0xab, 0xe7, 0xd1, 0x58, 0xf7, 0xd5, 0xd1, 0x57, 0x00, 0x8e, 0x84, 0xda, 0x3d, 0xba, 0x1e, 0x13, - 0xb5, 0xf3, 0xd8, 0x29, 0xcc, 0xf4, 0x63, 0x2a, 0x31, 0xa6, 0x04, 0xc6, 0x24, 0x52, 0xba, 0x63, - 0x30, 0xa3, 0x26, 0x9c, 0xd0, 0x21, 0x4c, 0xf9, 0x3d, 0x1a, 0xc5, 0xa5, 0x17, 0x39, 0x0a, 0x0a, - 0xaf, 0xf7, 0xb0, 0xea, 0x7b, 0x79, 0xff, 0x60, 0x58, 0x3e, 0xfa, 0x47, 0x49, 0xfc, 0xda, 0x54, - 0x12, 0x47, 0x4d, 0x05, 0x1c, 0x37, 0x15, 0xf0, 0x77, 0x53, 0x01, 0xdf, 0x9e, 0x28, 0x89, 0xe3, - 0x13, 0x25, 0xf1, 0xd7, 0x89, 0x92, 0xf8, 0x64, 0x2a, 0x34, 0xc0, 0x2d, 0x51, 0x56, 0x7d, 0x10, - 0xc4, 0xb2, 0x8c, 0x47, 0x7e, 0x4c, 0xf1, 0x8f, 0x42, 0x29, 0x25, 0xfe, 0x08, 0xb8, 0xf9, 0x7f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa4, 0x0e, 0x41, 0xb8, 0x10, 0x00, 0x00, + // 1331 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xcd, 0x6f, 0x1b, 0xc5, + 0x1b, 0xc7, 0x3d, 0xa9, 0xe3, 0x97, 0x69, 0xfa, 0xab, 0x3b, 0xbf, 0xd2, 0x18, 0x93, 0xae, 0xa3, + 0xa5, 0xa4, 0x69, 0x9a, 0xee, 0x92, 0x34, 0xa1, 0x80, 0x84, 0x50, 0x9c, 0x42, 0x93, 0x48, 0x91, + 0xd2, 0xad, 0x50, 0x25, 0x7a, 0xb0, 0xc6, 0xde, 0x89, 0xb3, 0x52, 0xbc, 0xeb, 0xec, 0x4c, 0x92, + 0x5a, 0x51, 0x00, 0x55, 0xe2, 0x86, 0x78, 0x11, 0xe2, 0xc0, 0x01, 0xc1, 0x01, 0x15, 0xce, 0x70, + 0x41, 0x5c, 0xb9, 0xe4, 0x18, 0x89, 0x0b, 0x27, 0x0b, 0x1c, 0x0e, 0x28, 0x7f, 0x42, 0x4f, 0x68, + 0x67, 0x67, 0x9c, 0x5d, 0xdb, 0x1b, 0x3b, 0x95, 0xc5, 0xc5, 0xda, 0xdd, 0x79, 0x66, 0x9e, 0xcf, + 0xf3, 0x9d, 0x67, 0xe6, 0x79, 0x64, 0x38, 0x56, 0x76, 0x68, 0x75, 0x17, 0xd3, 0xaa, 0xce, 0x7f, + 0x76, 0x66, 0xf4, 0xad, 0x6d, 0xe2, 0xd6, 0xb5, 0x9a, 0xeb, 0x30, 0x07, 0x65, 0xe4, 0xa8, 0xc6, + 0x7f, 0x76, 0x66, 0x72, 0x97, 0x2b, 0x4e, 0xc5, 0xe1, 0x83, 0xba, 0xf7, 0xe4, 0xdb, 0xe5, 0x3a, + 0x57, 0x61, 0xf5, 0x1a, 0xa1, 0x72, 0xb4, 0xe2, 0x38, 0x95, 0x4d, 0xa2, 0xe3, 0x9a, 0xa5, 0x63, + 0xdb, 0x76, 0x18, 0x66, 0x96, 0x63, 0xcb, 0xd1, 0x29, 0x6f, 0xae, 0x43, 0xf5, 0x12, 0xa6, 0xc4, + 0x77, 0xae, 0xef, 0xcc, 0x94, 0x08, 0xc3, 0x33, 0x7a, 0x0d, 0x57, 0x2c, 0x9b, 0x1b, 0xfb, 0xb6, + 0xea, 0x1c, 0xcc, 0xde, 0xf7, 0x2c, 0x16, 0x1d, 0x9b, 0xb9, 0xb8, 0xcc, 0x96, 0xed, 0x75, 0xc7, + 0x20, 0x5b, 0xdb, 0x84, 0x32, 0x94, 0x85, 0x49, 0x6c, 0x9a, 0x2e, 0xa1, 0x34, 0x0b, 0xc6, 0xc1, + 0x64, 0xda, 0x90, 0xaf, 0xea, 0xa7, 0x00, 0xbe, 0xd8, 0x65, 0x1a, 0xad, 0x39, 0x36, 0x25, 0xd1, + 0xf3, 0xd0, 0x7d, 0x78, 0xa1, 0x2c, 0x66, 0x14, 0x2d, 0x7b, 0xdd, 0xc9, 0x0e, 0x8d, 0x83, 0xc9, + 0xf3, 0xb3, 0x8a, 0xd6, 0xae, 0x8a, 0x16, 0x5c, 0xb8, 0x30, 0x72, 0xd0, 0xc8, 0xc7, 0x0e, 0x1b, + 0x79, 0x70, 0xdc, 0xc8, 0xc7, 0x8c, 0x91, 0x72, 0x60, 0xec, 0xcd, 0xf8, 0x3f, 0xdf, 0xe5, 0x81, + 0xfa, 0x21, 0x7c, 0x29, 0xc4, 0xb3, 0x64, 0x51, 0xe6, 0xb8, 0xf5, 0x9e, 0x91, 0xa0, 0x77, 0x21, + 0x3c, 0xd1, 0x44, 0xe0, 0x4c, 0x68, 0xbe, 0x80, 0x9a, 0x27, 0xa0, 0xe6, 0xef, 0x9e, 0x10, 0x50, + 0x5b, 0xc3, 0x15, 0x22, 0x56, 0x35, 0x02, 0x33, 0xd5, 0x9f, 0x01, 0x1c, 0xeb, 0x4e, 0x20, 0x44, + 0x59, 0x81, 0x49, 0x62, 0x33, 0xd7, 0x22, 0x1e, 0xc2, 0xb9, 0xc9, 0xf3, 0xb3, 0x53, 0xd1, 0x41, + 0x2f, 0x3a, 0x26, 0x11, 0xf3, 0xdf, 0xb1, 0x99, 0x5b, 0x2f, 0xc4, 0x3d, 0x01, 0x0c, 0xb9, 0x00, + 0xba, 0xd7, 0x05, 0xfa, 0x7a, 0x4f, 0x68, 0x1f, 0x24, 0x44, 0xfd, 0x41, 0x9b, 0x6c, 0xb4, 0x50, + 0xf7, 0x7c, 0x4b, 0xd9, 0x46, 0x61, 0xb2, 0xec, 0x98, 0xa4, 0x68, 0x99, 0x5c, 0xb6, 0xb8, 0x91, + 0xf0, 0x5e, 0x97, 0xcd, 0x81, 0xa9, 0xf6, 0x71, 0xbb, 0x6a, 0x2d, 0x00, 0xa1, 0xda, 0x18, 0x4c, + 0xcb, 0xdd, 0xf6, 0x75, 0x4b, 0x1b, 0x27, 0x1f, 0x06, 0xa7, 0xc3, 0x47, 0x92, 0x63, 0x61, 0x73, + 0x53, 0xa2, 0x3c, 0x60, 0x98, 0x91, 0xff, 0x2e, 0x81, 0xbe, 0x05, 0xf0, 0x6a, 0x04, 0x82, 0xd0, + 0x62, 0x1e, 0x26, 0xaa, 0x8e, 0x49, 0x36, 0x65, 0x02, 0x8d, 0x76, 0x26, 0xd0, 0xaa, 0x37, 0x2e, + 0xb2, 0x45, 0x18, 0x0f, 0x4e, 0xa4, 0x87, 0x42, 0x23, 0x03, 0xef, 0x9e, 0x51, 0xa3, 0xab, 0x10, + 0x72, 0x1f, 0x45, 0x13, 0x33, 0xcc, 0x11, 0x46, 0x8c, 0x34, 0xff, 0x72, 0x17, 0x33, 0xac, 0xde, + 0x16, 0x91, 0x77, 0x2e, 0x2c, 0x22, 0x47, 0x30, 0xce, 0x67, 0x02, 0x3e, 0x93, 0x3f, 0xab, 0x5b, + 0x50, 0xe1, 0x93, 0x1e, 0x54, 0xb1, 0xcb, 0xce, 0xc8, 0x33, 0xdf, 0xc9, 0x53, 0xb8, 0xf2, 0xac, + 0x91, 0x47, 0x01, 0x82, 0x55, 0x42, 0xa9, 0xa7, 0x44, 0x80, 0x73, 0x15, 0xe6, 0x23, 0x5d, 0x0a, + 0xd2, 0xa9, 0x20, 0x69, 0xe4, 0x9a, 0x7e, 0x04, 0x37, 0x61, 0x46, 0xe4, 0x7e, 0xef, 0x13, 0xa7, + 0x7e, 0x33, 0x04, 0x33, 0x9e, 0x61, 0xe8, 0xa2, 0xbd, 0xd1, 0x66, 0x5d, 0xc8, 0x34, 0x1b, 0xf9, + 0x04, 0x37, 0xbb, 0x7b, 0xdc, 0xc8, 0x0f, 0x59, 0x66, 0xeb, 0xc4, 0x66, 0x61, 0xb2, 0xec, 0x12, + 0xcc, 0x1c, 0x97, 0xc7, 0x9b, 0x36, 0xe4, 0x2b, 0x7a, 0x0f, 0xa6, 0x3d, 0x9c, 0xe2, 0x06, 0xa6, + 0x1b, 0xd9, 0x73, 0x9c, 0xfb, 0xf5, 0x67, 0x8d, 0xfc, 0x5c, 0xc5, 0x62, 0x1b, 0xdb, 0x25, 0xad, + 0xec, 0x54, 0x75, 0x46, 0x6c, 0x93, 0xb8, 0x55, 0xcb, 0x66, 0xc1, 0xc7, 0x4d, 0xab, 0x44, 0xf5, + 0x52, 0x9d, 0x11, 0xaa, 0x2d, 0x91, 0xc7, 0x05, 0xef, 0xc1, 0x48, 0x79, 0x4b, 0x2d, 0x61, 0xba, + 0x81, 0x1e, 0xc1, 0x2b, 0x96, 0x4d, 0x19, 0xb6, 0x99, 0x85, 0x19, 0x29, 0xd6, 0xbc, 0x49, 0x94, + 0x7a, 0x29, 0x98, 0x88, 0xba, 0xf3, 0x17, 0xca, 0x65, 0x42, 0xe9, 0xa2, 0x63, 0xaf, 0x5b, 0x15, + 0x91, 0xc4, 0x2f, 0x04, 0xd6, 0x58, 0x6b, 0x2d, 0xe1, 0x5f, 0xfa, 0x2b, 0xf1, 0x54, 0x3c, 0x33, + 0xbc, 0x12, 0x4f, 0x0d, 0x67, 0x12, 0xea, 0x13, 0x00, 0x2f, 0x05, 0xd4, 0x14, 0x02, 0x2d, 0x7b, + 0xd7, 0x87, 0x27, 0x90, 0x57, 0x6b, 0x00, 0xf7, 0xab, 0x76, 0xbb, 0x76, 0xc3, 0xba, 0x16, 0x52, + 0xad, 0x5a, 0x93, 0x2a, 0x8b, 0x31, 0x34, 0x26, 0x76, 0xd6, 0xcf, 0x96, 0xd4, 0x71, 0x23, 0xcf, + 0xdf, 0xfd, 0xbd, 0x14, 0x55, 0xe8, 0x51, 0x80, 0x81, 0xca, 0x2d, 0x0d, 0x5f, 0x10, 0xe0, 0xb9, + 0x2f, 0x88, 0xa7, 0x00, 0xa2, 0xe0, 0xea, 0x22, 0xc4, 0x7b, 0x10, 0xb6, 0x42, 0x94, 0x37, 0x43, + 0x3f, 0x31, 0xfa, 0xfa, 0xa6, 0x65, 0x7c, 0x03, 0xbc, 0x27, 0x30, 0x1c, 0xe5, 0x9c, 0x6b, 0x96, + 0x6d, 0x13, 0xf3, 0x14, 0x2d, 0x9e, 0xff, 0xb2, 0xfc, 0x0c, 0x88, 0xb6, 0x25, 0xe4, 0xa3, 0x75, + 0x06, 0x53, 0xe2, 0x54, 0xf8, 0x7a, 0xc4, 0x0b, 0x17, 0xbd, 0x58, 0x9b, 0x8d, 0x7c, 0xd2, 0x3f, + 0x1a, 0xd4, 0x48, 0xfa, 0xa7, 0x62, 0x80, 0x41, 0x5f, 0x16, 0x9b, 0xb3, 0x86, 0x5d, 0x5c, 0x95, + 0xf1, 0xaa, 0xab, 0xf0, 0xff, 0xa1, 0xaf, 0x82, 0xf0, 0x35, 0x98, 0xa8, 0xf1, 0x2f, 0x22, 0x1d, + 0xb2, 0x9d, 0xfb, 0xe5, 0xcf, 0x90, 0x57, 0xb9, 0x6f, 0xad, 0x7e, 0x01, 0xc4, 0xa5, 0x17, 0x2c, + 0x97, 0xfe, 0x31, 0x96, 0x0a, 0x5f, 0x87, 0x17, 0xc5, 0xc1, 0x2e, 0x86, 0x2f, 0xbf, 0xff, 0x89, + 0xcf, 0x0b, 0x03, 0xae, 0x5b, 0x5f, 0x03, 0x71, 0x2b, 0x76, 0x63, 0x12, 0xf1, 0xde, 0x82, 0xa8, + 0xd5, 0xf6, 0x09, 0x2a, 0x22, 0xcb, 0xf9, 0x25, 0x39, 0xb2, 0x20, 0x07, 0x06, 0xb6, 0x29, 0xb3, + 0xbf, 0x5d, 0x80, 0xc3, 0x9c, 0x0d, 0x7d, 0x05, 0xe0, 0x48, 0xb0, 0xa5, 0x44, 0x5d, 0xba, 0xaf, + 0xa8, 0x3e, 0x38, 0x77, 0xb3, 0x2f, 0x5b, 0xdf, 0xbf, 0x3a, 0xfd, 0xe4, 0xf7, 0xbf, 0xbf, 0x1c, + 0x9a, 0x40, 0xd7, 0xf4, 0x8e, 0x0e, 0x5e, 0x46, 0xaa, 0xef, 0x09, 0x11, 0xf6, 0xd1, 0x53, 0x00, + 0x2f, 0xb6, 0x75, 0x8c, 0xe8, 0x56, 0x0f, 0x77, 0xe1, 0xde, 0x36, 0xa7, 0xf5, 0x6b, 0x2e, 0x00, + 0xe7, 0x38, 0xa0, 0x86, 0xa6, 0xfb, 0x01, 0xd4, 0x37, 0x04, 0xd4, 0xf7, 0x01, 0x50, 0xd1, 0xa4, + 0xf5, 0x04, 0x0d, 0x77, 0x93, 0x3d, 0x41, 0xdb, 0x7a, 0x3f, 0x75, 0x96, 0x83, 0x4e, 0xa3, 0xa9, + 0x6e, 0xa0, 0x26, 0xd1, 0xf7, 0xc4, 0x29, 0xdf, 0xd7, 0x4f, 0x3a, 0xc2, 0x1f, 0x00, 0xcc, 0xb4, + 0x37, 0x50, 0x28, 0xca, 0x71, 0x44, 0xb3, 0x97, 0xd3, 0xfb, 0xb6, 0xef, 0x87, 0xb4, 0x43, 0x52, + 0xca, 0xa1, 0x7e, 0x02, 0x30, 0xd3, 0xde, 0xf0, 0x44, 0x92, 0x46, 0xb4, 0x5c, 0x91, 0xa4, 0x51, + 0x9d, 0x94, 0xfa, 0x16, 0x27, 0xbd, 0x83, 0xe6, 0xfb, 0x22, 0x75, 0xf1, 0xae, 0xbe, 0x77, 0xd2, + 0x29, 0xed, 0xa3, 0x5f, 0x01, 0x44, 0x9d, 0xdd, 0x0f, 0x7a, 0x35, 0x02, 0x23, 0xb2, 0x37, 0xcb, + 0xcd, 0x9c, 0x61, 0x86, 0x40, 0x7f, 0x9b, 0xa3, 0xbf, 0x81, 0xee, 0xf4, 0x27, 0xb2, 0xb7, 0x50, + 0x18, 0xbe, 0x0e, 0xe3, 0x3c, 0x6d, 0xd5, 0xc8, 0x3c, 0x3c, 0xc9, 0xd5, 0x97, 0x4f, 0xb5, 0x11, + 0x44, 0x93, 0x9c, 0x48, 0x45, 0xe3, 0xbd, 0x12, 0x14, 0xb9, 0x70, 0x98, 0xd7, 0x28, 0x74, 0xda, + 0xba, 0xb2, 0x6a, 0xe4, 0xae, 0x9d, 0x6e, 0x24, 0xbc, 0x2b, 0xdc, 0x7b, 0x16, 0x5d, 0xe9, 0xee, + 0x1d, 0x7d, 0x02, 0xe0, 0xf9, 0x40, 0x79, 0x44, 0x37, 0x22, 0x56, 0xed, 0x2c, 0xd3, 0xb9, 0xa9, + 0x7e, 0x4c, 0x05, 0xc6, 0x04, 0xc7, 0x18, 0x47, 0x4a, 0x77, 0x0c, 0xaa, 0xd7, 0xf8, 0x24, 0xb4, + 0x0f, 0x13, 0x7e, 0x4d, 0x43, 0x51, 0xe1, 0x85, 0x4a, 0x67, 0xee, 0x95, 0x1e, 0x56, 0x7d, 0xbb, + 0xf7, 0x9d, 0xfe, 0x02, 0x20, 0xea, 0xac, 0x50, 0x91, 0x99, 0x1b, 0x59, 0x60, 0x23, 0x33, 0x37, + 0xba, 0xfc, 0xf5, 0x73, 0xe8, 0xa8, 0x2e, 0xca, 0xb3, 0xbe, 0xd7, 0x56, 0xbe, 0xf7, 0x0b, 0x4b, + 0x07, 0x7f, 0x29, 0xb1, 0x1f, 0x9b, 0x4a, 0xec, 0xa0, 0xa9, 0x80, 0xc3, 0xa6, 0x02, 0xfe, 0x6c, + 0x2a, 0xe0, 0xf3, 0x23, 0x25, 0x76, 0x78, 0xa4, 0xc4, 0xfe, 0x38, 0x52, 0x62, 0xef, 0x4f, 0x04, + 0x7a, 0xf5, 0x45, 0x87, 0x56, 0x1f, 0x4a, 0x17, 0xa6, 0xfe, 0xd8, 0x77, 0xc5, 0xff, 0x3c, 0x2a, + 0x25, 0xf8, 0x7f, 0x3e, 0xb7, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x78, 0x46, 0xe1, 0xa8, 0xa3, + 0x12, 0x00, 0x00, } func (this *QueryContractInfoResponse) Equal(that interface{}) bool { @@ -1217,6 +1319,8 @@ type QueryClient interface { PinnedCodes(ctx context.Context, in *QueryPinnedCodesRequest, opts ...grpc.CallOption) (*QueryPinnedCodesResponse, error) // Params gets the module params Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // ContractsByCreator gets the contracts by creator + ContractsByCreator(ctx context.Context, in *QueryContractsByCreatorRequest, opts ...grpc.CallOption) (*QueryContractsByCreatorResponse, error) } type queryClient struct { @@ -1317,6 +1421,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) ContractsByCreator(ctx context.Context, in *QueryContractsByCreatorRequest, opts ...grpc.CallOption) (*QueryContractsByCreatorResponse, error) { + out := new(QueryContractsByCreatorResponse) + err := c.cc.Invoke(ctx, "/cosmwasm.wasm.v1.Query/ContractsByCreator", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ContractInfo gets the contract meta data @@ -1339,6 +1452,8 @@ type QueryServer interface { PinnedCodes(context.Context, *QueryPinnedCodesRequest) (*QueryPinnedCodesResponse, error) // Params gets the module params Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // ContractsByCreator gets the contracts by creator + ContractsByCreator(context.Context, *QueryContractsByCreatorRequest) (*QueryContractsByCreatorResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1384,6 +1499,10 @@ func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsReq return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) ContractsByCreator(ctx context.Context, req *QueryContractsByCreatorRequest) (*QueryContractsByCreatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ContractsByCreator not implemented") +} + func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } @@ -1568,6 +1687,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_ContractsByCreator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryContractsByCreatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ContractsByCreator(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmwasm.wasm.v1.Query/ContractsByCreator", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ContractsByCreator(ctx, req.(*QueryContractsByCreatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmwasm.wasm.v1.Query", HandlerType: (*QueryServer)(nil), @@ -1612,6 +1749,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "ContractsByCreator", + Handler: _Query_ContractsByCreator_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmwasm/wasm/v1/query.proto", @@ -2437,6 +2578,92 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryContractsByCreatorRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryContractsByCreatorRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryContractsByCreatorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.CreatorAddress) > 0 { + i -= len(m.CreatorAddress) + copy(dAtA[i:], m.CreatorAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.CreatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryContractsByCreatorResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryContractsByCreatorResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryContractsByCreatorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddresses) > 0 { + for iNdEx := len(m.ContractAddresses) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ContractAddresses[iNdEx]) + copy(dAtA[i:], m.ContractAddresses[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddresses[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2780,6 +3007,42 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QueryContractsByCreatorRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CreatorAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryContractsByCreatorResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ContractAddresses) > 0 { + for _, s := range m.ContractAddresses { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -5049,6 +5312,244 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { return nil } +func (m *QueryContractsByCreatorRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryContractsByCreatorRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryContractsByCreatorRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CreatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *QueryContractsByCreatorResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryContractsByCreatorResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryContractsByCreatorResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddresses", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddresses = append(m.ContractAddresses, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/wasm/types/query.pb.gw.go b/x/wasm/types/query.pb.gw.go index 1fa96f457a..527cac4e74 100644 --- a/x/wasm/types/query.pb.gw.go +++ b/x/wasm/types/query.pb.gw.go @@ -572,6 +572,74 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal return msg, metadata, err } +var filter_Query_ContractsByCreator_0 = &utilities.DoubleArray{Encoding: map[string]int{"creator_address": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + +func request_Query_ContractsByCreator_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryContractsByCreatorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creator_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator_address") + } + + protoReq.CreatorAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator_address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractsByCreator_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ContractsByCreator(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_Query_ContractsByCreator_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryContractsByCreatorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creator_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creator_address") + } + + protoReq.CreatorAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creator_address", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ContractsByCreator_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ContractsByCreator(ctx, &protoReq) + return msg, metadata, err +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -797,6 +865,25 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("GET", pattern_Query_ContractsByCreator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ContractsByCreator_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ContractsByCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -1027,6 +1114,25 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle("GET", pattern_Query_ContractsByCreator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ContractsByCreator_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ContractsByCreator_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) + return nil } @@ -1049,7 +1155,9 @@ var ( pattern_Query_PinnedCodes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "pinned"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ContractsByCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmwasm", "wasm", "v1", "contracts", "creator", "creator_address"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -1072,4 +1180,6 @@ var ( forward_Query_PinnedCodes_0 = runtime.ForwardResponseMessage forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_ContractsByCreator_0 = runtime.ForwardResponseMessage ) From 7243617196723282f06671c926bc64e4aa4b45a2 Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Fri, 21 Oct 2022 18:01:51 +0700 Subject: [PATCH 004/294] Can a contract send data on a different's contract IBC (#1056) * add test contract send ibc not owned * add test send ibc diff contract counterparty channel * remove meaningless case --- x/wasm/relay_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index c1cff76c5b..7645f42365 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -356,6 +356,70 @@ func TestContractCanEmulateIBCTransferMessageWithTimeout(t *testing.T) { assert.Equal(t, initialSenderBalance.String(), newSenderBalance.String()) } +func TestContractEmulateIBCTransferMessageOnDiffContractIBCChannel(t *testing.T) { + // scenario: given two chains, A and B + // with 2 contract A1 and A2 on chain A + // then the contract A2 try to send an ibc packet via IBC Channel that create by A1 and B + myContractA1 := &sendEmulatedIBCTransferContract{} + myContractA2 := &sendEmulatedIBCTransferContract{} + + var ( + chainAOpts = []wasmkeeper.Option{ + wasmkeeper.WithWasmEngine( + wasmtesting.NewIBCContractMockWasmer(myContractA1), + ), + wasmkeeper.WithWasmEngine( + wasmtesting.NewIBCContractMockWasmer(myContractA2), + ), + } + + coordinator = wasmibctesting.NewCoordinator(t, 2, chainAOpts) + + chainA = coordinator.GetChain(wasmibctesting.GetChainID(0)) + chainB = coordinator.GetChain(wasmibctesting.GetChainID(1)) + ) + + coordinator.CommitBlock(chainA, chainB) + myContractAddr1 := chainA.SeedNewContractInstance() + myContractA1.contractAddr = myContractAddr1.String() + myContractAddr2 := chainA.SeedNewContractInstance() + myContractA2.contractAddr = myContractAddr2.String() + + path := wasmibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: chainA.ContractInfo(myContractAddr1).IBCPortID, + Version: ibctransfertypes.Version, + Order: channeltypes.UNORDERED, + } + path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: ibctransfertypes.PortID, + Version: ibctransfertypes.Version, + Order: channeltypes.UNORDERED, + } + coordinator.SetupConnections(path) + coordinator.CreateChannels(path) + + // when contract is triggered to send the ibc package to chain B + timeout := uint64(chainB.LastHeader.Header.Time.Add(time.Hour).UnixNano()) // enough time to not timeout + receiverAddress := chainB.SenderAccount.GetAddress() + coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + + // start transfer from chainA - A2 to chainB via IBC channel + startMsg := &types.MsgExecuteContract{ + Sender: chainA.SenderAccount.GetAddress().String(), + Contract: myContractAddr2.String(), + Msg: startTransfer{ + ChannelID: path.EndpointA.ChannelID, + CoinsToSend: coinToSendToB, + ReceiverAddr: receiverAddress.String(), + Timeout: timeout, + }.GetBytes(), + Funds: sdk.NewCoins(coinToSendToB), + } + _, err := chainA.SendMsgsExpPass(false, startMsg) + require.Error(t, err) +} + func TestContractHandlesChannelClose(t *testing.T) { // scenario: a contract is the sending side of an ics20 transfer but the packet was not received // on the destination chain within the timeout boundaries From 7ae500da5cfa8b10d52d120f7d4ed407392fe869 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:59:25 +0200 Subject: [PATCH 005/294] Bump bufbuild/buf-setup-action from 1.8.0 to 1.9.0 (#1057) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.8.0 to 1.9.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.8.0...v1.9.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 281eb4fc6e..88b2f465e9 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.1.0 - - uses: bufbuild/buf-setup-action@v1.8.0 + - uses: bufbuild/buf-setup-action@v1.9.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From 4f8673913a6ff12cb253eb8acd89e1af4c803ff9 Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Mon, 24 Oct 2022 17:21:05 -0500 Subject: [PATCH 006/294] Update instantiate cli example --- x/wasm/client/cli/tx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index d65e45c2d1..9a2eebfda8 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -183,7 +183,7 @@ func InstantiateContractCmd() *cobra.Command { Long: fmt.Sprintf(`Creates a new instance of an uploaded wasm code with the given 'constructor' message. Each contract instance has a unique address assigned. Example: -$ %s wasmd tx wasm instantiate 1 '{"foo":"bar"}' --admin="$(%s keys show mykey -a)" \ +$ %s tx wasm instantiate 1 '{"foo":"bar"}' --admin="$(%s keys show mykey -a)" \ --from mykey --amount="100ustake" --label "local0.1.0" `, version.AppName, version.AppName), Aliases: []string{"start", "init", "inst", "i"}, @@ -224,7 +224,7 @@ Each contract instance has a unique address assigned. They are assigned automati for special use cases, the given 'salt' argument and '--fix-msg' parameters can be used to generate a custom address. Predictable address example (also see '%s query wasm build-address -h'): -$ %s wasmd tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --admin="$(%s keys show mykey -a)" \ +$ %s tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --admin="$(%s keys show mykey -a)" \ --from mykey --amount="100ustake" --label "local0.1.0" \ --fix-msg `, version.AppName, version.AppName, version.AppName), From 0e0436ddae9383a8840f1679e91c431884985076 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Fri, 28 Oct 2022 13:02:04 +0700 Subject: [PATCH 007/294] bump core libraries --- go.mod | 24 ++++++++++++------------ go.sum | 46 ++++++++++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 216c2e57e7..9fc233ec7d 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,11 @@ go 1.18 require ( github.com/CosmWasm/wasmvm v1.1.1 - github.com/cosmos/cosmos-proto v1.0.0-alpha7 - github.com/cosmos/cosmos-sdk v0.45.9 + github.com/cosmos/cosmos-proto v1.0.0-alpha8 + github.com/cosmos/cosmos-sdk v0.45.10 github.com/cosmos/gogoproto v1.4.2 - github.com/cosmos/iavl v0.19.3 - github.com/cosmos/ibc-go/v3 v3.3.0 + github.com/cosmos/iavl v0.19.4 + github.com/cosmos/ibc-go/v3 v3.3.1 github.com/cosmos/interchain-accounts v0.1.0 github.com/dvsekhvalnov/jose2go v1.5.0 github.com/gogo/protobuf v1.3.3 @@ -26,10 +26,10 @@ require ( github.com/spf13/viper v1.13.0 github.com/stretchr/testify v1.8.0 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca - github.com/tendermint/tendermint v0.34.21 + github.com/tendermint/tendermint v0.34.22 github.com/tendermint/tm-db v0.6.7 google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b - google.golang.org/grpc v1.49.0 + google.golang.org/grpc v1.50.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -82,16 +82,16 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect github.com/improbable-eng/grpc-web v0.14.1 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/lib/pq v1.10.6 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect @@ -102,11 +102,11 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect github.com/rs/cors v1.8.2 // indirect github.com/rs/zerolog v1.27.0 // indirect - github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect diff --git a/go.sum b/go.sum index 235a94278b..b65bb5e76f 100644 --- a/go.sum +++ b/go.sum @@ -160,10 +160,10 @@ github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= -github.com/cosmos/cosmos-proto v1.0.0-alpha7 h1:yqYUOHF2jopwZh4dVQp3xgqwftE5/2hkrwIV6vkUbO0= -github.com/cosmos/cosmos-proto v1.0.0-alpha7/go.mod h1:dosO4pSAbJF8zWCzCoTWP7nNsjcvSUBQmniFxDg5daw= -github.com/cosmos/cosmos-sdk v0.45.9 h1:Z4s1EZL/mfM8uSSZr8WmyEbWp4hqbWVI5sAIFR432KY= -github.com/cosmos/cosmos-sdk v0.45.9/go.mod h1:Z5M4TX7PsHNHlF/1XanI2DIpORQ+Q/st7oaeufEjnvU= +github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= +github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= +github.com/cosmos/cosmos-sdk v0.45.10 h1:YRf1N6C7OFCc8FJ5wuhcnDDySJNDn5DxSscVgbeXgz4= +github.com/cosmos/cosmos-sdk v0.45.10/go.mod h1:CbfWNs4PuxxsvRD/snQuSBDwIhtsD7rIDTVQyYMKTa0= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -173,10 +173,10 @@ github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAY github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.3 h1:cESO0OwTTxQm5rmyESKW+zESheDUYI7CcZDWWDwnuxg= -github.com/cosmos/iavl v0.19.3/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v3 v3.3.0 h1:r8gYUvQreMQrf4R5RgedK9gcbjLk4uE2q6fuZGjf4n0= -github.com/cosmos/ibc-go/v3 v3.3.0/go.mod h1:VUWLHw0C3USmTQZnTdkuXXdUdLbW8zsK3lV1Ieposog= +github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= +github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/ibc-go/v3 v3.3.1 h1:i8o3iPSPN8fr7AjCPQnHEKz/VfeMrxc8mjvgAw6txWk= +github.com/cosmos/ibc-go/v3 v3.3.1/go.mod h1:V1nliDk/5q5KWr0mup7M76oN4SY0IOU371SKbCV2wN0= github.com/cosmos/interchain-accounts v0.1.0 h1:QmuwNsf1Hxl3P5GSGt7Z+JeuHPiZw4Z34R/038P5T6s= github.com/cosmos/interchain-accounts v0.1.0/go.mod h1:Fv6LXDs+0ng4mIDVWwEJMXbAIMxY4kiq+A7Bw1Fb9AY= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= @@ -344,8 +344,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -443,8 +442,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -507,16 +507,18 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -524,8 +526,9 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -665,8 +668,8 @@ github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0 github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= @@ -689,8 +692,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -758,8 +761,8 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.21 h1:UiGGnBFHVrZhoQVQ7EfwSOLuCtarqCSsRf8VrklqB7s= -github.com/tendermint/tendermint v0.34.21/go.mod h1:XDvfg6U7grcFTDx7VkzxnhazQ/bspGJAn4DZ6DcLLjQ= +github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjclr41o+2Q= +github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= @@ -1012,6 +1015,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1176,7 +1180,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1222,7 +1225,6 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From fe50854f8d1a72cb4f6d3ae3fa2dc4213e8e4f57 Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:06:53 +0700 Subject: [PATCH 008/294] Add simulation for gov (#1064) * add struct for sim gov * add proposal for store contract * change wasm file * add proposal instantiate contract * change admin account * add sim gov proposals Update Admin * add sim gov execute contract * fix some bug * add sim gov clear admin * add comment * fix lint --- app/params/weights.go | 7 ++ x/wasm/module.go | 4 +- x/wasm/simulation/proposals.go | 221 +++++++++++++++++++++++++++++++++ x/wasm/types/proposal.go | 52 ++++++++ 4 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 x/wasm/simulation/proposals.go diff --git a/app/params/weights.go b/app/params/weights.go index 9cb2dd39a4..e1b5e3a8d2 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -20,7 +20,14 @@ const ( DefaultWeightCommunitySpendProposal int = 5 DefaultWeightTextProposal int = 5 DefaultWeightParamChangeProposal int = 5 + DefaultWeightMsgStoreCode int = 50 DefaultWeightMsgInstantiateContract int = 100 DefaultWeightMsgExecuteContract int = 100 + + DefaultWeightStoreCodeProposal int = 5 + DefaultWeightInstantiateContractProposal int = 5 + DefaultWeightUpdateAdminProposal int = 5 + DefaultWeightExecuteContractProposal int = 5 + DefaultWeightClearAdminProposal int = 5 ) diff --git a/x/wasm/module.go b/x/wasm/module.go index a52dc1bf0b..8473d7f34e 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -201,8 +201,8 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { } // ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { - return nil +func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent { + return simulation.ProposalContents(am.bankKeeper, am.keeper) } // RandomizedParams creates randomized bank param changes for the simulator. diff --git a/x/wasm/simulation/proposals.go b/x/wasm/simulation/proposals.go new file mode 100644 index 0000000000..8e73f04f64 --- /dev/null +++ b/x/wasm/simulation/proposals.go @@ -0,0 +1,221 @@ +package simulation + +import ( + "math/rand" + + "github.com/CosmWasm/wasmd/app/params" + "github.com/CosmWasm/wasmd/x/wasm/keeper/testdata" + "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" +) + +const ( + WeightStoreCodeProposal = "weight_store_code_proposal" + WeightInstantiateContractProposal = "weight_instantiate_contract_proposal" + WeightUpdateAdminProposal = "weight_update_admin_proposal" + WeightExeContractProposal = "weight_execute_contract_proposal" + WeightClearAdminProposal = "weight_clear_admin_proposal" +) + +func ProposalContents(bk BankKeeper, wasmKeeper WasmKeeper) []simtypes.WeightedProposalContent { + return []simtypes.WeightedProposalContent{ + // simulation.NewWeightedProposalContent( + // WeightStoreCodeProposal, + // params.DefaultWeightStoreCodeProposal, + // SimulateStoreCodeProposal(wasmKeeper), + // ), + simulation.NewWeightedProposalContent( + WeightInstantiateContractProposal, + params.DefaultWeightInstantiateContractProposal, + SimulateInstantiateContractProposal( + bk, + wasmKeeper, + DefaultSimulationCodeIDSelector, + ), + ), + simulation.NewWeightedProposalContent( + WeightUpdateAdminProposal, + params.DefaultWeightUpdateAdminProposal, + SimulateUpdateAdminProposal( + wasmKeeper, + DefaultSimulateUpdateAdminProposalContractSelector, + ), + ), + simulation.NewWeightedProposalContent( + WeightExeContractProposal, + params.DefaultWeightExecuteContractProposal, + SimulateExecuteContractProposal( + bk, + wasmKeeper, + DefaultSimulationExecuteContractSelector, + DefaultSimulationExecuteSenderSelector, + DefaultSimulationExecutePayloader, + ), + ), + simulation.NewWeightedProposalContent( + WeightClearAdminProposal, + params.DefaultWeightClearAdminProposal, + SimulateClearAdminProposal( + wasmKeeper, + DefaultSimulateClearAdminProposalContractSelector, + ), + ), + } +} + +// simulate store code proposal (unused now) +// Current problem: out of gas (defaul gaswanted config of gov SimulateMsgSubmitProposal is 10_000_000) +// but this proposal may need more than it +func SimulateStoreCodeProposal(wasmKeeper WasmKeeper) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + simAccount, _ := simtypes.RandomAcc(r, accs) + + wasmBz := testdata.ReflectContractWasm() + + permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission.With(simAccount.Address) + + return types.NewStoreCodeProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + simAccount.Address.String(), + wasmBz, + &permission, + false, + ) + } +} + +// Simulate instantiate contract proposal +func SimulateInstantiateContractProposal(bk BankKeeper, wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + simAccount, _ := simtypes.RandomAcc(r, accs) + // admin + adminAccount, _ := simtypes.RandomAcc(r, accs) + // get codeID + codeID := codeSelector(ctx, wasmKeeper) + if codeID == 0 { + return nil + } + + return types.NewInstantiateContractProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + simAccount.Address.String(), + adminAccount.Address.String(), + codeID, + simtypes.RandStringOfLength(r, 10), + []byte(`{}`), + sdk.Coins{}, + ) + } +} + +// Simulate execute contract proposal +func SimulateExecuteContractProposal( + bk BankKeeper, + wasmKeeper WasmKeeper, + contractSelector MsgExecuteContractSelector, + senderSelector MsgExecuteSenderSelector, + payloader MsgExecutePayloader, +) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + ctAddress := contractSelector(ctx, wasmKeeper) + if ctAddress == nil { + return nil + } + + simAccount, err := senderSelector(wasmKeeper, ctx, ctAddress, accs) + if err != nil { + return nil + } + + msg := types.MsgExecuteContract{ + Sender: simAccount.Address.String(), + Contract: ctAddress.String(), + Funds: sdk.Coins{}, + } + + if err := payloader(&msg); err != nil { + return nil + } + + return types.NewExecuteContractProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + simAccount.Address.String(), + ctAddress.String(), + msg.Msg, + sdk.Coins{}, + ) + } +} + +type UpdateAdminContractSelector func(sdk.Context, WasmKeeper, string) (sdk.AccAddress, types.ContractInfo) + +func DefaultSimulateUpdateAdminProposalContractSelector( + ctx sdk.Context, + wasmKeeper WasmKeeper, + adminAddress string, +) (sdk.AccAddress, types.ContractInfo) { + var contractAddr sdk.AccAddress + var contractInfo types.ContractInfo + wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool { + if info.Admin != adminAddress { + return false + } + contractAddr = address + contractInfo = info + return true + }) + return contractAddr, contractInfo +} + +// Simulate update admin contract proposal +func SimulateUpdateAdminProposal(wasmKeeper WasmKeeper, contractSelector UpdateAdminContractSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + simAccount, _ := simtypes.RandomAcc(r, accs) + ctAddress, _ := contractSelector(ctx, wasmKeeper, simAccount.Address.String()) + if ctAddress == nil { + return nil + } + + return types.NewUpdateAdminProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + simtypes.RandomAccounts(r, 1)[0].Address.String(), + ctAddress.String(), + ) + } +} + +type ClearAdminContractSelector func(sdk.Context, WasmKeeper) sdk.AccAddress + +func DefaultSimulateClearAdminProposalContractSelector( + ctx sdk.Context, + wasmKeeper WasmKeeper, +) sdk.AccAddress { + var contractAddr sdk.AccAddress + wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool { + contractAddr = address + return true + }) + return contractAddr +} + +// Simulate clear admin proposal +func SimulateClearAdminProposal(wasmKeeper WasmKeeper, contractSelector ClearAdminContractSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + ctAddress := contractSelector(ctx, wasmKeeper) + if ctAddress == nil { + return nil + } + + return types.NewClearAdminProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + ctAddress.String(), + ) + } +} diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index acf30784c9..bb2ba16d6b 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -83,6 +83,17 @@ func init() { // register new content types with the sdk govtypes.RegisterProposalTypeCodec(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal") } +func NewStoreCodeProposal( + title string, + description string, + runAs string, + wasmBz []byte, + permission *AccessConfig, + unpinCode bool, +) *StoreCodeProposal { + return &StoreCodeProposal{title, description, runAs, wasmBz, permission, unpinCode} +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p StoreCodeProposal) ProposalRoute() string { return RouterKey } @@ -143,6 +154,19 @@ func (p StoreCodeProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewInstantiateContractProposal( + title string, + description string, + runAs string, + admin string, + codeID uint64, + label string, + msg RawContractMessage, + funds sdk.Coins, +) *InstantiateContractProposal { + return &InstantiateContractProposal{title, description, runAs, admin, codeID, label, msg, funds} +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p InstantiateContractProposal) ProposalRoute() string { return RouterKey } @@ -334,6 +358,17 @@ func (p SudoContractProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewExecuteContractProposal( + title string, + description string, + runAs string, + contract string, + msg RawContractMessage, + funds sdk.Coins, +) *ExecuteContractProposal { + return &ExecuteContractProposal{title, description, runAs, contract, msg, funds} +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p ExecuteContractProposal) ProposalRoute() string { return RouterKey } @@ -397,6 +432,15 @@ func (p ExecuteContractProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewUpdateAdminProposal( + title string, + description string, + newAdmin string, + contract string, +) *UpdateAdminProposal { + return &UpdateAdminProposal{title, description, newAdmin, contract} +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p UpdateAdminProposal) ProposalRoute() string { return RouterKey } @@ -433,6 +477,14 @@ func (p UpdateAdminProposal) String() string { `, p.Title, p.Description, p.Contract, p.NewAdmin) } +func NewClearAdminProposal( + title string, + description string, + contract string, +) *ClearAdminProposal { + return &ClearAdminProposal{title, description, contract} +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p ClearAdminProposal) ProposalRoute() string { return RouterKey } From bfb4bc08ef73be3ce4d067fb5c72924fffb2bb2d Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:54:15 +0700 Subject: [PATCH 009/294] Add weighted operations run simulation (#1055) * add WeightedOperations msg update admin * add check contract info condition * add fnc simulate migrate * add weights operations migrate contract * fix simulation msg update admin * add simulation.NewWeightedOperation * add sml msg clear admin * fix lint * remove msg migrate * change admin to use test account * add migrate * add new contract for simulation migrate * correct return log * Polish SimulateMsgMigrateContract Co-authored-by: Alex Peters --- app/params/weights.go | 3 + x/wasm/keeper/testdata/reflect.go | 7 + x/wasm/keeper/testdata/reflect_1_1.wasm | Bin 0 -> 257047 bytes x/wasm/simulation/operations.go | 216 +++++++++++++++++++++++- x/wasm/simulation/proposals.go | 7 +- 5 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 x/wasm/keeper/testdata/reflect_1_1.wasm diff --git a/app/params/weights.go b/app/params/weights.go index e1b5e3a8d2..d8eed7679f 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -24,6 +24,9 @@ const ( DefaultWeightMsgStoreCode int = 50 DefaultWeightMsgInstantiateContract int = 100 DefaultWeightMsgExecuteContract int = 100 + DefaultWeightMsgUpdateAdmin int = 25 + DefaultWeightMsgClearAdmin int = 10 + DefaultWeightMsgMigrateContract int = 50 DefaultWeightStoreCodeProposal int = 5 DefaultWeightInstantiateContractProposal int = 5 diff --git a/x/wasm/keeper/testdata/reflect.go b/x/wasm/keeper/testdata/reflect.go index 51f5f14d53..64fed6150a 100644 --- a/x/wasm/keeper/testdata/reflect.go +++ b/x/wasm/keeper/testdata/reflect.go @@ -10,10 +10,17 @@ import ( //go:embed reflect.wasm var reflectContract []byte +//go:embed reflect_1_1.wasm +var migrateReflectContract []byte + func ReflectContractWasm() []byte { return reflectContract } +func MigrateReflectContractWasm() []byte { + return migrateReflectContract +} + // ReflectHandleMsg is used to encode handle messages type ReflectHandleMsg struct { Reflect *ReflectPayload `json:"reflect_msg,omitempty"` diff --git a/x/wasm/keeper/testdata/reflect_1_1.wasm b/x/wasm/keeper/testdata/reflect_1_1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7383a6d635479f28858dbf67254543b7b1c9add7 GIT binary patch literal 257047 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%0D{~saPrGr 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 xq96YyueVIdB}Xd! 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 M2iGTY4YgGLe@e||KL7v# literal 0 HcmV?d00001 diff --git a/x/wasm/simulation/operations.go b/x/wasm/simulation/operations.go index 13c2f01670..34e7ef35d5 100644 --- a/x/wasm/simulation/operations.go +++ b/x/wasm/simulation/operations.go @@ -27,6 +27,9 @@ const ( OpWeightMsgStoreCode = "op_weight_msg_store_code" OpWeightMsgInstantiateContract = "op_weight_msg_instantiate_contract" OpWeightMsgExecuteContract = "op_weight_msg_execute_contract" + OpWeightMsgUpdateAdmin = "op_weight_msg_update_admin" + OpWeightMsgClearAdmin = "op_weight_msg_clear_admin" + OpWeightMsgMigrateContract = "op_weight_msg_migrate_contract" OpReflectContractPath = "op_reflect_contract_path" ) @@ -54,6 +57,9 @@ func WeightedOperations( weightMsgStoreCode int weightMsgInstantiateContract int weightMsgExecuteContract int + weightMsgUpdateAdmin int + weightMsgClearAdmin int + weightMsgMigrateContract int wasmContractPath string ) @@ -62,7 +68,6 @@ func WeightedOperations( weightMsgStoreCode = params.DefaultWeightMsgStoreCode }, ) - simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgInstantiateContract, &weightMsgInstantiateContract, nil, func(_ *rand.Rand) { weightMsgInstantiateContract = params.DefaultWeightMsgInstantiateContract @@ -73,6 +78,21 @@ func WeightedOperations( weightMsgExecuteContract = params.DefaultWeightMsgExecuteContract }, ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgUpdateAdmin, &weightMsgUpdateAdmin, nil, + func(_ *rand.Rand) { + weightMsgUpdateAdmin = params.DefaultWeightMsgUpdateAdmin + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgClearAdmin, &weightMsgClearAdmin, nil, + func(_ *rand.Rand) { + weightMsgClearAdmin = params.DefaultWeightMsgClearAdmin + }, + ) + simstate.AppParams.GetOrGenerate(simstate.Cdc, OpWeightMsgMigrateContract, &weightMsgMigrateContract, nil, + func(_ *rand.Rand) { + weightMsgMigrateContract = params.DefaultWeightMsgMigrateContract + }, + ) simstate.AppParams.GetOrGenerate(simstate.Cdc, OpReflectContractPath, &wasmContractPath, nil, func(_ *rand.Rand) { wasmContractPath = "" @@ -81,7 +101,7 @@ func WeightedOperations( var wasmBz []byte if wasmContractPath == "" { - wasmBz = testdata.ReflectContractWasm() + wasmBz = testdata.MigrateReflectContractWasm() } else { var err error wasmBz, err = os.ReadFile(wasmContractPath) @@ -110,6 +130,194 @@ func WeightedOperations( DefaultSimulationExecutePayloader, ), ), + simulation.NewWeightedOperation( + weightMsgUpdateAdmin, + SimulateMsgUpdateAmin( + ak, + bk, + wasmKeeper, + DefaultSimulationUpdateAdminContractSelector, + ), + ), + simulation.NewWeightedOperation( + weightMsgClearAdmin, + SimulateMsgClearAdmin( + ak, + bk, + wasmKeeper, + DefaultSimulationClearAdminContractSelector, + ), + ), + simulation.NewWeightedOperation( + weightMsgMigrateContract, + SimulateMsgMigrateContract( + ak, + bk, + wasmKeeper, + DefaultSimulationMigrateContractSelector, + DefaultSimulationMigrateCodeIDSelector, + ), + ), + } +} + +type ( + MsgMigrateContractSelector func(sdk.Context, WasmKeeper, string) (sdk.AccAddress, types.ContractInfo) + MsgMigrateCodeIDSelector func(sdk.Context, WasmKeeper, uint64) uint64 +) + +func DefaultSimulationMigrateContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) (sdk.AccAddress, types.ContractInfo) { + var contractAddress sdk.AccAddress + var contractInfo types.ContractInfo + wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool { + if info.Admin != adminAddress { + return false + } + contractAddress = address + contractInfo = info + return true + }) + return contractAddress, contractInfo +} + +func DefaultSimulationMigrateCodeIDSelector(ctx sdk.Context, wasmKeeper WasmKeeper, currentCodeID uint64) uint64 { + var codeID uint64 + wasmKeeper.IterateCodeInfos(ctx, func(u uint64, info types.CodeInfo) bool { + if (info.InstantiateConfig.Permission != types.AccessTypeEverybody) || (u == currentCodeID) { + return false + } + codeID = u + return true + }) + return codeID +} + +func SimulateMsgMigrateContract( + ak types.AccountKeeper, + bk BankKeeper, + wasmKeeper WasmKeeper, + contractSelector MsgMigrateContractSelector, + codeIDSelector MsgMigrateCodeIDSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + simAccount, _ := simtypes.RandomAcc(r, accs) + ctAddress, info := contractSelector(ctx, wasmKeeper, simAccount.Address.String()) + if ctAddress == nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgMigrateContract{}.Type(), "no contract instance available"), nil, nil + } + + codeID := codeIDSelector(ctx, wasmKeeper, info.CodeID) + if codeID == 0 { + return simtypes.NoOpMsg(types.ModuleName, types.MsgMigrateContract{}.Type(), "no target contract available"), nil, nil + } + migrateMsg := types.MsgMigrateContract{ + Sender: simAccount.Address.String(), + Contract: ctAddress.String(), + CodeID: codeID, + Msg: []byte(`{}`), + } + + txCtx := BuildOperationInput(r, app, ctx, &migrateMsg, simAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +type MsgClearAdminContractSelector func(sdk.Context, WasmKeeper, string) sdk.AccAddress + +func DefaultSimulationClearAdminContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) sdk.AccAddress { + var ctAddress sdk.AccAddress + wasmKeeper.IterateContractInfo(ctx, func(addr sdk.AccAddress, info types.ContractInfo) bool { + if info.Admin != adminAddress { + return false + } + ctAddress = addr + return true + }) + return ctAddress +} + +func SimulateMsgClearAdmin( + ak types.AccountKeeper, + bk BankKeeper, + wasmKeeper WasmKeeper, + contractSelector MsgClearAdminContractSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accounts []simtypes.Account, + chainID string, + ) (OperationMsg simtypes.OperationMsg, futureOps []simtypes.FutureOperation, err error) { + simAccount, _ := simtypes.RandomAcc(r, accounts) + ctAddress := contractSelector(ctx, wasmKeeper, simAccount.Address.String()) + if ctAddress == nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgClearAdmin{}.Type(), "no contract instance available"), nil, nil + } + + msg := types.MsgClearAdmin{ + Sender: simAccount.Address.String(), + Contract: ctAddress.String(), + } + txCtx := BuildOperationInput(r, app, ctx, &msg, simAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) + } +} + +type MsgUpdateAdminContractSelector func(sdk.Context, WasmKeeper, string) (sdk.AccAddress, types.ContractInfo) + +// DefaultSimulationUpdateAdminContractSelector picks the first contract which Admin != "" +func DefaultSimulationUpdateAdminContractSelector(ctx sdk.Context, wasmKeeper WasmKeeper, adminAddress string) (sdk.AccAddress, types.ContractInfo) { + var contractAddress sdk.AccAddress + var contractInfo types.ContractInfo + wasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info types.ContractInfo) bool { + if info.Admin != adminAddress { + return false + } + contractAddress = address + contractInfo = info + return true + }) + return contractAddress, contractInfo +} + +func SimulateMsgUpdateAmin( + ak types.AccountKeeper, + bk BankKeeper, + wasmKeeper WasmKeeper, + contractSelector MsgUpdateAdminContractSelector, +) simtypes.Operation { + return func( + r *rand.Rand, + app *baseapp.BaseApp, + ctx sdk.Context, + accs []simtypes.Account, + chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + simAccount, _ := simtypes.RandomAcc(r, accs) + ctAddress, _ := contractSelector(ctx, wasmKeeper, simAccount.Address.String()) + if ctAddress == nil { + return simtypes.NoOpMsg(types.ModuleName, types.MsgUpdateAdmin{}.Type(), "no contract instance available"), nil, nil + } + + newAdmin, _ := simtypes.RandomAcc(r, accs) + if newAdmin.Address.String() == simAccount.Address.String() { + return simtypes.NoOpMsg(types.ModuleName, types.MsgUpdateAdmin{}.Type(), "new admin cannot be the same as current admin"), nil, nil + } + + msg := types.MsgUpdateAdmin{ + Sender: simAccount.Address.String(), + NewAdmin: newAdmin.Address.String(), + Contract: ctAddress.String(), + } + txCtx := BuildOperationInput(r, app, ctx, &msg, simAccount, ak, bk, nil) + return simulation.GenAndDeliverTxWithRandFees(txCtx) } } @@ -180,9 +388,11 @@ func SimulateMsgInstantiateContract(ak types.AccountKeeper, bk BankKeeper, wasmK } } + adminAccount, _ := simtypes.RandomAcc(r, accs) + msg := types.MsgInstantiateContract{ Sender: simAccount.Address.String(), - Admin: simtypes.RandomAccounts(r, 1)[0].Address.String(), + Admin: adminAccount.Address.String(), CodeID: codeID, Label: simtypes.RandStringOfLength(r, 10), Msg: []byte(`{}`), diff --git a/x/wasm/simulation/proposals.go b/x/wasm/simulation/proposals.go index 8e73f04f64..1ee9584811 100644 --- a/x/wasm/simulation/proposals.go +++ b/x/wasm/simulation/proposals.go @@ -3,12 +3,13 @@ package simulation import ( "math/rand" - "github.com/CosmWasm/wasmd/app/params" - "github.com/CosmWasm/wasmd/x/wasm/keeper/testdata" - "github.com/CosmWasm/wasmd/x/wasm/types" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/CosmWasm/wasmd/app/params" + "github.com/CosmWasm/wasmd/x/wasm/keeper/testdata" + "github.com/CosmWasm/wasmd/x/wasm/types" ) const ( From 0223e2bddbd50600e128b3323f55983206d8b048 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Wed, 2 Nov 2022 17:14:41 +0100 Subject: [PATCH 010/294] Add SilenceUsage flag to hide menu when an error occurs. (#1068) * Add SilenceUsage flag to hide menu when an error occurs. * Fix lint errors --- x/wasm/client/cli/genesis_msg.go | 5 +++++ x/wasm/client/cli/gov_tx.go | 10 ++++++++++ x/wasm/client/cli/new_tx.go | 3 +++ x/wasm/client/cli/query.go | 18 ++++++++++++++++-- x/wasm/client/cli/tx.go | 5 +++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/x/wasm/client/cli/genesis_msg.go b/x/wasm/client/cli/genesis_msg.go index 8aedae358a..b6b1321aee 100644 --- a/x/wasm/client/cli/genesis_msg.go +++ b/x/wasm/client/cli/genesis_msg.go @@ -68,6 +68,7 @@ func GenesisStoreCodeCmd(defaultNodeHome string, genesisMutator GenesisMutator) return nil }) }, + SilenceUsage: true, } cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator") cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional") @@ -136,6 +137,7 @@ func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator Genesi return nil }) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") @@ -189,6 +191,7 @@ func GenesisExecuteContractCmd(defaultNodeHome string, genesisMutator GenesisMut return nil }) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract along with command") cmd.Flags().String(flagRunAs, "", "The address that pays the funds.") @@ -217,6 +220,7 @@ func GenesisListCodesCmd(defaultNodeHome string, genReader GenesisReader) *cobra } return printJSONOutput(cmd, all) }, + SilenceUsage: true, } cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") flags.AddQueryFlagsToCmd(cmd) @@ -239,6 +243,7 @@ func GenesisListContractsCmd(defaultNodeHome string, genReader GenesisReader) *c all := GetAllContracts(state) return printJSONOutput(cmd, all) }, + SilenceUsage: true, } cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") flags.AddQueryFlagsToCmd(cmd) diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 8daeb82183..fbab1645c9 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -80,6 +80,7 @@ func ProposalStoreCodeCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator") @@ -156,6 +157,7 @@ func ProposalInstantiateContractCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") @@ -221,6 +223,7 @@ func ProposalMigrateContractCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags @@ -295,6 +298,7 @@ func ProposalExecuteContractCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } cmd.Flags().String(flagRunAs, "", "The address that is passed as sender to the contract on proposal execution") cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") @@ -354,6 +358,7 @@ func ProposalSudoContractCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flagsExecute @@ -413,6 +418,7 @@ func ProposalUpdateContractAdminCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") @@ -465,6 +471,7 @@ func ProposalClearContractAdminCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") @@ -521,6 +528,7 @@ func ProposalPinCodesCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") @@ -589,6 +597,7 @@ func ProposalUnpinCodesCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") @@ -704,6 +713,7 @@ $ %s tx gov submit-proposal update-instantiate-config 1:nobody 2:everybody 3:%s1 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") diff --git a/x/wasm/client/cli/new_tx.go b/x/wasm/client/cli/new_tx.go index e3b47792e6..2be19350ac 100644 --- a/x/wasm/client/cli/new_tx.go +++ b/x/wasm/client/cli/new_tx.go @@ -34,6 +34,7 @@ func MigrateContractCmd() *cobra.Command { } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, + SilenceUsage: true, } flags.AddTxFlagsToCmd(cmd) return cmd @@ -79,6 +80,7 @@ func UpdateContractAdminCmd() *cobra.Command { } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, + SilenceUsage: true, } flags.AddTxFlagsToCmd(cmd) return cmd @@ -115,6 +117,7 @@ func ClearContractAdminCmd() *cobra.Command { } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, + SilenceUsage: true, } flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/x/wasm/client/cli/query.go b/x/wasm/client/cli/query.go index 8d13a1192a..a621ba0825 100644 --- a/x/wasm/client/cli/query.go +++ b/x/wasm/client/cli/query.go @@ -28,6 +28,7 @@ func GetQueryCmd() *cobra.Command { DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, + SilenceUsage: true, } queryCmd.AddCommand( GetCmdListCode(), @@ -137,6 +138,7 @@ func GetCmdListCode() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "list codes") @@ -182,6 +184,7 @@ func GetCmdListContractByCode() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "list contracts by code") @@ -224,6 +227,7 @@ func GetCmdQueryCode() *cobra.Command { fmt.Printf("Downloading wasm code to %s\n", args[1]) return os.WriteFile(args[1], res.Data, 0o600) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) return cmd @@ -263,6 +267,7 @@ func GetCmdQueryCodeInfo() *cobra.Command { return clientCtx.PrintProto(res.CodeInfoResponse) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) return cmd @@ -298,6 +303,7 @@ func GetCmdGetContractInfo() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) return cmd @@ -312,6 +318,7 @@ func GetCmdGetContractState() *cobra.Command { DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, + SilenceUsage: true, } cmd.AddCommand( GetCmdGetContractStateAll(), @@ -355,6 +362,7 @@ func GetCmdGetContractStateAll() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "contract state") @@ -396,6 +404,7 @@ func GetCmdGetContractStateRaw() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } decoder.RegisterFlags(cmd.PersistentFlags(), "key argument") flags.AddQueryFlagsToCmd(cmd) @@ -444,6 +453,7 @@ func GetCmdGetContractStateSmart() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } decoder.RegisterFlags(cmd.PersistentFlags(), "query argument") flags.AddQueryFlagsToCmd(cmd) @@ -487,6 +497,7 @@ func GetCmdGetContractHistory() *cobra.Command { return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) @@ -499,7 +510,7 @@ func GetCmdListPinnedCode() *cobra.Command { cmd := &cobra.Command{ Use: "pinned", Short: "List all pinned code ids", - Long: "\t\tLong: List all pinned code ids,\n", + Long: "List all pinned code ids", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -523,6 +534,7 @@ func GetCmdListPinnedCode() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "list codes") @@ -534,7 +546,7 @@ func GetCmdListContractsByCreator() *cobra.Command { cmd := &cobra.Command{ Use: "list-contracts-by-creator [creator]", Short: "List all contracts by creator", - Long: "\t\tLong: List all contracts by creator,\n", + Long: "List all contracts by creator", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -563,6 +575,7 @@ func GetCmdListContractsByCreator() *cobra.Command { } return clientCtx.PrintProto(res) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) return cmd @@ -650,6 +663,7 @@ func GetCmdQueryParams() *cobra.Command { return clientCtx.PrintProto(&res.Params) }, + SilenceUsage: true, } flags.AddQueryFlagsToCmd(cmd) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 9a2eebfda8..7e4c6e36f0 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -42,6 +42,7 @@ func GetTxCmd() *cobra.Command { DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, + SilenceUsage: true, } txCmd.AddCommand( StoreCodeCmd(), @@ -76,6 +77,7 @@ func StoreCodeCmd() *cobra.Command { } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, + SilenceUsage: true, } cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional") @@ -202,6 +204,7 @@ $ %s tx wasm instantiate 1 '{"foo":"bar"}' --admin="$(%s keys show mykey -a)" \ } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") @@ -262,6 +265,7 @@ $ %s tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --adm } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") @@ -347,6 +351,7 @@ func ExecuteContractCmd() *cobra.Command { } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, + SilenceUsage: true, } cmd.Flags().String(flagAmount, "", "Coins to send to the contract along with command") From a9ce273e3c1c4f7224e1293fcf1bfd5a50e4fe17 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Wed, 2 Nov 2022 17:16:32 +0100 Subject: [PATCH 011/294] Introduce AcceptListStargateQuerier (#1069) * Stargate query enable * Remove initialized whitelists * Roman's review * Minor improvement * Add tests * Add testings and codec * Fix lint * Fix test * Fix from code review * Refactor Stargate querier init * Fix typo Co-authored-by: mattverse --- x/wasm/keeper/keeper.go | 4 +- x/wasm/keeper/options.go | 2 +- x/wasm/keeper/query_plugins.go | 68 +++++++- x/wasm/keeper/query_plugins_test.go | 232 ++++++++++++++++++++++++++-- x/wasm/keeper/reflect_test.go | 8 +- 5 files changed, 288 insertions(+), 26 deletions(-) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 93dad3f5b4..3112a26eb5 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -119,7 +119,7 @@ func NewKeeper( capabilityKeeper types.CapabilityKeeper, portSource types.ICS20TransferPortSource, router MessageRouter, - queryRouter GRPCQueryRouter, + _ GRPCQueryRouter, homeDir string, wasmConfig types.WasmConfig, availableCapabilities string, @@ -150,7 +150,7 @@ func NewKeeper( maxQueryStackSize: types.DefaultMaxQueryStackSize, acceptedAccountTypes: defaultAcceptedAccountTypes, } - keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, queryRouter, keeper) + keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, keeper) for _, o := range opts { o.apply(keeper) } diff --git a/x/wasm/keeper/options.go b/x/wasm/keeper/options.go index cc5547f22c..223a771f63 100644 --- a/x/wasm/keeper/options.go +++ b/x/wasm/keeper/options.go @@ -57,7 +57,7 @@ func WithQueryHandlerDecorator(d func(old WasmVMQueryHandler) WasmVMQueryHandler } // WithQueryPlugins is an optional constructor parameter to pass custom query plugins for wasmVM requests. -// This option expects the default `QueryHandler` set an should not be combined with Option `WithQueryHandler` or `WithQueryHandlerDecorator`. +// This option expects the default `QueryHandler` set and should not be combined with Option `WithQueryHandler` or `WithQueryHandlerDecorator`. func WithQueryPlugins(x *QueryPlugins) Option { return optsFn(func(k *Keeper) { q, ok := k.wasmVMQueryHandler.(QueryPlugins) diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index 371242d00a..7196860d90 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -3,8 +3,11 @@ package keeper import ( "encoding/json" "errors" + "fmt" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + abci "github.com/tendermint/tendermint/abci/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" @@ -99,7 +102,6 @@ func DefaultQueryPlugins( staking types.StakingKeeper, distKeeper types.DistributionKeeper, channelKeeper types.ChannelKeeper, - queryRouter GRPCQueryRouter, wasm wasmQueryKeeper, ) QueryPlugins { return QueryPlugins{ @@ -107,7 +109,7 @@ func DefaultQueryPlugins( Custom: NoCustomQuerier, IBC: IBCQuerier(wasm, channelKeeper), Staking: StakingQuerier(staking, distKeeper), - Stargate: StargateQuerier(queryRouter), + Stargate: RejectStargateQuerier(), Wasm: WasmQuerier(wasm), } } @@ -278,9 +280,47 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper) } } -func StargateQuerier(queryRouter GRPCQueryRouter) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { - return func(ctx sdk.Context, msg *wasmvmtypes.StargateQuery) ([]byte, error) { - return nil, wasmvmtypes.UnsupportedRequest{Kind: "Stargate queries are disabled."} +// RejectStargateQuerier rejects all stargate queries +func RejectStargateQuerier() func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { + return func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { + return nil, wasmvmtypes.UnsupportedRequest{Kind: "Stargate queries are disabled"} + } +} + +// AcceptedStargateQueries define accepted Stargate queries as a map with path as key and response type as value. +// For example: +// acceptList["/cosmos.auth.v1beta1.Query/Account"]= &authtypes.QueryAccountResponse{} +type AcceptedStargateQueries map[string]codec.ProtoMarshaler + +// AcceptListStargateQuerier supports a preconfigured set of stargate queries only. +// All arguments must be non nil. +// +// Warning: Chains need to test and maintain their accept list carefully. +// There were critical consensus breaking issues in the past with non-deterministic behaviour in the SDK. +// +// This queries can be set via WithQueryPlugins option in the wasm keeper constructor: +// WithQueryPlugins(&QueryPlugins{Stargate: AcceptListStargateQuerier(acceptList, queryRouter, codec)}) +func AcceptListStargateQuerier(acceptList AcceptedStargateQueries, queryRouter GRPCQueryRouter, codec codec.Codec) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { + return func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) { + protoResponse, accepted := acceptList[request.Path] + if !accepted { + return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("'%s' path is not allowed from the contract", request.Path)} + } + + route := queryRouter.Route(request.Path) + if route == nil { + return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query '%s'", request.Path)} + } + + res, err := route(ctx, abci.RequestQuery{ + Data: request.Data, + Path: request.Path, + }) + if err != nil { + return nil, err + } + + return ConvertProtoToJSONMarshal(codec, protoResponse, res.Value) } } @@ -527,6 +567,24 @@ func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin { } } +// ConvertProtoToJSONMarshal unmarshals the given bytes into a proto message and then marshals it to json. +// This is done so that clients calling stargate queries do not need to define their own proto unmarshalers, +// being able to use response directly by json marshalling, which is supported in cosmwasm. +func ConvertProtoToJSONMarshal(cdc codec.Codec, protoResponse codec.ProtoMarshaler, bz []byte) ([]byte, error) { + // unmarshal binary into stargate response data structure + err := cdc.Unmarshal(bz, protoResponse) + if err != nil { + return nil, sdkerrors.Wrap(err, "to proto") + } + + bz, err = cdc.MarshalJSON(protoResponse) + if err != nil { + return nil, sdkerrors.Wrap(err, "to json") + } + + return bz, nil +} + var _ WasmVMQueryHandler = WasmVMQueryHandlerFn(nil) // WasmVMQueryHandlerFn is a helper to construct a function based query handler. diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index f9282ac152..1c0fa231c9 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -1,19 +1,32 @@ -package keeper +package keeper_test import ( + "encoding/hex" "encoding/json" + "fmt" "testing" - - "github.com/cosmos/cosmos-sdk/store" - dbm "github.com/tendermint/tm-db" + "time" wasmvmtypes "github.com/CosmWasm/wasmvm/types" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + "github.com/CosmWasm/wasmd/app" + "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting" "github.com/CosmWasm/wasmd/x/wasm/types" ) @@ -307,8 +320,8 @@ func TestIBCQuerier(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - h := IBCQuerier(spec.wasmKeeper, spec.channelKeeper) - gotResult, gotErr := h(sdk.Context{}, RandomAccountAddress(t), spec.srcQuery) + h := keeper.IBCQuerier(spec.wasmKeeper, spec.channelKeeper) + gotResult, gotErr := h(sdk.Context{}, keeper.RandomAccountAddress(t), spec.srcQuery) require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr) if spec.expErr != nil { return @@ -324,10 +337,10 @@ func TestBankQuerierBalance(t *testing.T) { }} ctx := sdk.Context{} - q := BankQuerier(mock) + q := keeper.BankQuerier(mock) gotBz, gotErr := q(ctx, &wasmvmtypes.BankQuery{ Balance: &wasmvmtypes.BalanceQuery{ - Address: RandomBech32AccountAddress(t), + Address: keeper.RandomBech32AccountAddress(t), Denom: "ALX", }, }) @@ -344,9 +357,9 @@ func TestBankQuerierBalance(t *testing.T) { } func TestContractInfoWasmQuerier(t *testing.T) { - myValidContractAddr := RandomBech32AccountAddress(t) - myCreatorAddr := RandomBech32AccountAddress(t) - myAdminAddr := RandomBech32AccountAddress(t) + myValidContractAddr := keeper.RandomBech32AccountAddress(t) + myCreatorAddr := keeper.RandomBech32AccountAddress(t) + myAdminAddr := keeper.RandomBech32AccountAddress(t) var ctx sdk.Context specs := map[string]struct { @@ -433,7 +446,7 @@ func TestContractInfoWasmQuerier(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - q := WasmQuerier(spec.mock) + q := keeper.WasmQuerier(spec.mock) gotBz, gotErr := q(ctx, spec.req) if spec.expErr { require.Error(t, gotErr) @@ -464,17 +477,82 @@ func TestQueryErrors(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - mock := WasmVMQueryHandlerFn(func(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) { + mock := keeper.WasmVMQueryHandlerFn(func(ctx sdk.Context, caller sdk.AccAddress, request wasmvmtypes.QueryRequest) ([]byte, error) { return nil, spec.src }) ctx := sdk.Context{}.WithGasMeter(sdk.NewInfiniteGasMeter()).WithMultiStore(store.NewCommitMultiStore(dbm.NewMemDB())) - q := NewQueryHandler(ctx, mock, sdk.AccAddress{}, NewDefaultWasmGasRegister()) + q := keeper.NewQueryHandler(ctx, mock, sdk.AccAddress{}, keeper.NewDefaultWasmGasRegister()) _, gotErr := q.Query(wasmvmtypes.QueryRequest{}, 1) assert.Equal(t, spec.expErr, gotErr) }) } } +func TestAcceptListStargateQuerier(t *testing.T) { + wasmApp := app.SetupWithEmptyStore(t) + ctx := wasmApp.NewUncachedContext(false, tmproto.Header{ChainID: "foo", Height: 1, Time: time.Now()}) + wasmApp.StakingKeeper.SetParams(ctx, stakingtypes.DefaultParams()) + + addrs := app.AddTestAddrs(wasmApp, ctx, 2, sdk.NewInt(1_000_000)) + accepted := keeper.AcceptedStargateQueries{ + "/cosmos.auth.v1beta1.Query/Account": &authtypes.QueryAccountResponse{}, + "/no/route/to/this": &authtypes.QueryAccountResponse{}, + } + + marshal := func(pb proto.Message) []byte { + b, err := proto.Marshal(pb) + require.NoError(t, err) + return b + } + + specs := map[string]struct { + req *wasmvmtypes.StargateQuery + expErr bool + expResp string + }{ + "in accept list - success result": { + req: &wasmvmtypes.StargateQuery{ + Path: "/cosmos.auth.v1beta1.Query/Account", + Data: marshal(&authtypes.QueryAccountRequest{Address: addrs[0].String()}), + }, + expResp: fmt.Sprintf(`{"account":{"@type":"/cosmos.auth.v1beta1.BaseAccount","address":%q,"pub_key":null,"account_number":"1","sequence":"0"}}`, addrs[0].String()), + }, + "in accept list - error result": { + req: &wasmvmtypes.StargateQuery{ + Path: "/cosmos.auth.v1beta1.Query/Account", + Data: marshal(&authtypes.QueryAccountRequest{Address: sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()).String()}), + }, + expErr: true, + }, + "not in accept list": { + req: &wasmvmtypes.StargateQuery{ + Path: "/cosmos.bank.v1beta1.Query/AllBalances", + Data: marshal(&banktypes.QueryAllBalancesRequest{Address: addrs[0].String()}), + }, + expErr: true, + }, + "unknown route": { + req: &wasmvmtypes.StargateQuery{ + Path: "/no/route/to/this", + Data: marshal(&banktypes.QueryAllBalancesRequest{Address: addrs[0].String()}), + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + q := keeper.AcceptListStargateQuerier(accepted, wasmApp.GRPCQueryRouter(), wasmApp.AppCodec()) + gotBz, gotErr := q(ctx, spec.req) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.JSONEq(t, spec.expResp, string(gotBz), string(gotBz)) + }) + } +} + type mockWasmQueryKeeper struct { GetContractInfoFn func(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo QueryRawFn func(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte @@ -536,3 +614,129 @@ func (m bankKeeperMock) GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk } return m.GetAllBalancesFn(ctx, addr) } + +func TestConvertProtoToJSONMarshal(t *testing.T) { + testCases := []struct { + name string + queryPath string + protoResponseStruct codec.ProtoMarshaler + originalResponse string + expectedProtoResponse codec.ProtoMarshaler + expectedError bool + }{ + { + name: "successful conversion from proto response to json marshalled response", + queryPath: "/cosmos.bank.v1beta1.Query/AllBalances", + originalResponse: "0a090a036261721202333012050a03666f6f", + protoResponseStruct: &banktypes.QueryAllBalancesResponse{}, + expectedProtoResponse: &banktypes.QueryAllBalancesResponse{ + Balances: sdk.NewCoins(sdk.NewCoin("bar", sdk.NewInt(30))), + Pagination: &query.PageResponse{ + NextKey: []byte("foo"), + }, + }, + }, + { + name: "invalid proto response struct", + queryPath: "/cosmos.bank.v1beta1.Query/AllBalances", + originalResponse: "0a090a036261721202333012050a03666f6f", + protoResponseStruct: &authtypes.QueryAccountResponse{}, + expectedError: true, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) { + originalVersionBz, err := hex.DecodeString(tc.originalResponse) + require.NoError(t, err) + appCodec := app.MakeEncodingConfig().Marshaler + + jsonMarshalledResponse, err := keeper.ConvertProtoToJSONMarshal(appCodec, tc.protoResponseStruct, originalVersionBz) + if tc.expectedError { + require.Error(t, err) + return + } + require.NoError(t, err) + + // check response by json marshalling proto response into json response manually + jsonMarshalExpectedResponse, err := appCodec.MarshalJSON(tc.expectedProtoResponse) + require.NoError(t, err) + require.JSONEq(t, string(jsonMarshalledResponse), string(jsonMarshalExpectedResponse)) + }) + } +} + +// TestDeterministicJsonMarshal tests that we get deterministic JSON marshalled response upon +// proto struct update in the state machine. +func TestDeterministicJsonMarshal(t *testing.T) { + testCases := []struct { + name string + originalResponse string + updatedResponse string + queryPath string + responseProtoStruct codec.ProtoMarshaler + expectedProto func() codec.ProtoMarshaler + }{ + /** + * + * Origin Response + * 0a530a202f636f736d6f732e617574682e763162657461312e426173654163636f756e74122f0a2d636f736d6f7331346c3268686a6e676c3939367772703935673867646a6871653038326375367a7732706c686b + * + * Updated Response + * 0a530a202f636f736d6f732e617574682e763162657461312e426173654163636f756e74122f0a2d636f736d6f7331646a783375676866736d6b6135386676673076616a6e6533766c72776b7a6a346e6377747271122d636f736d6f7331646a783375676866736d6b6135386676673076616a6e6533766c72776b7a6a346e6377747271 + // Origin proto + message QueryAccountResponse { + // account defines the account of the corresponding address. + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; + } + // Updated proto + message QueryAccountResponse { + // account defines the account of the corresponding address. + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; + // address is the address to query for. + string address = 2; + } + */ + { + "Query Account", + "0a530a202f636f736d6f732e617574682e763162657461312e426173654163636f756e74122f0a2d636f736d6f733166387578756c746e3873717a687a6e72737a3371373778776171756867727367366a79766679", + "0a530a202f636f736d6f732e617574682e763162657461312e426173654163636f756e74122f0a2d636f736d6f733166387578756c746e3873717a687a6e72737a3371373778776171756867727367366a79766679122d636f736d6f733166387578756c746e3873717a687a6e72737a3371373778776171756867727367366a79766679", + "/cosmos.auth.v1beta1.Query/Account", + &authtypes.QueryAccountResponse{}, + func() codec.ProtoMarshaler { + account := authtypes.BaseAccount{ + Address: "cosmos1f8uxultn8sqzhznrsz3q77xwaquhgrsg6jyvfy", + } + accountResponse, err := codectypes.NewAnyWithValue(&account) + require.NoError(t, err) + return &authtypes.QueryAccountResponse{ + Account: accountResponse, + } + }, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) { + appCodec := app.MakeEncodingConfig().Marshaler + + originVersionBz, err := hex.DecodeString(tc.originalResponse) + require.NoError(t, err) + jsonMarshalledOriginalBz, err := keeper.ConvertProtoToJSONMarshal(appCodec, tc.responseProtoStruct, originVersionBz) + require.NoError(t, err) + + newVersionBz, err := hex.DecodeString(tc.updatedResponse) + require.NoError(t, err) + jsonMarshalledUpdatedBz, err := keeper.ConvertProtoToJSONMarshal(appCodec, tc.responseProtoStruct, newVersionBz) + require.NoError(t, err) + + // json marshalled bytes should be the same since we use the same proto struct for unmarshalling + require.Equal(t, jsonMarshalledOriginalBz, jsonMarshalledUpdatedBz) + + // raw build also make same result + jsonMarshalExpectedResponse, err := appCodec.MarshalJSON(tc.expectedProto()) + require.NoError(t, err) + require.Equal(t, jsonMarshalledUpdatedBz, jsonMarshalExpectedResponse) + }) + } +} diff --git a/x/wasm/keeper/reflect_test.go b/x/wasm/keeper/reflect_test.go index f478a32935..1336be7fee 100644 --- a/x/wasm/keeper/reflect_test.go +++ b/x/wasm/keeper/reflect_test.go @@ -384,10 +384,10 @@ func TestReflectInvalidStargateQuery(t *testing.T) { }) require.NoError(t, err) - // make a query on the chain, should be blacklisted + // make a query on the chain, should not be whitelisted _, err = keeper.QuerySmart(ctx, contractAddr, protoQueryBz) require.Error(t, err) - require.Contains(t, err.Error(), "Stargate queries are disabled") + require.Contains(t, err.Error(), "Unsupported query") // now, try to build a protobuf query protoRequest = wasmvmtypes.QueryRequest{ @@ -404,7 +404,7 @@ func TestReflectInvalidStargateQuery(t *testing.T) { // make a query on the chain, should be blacklisted _, err = keeper.QuerySmart(ctx, contractAddr, protoQueryBz) require.Error(t, err) - require.Contains(t, err.Error(), "Stargate queries are disabled") + require.Contains(t, err.Error(), "Unsupported query") // and another one protoRequest = wasmvmtypes.QueryRequest{ @@ -421,7 +421,7 @@ func TestReflectInvalidStargateQuery(t *testing.T) { // make a query on the chain, should be blacklisted _, err = keeper.QuerySmart(ctx, contractAddr, protoQueryBz) require.Error(t, err) - require.Contains(t, err.Error(), "Stargate queries are disabled") + require.Contains(t, err.Error(), "Unsupported query") } type reflectState struct { From b7e4770e316af00f2de8c29a5c22489e13bdf2e0 Mon Sep 17 00:00:00 2001 From: ravaliGangasani Date: Tue, 8 Nov 2022 16:37:54 +0530 Subject: [PATCH 012/294] Update gov_tx.go adding instantiate-anyof-addresses flag in the gov_tx.go --- x/wasm/client/cli/gov_tx.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index fbab1645c9..01f7aaf80e 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -88,6 +88,7 @@ func ProposalStoreCodeCmd() *cobra.Command { cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional") cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional") cmd.Flags().Bool(flagUnpinCode, false, "Unpin code on upload, optional") + cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") From 4fe2fbc8f322efdaf187e2e5c99ce32fd1df06f0 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Wed, 9 Nov 2022 08:58:05 +0100 Subject: [PATCH 013/294] Deprecate REST endpoints (#1070) * Deprecate REST support * Add deprecation and nolint annotations --- app/app.go | 2 +- x/wasm/alias.go | 1 - x/wasm/client/proposal_handler.go | 3 ++- x/wasm/client/rest/rest.go | 2 ++ x/wasm/keeper/legacy_querier.go | 1 + x/wasm/keeper/recurse_test.go | 29 ++++++++++++----------------- x/wasm/module.go | 2 +- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/app.go b/app/app.go index 5d62f67e1e..c81550fd22 100644 --- a/app/app.go +++ b/app/app.go @@ -185,7 +185,7 @@ var ( distr.AppModuleBasic{}, gov.NewAppModuleBasic( append( - wasmclient.ProposalHandlers, + wasmclient.ProposalHandlers, //nolint:staticcheck paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, diff --git a/x/wasm/alias.go b/x/wasm/alias.go index a64de37bdd..e47a657c97 100644 --- a/x/wasm/alias.go +++ b/x/wasm/alias.go @@ -59,7 +59,6 @@ var ( EncodeStakingMsg = keeper.EncodeStakingMsg EncodeWasmMsg = keeper.EncodeWasmMsg NewKeeper = keeper.NewKeeper - NewLegacyQuerier = keeper.NewLegacyQuerier DefaultQueryPlugins = keeper.DefaultQueryPlugins BankQuerier = keeper.BankQuerier NoCustomQuerier = keeper.NoCustomQuerier diff --git a/x/wasm/client/proposal_handler.go b/x/wasm/client/proposal_handler.go index 6d4735180e..9d90d48df8 100644 --- a/x/wasm/client/proposal_handler.go +++ b/x/wasm/client/proposal_handler.go @@ -4,10 +4,11 @@ import ( govclient "github.com/cosmos/cosmos-sdk/x/gov/client" "github.com/CosmWasm/wasmd/x/wasm/client/cli" - "github.com/CosmWasm/wasmd/x/wasm/client/rest" + "github.com/CosmWasm/wasmd/x/wasm/client/rest" //nolint:staticcheck ) // ProposalHandlers define the wasm cli proposal types and rest handler. +// Deprecated: the rest package will be removed. You can use the GRPC gateway instead var ProposalHandlers = []govclient.ProposalHandler{ govclient.NewProposalHandler(cli.ProposalStoreCodeCmd, rest.StoreCodeProposalHandler), govclient.NewProposalHandler(cli.ProposalInstantiateContractCmd, rest.InstantiateProposalHandler), diff --git a/x/wasm/client/rest/rest.go b/x/wasm/client/rest/rest.go index 2e697a6b50..95339d3aa0 100644 --- a/x/wasm/client/rest/rest.go +++ b/x/wasm/client/rest/rest.go @@ -1,3 +1,4 @@ +// Deprecated: the rest package will be removed. You can use the GRPC gateway instead package rest import ( @@ -6,6 +7,7 @@ import ( ) // RegisterRoutes registers staking-related REST handlers to a router +// Deprecated: the rest package will be removed. You can use the GRPC gateway instead func RegisterRoutes(cliCtx client.Context, r *mux.Router) { registerQueryRoutes(cliCtx, r) registerTxRoutes(cliCtx, r) diff --git a/x/wasm/keeper/legacy_querier.go b/x/wasm/keeper/legacy_querier.go index a4dd3055aa..8ff72e1f81 100644 --- a/x/wasm/keeper/legacy_querier.go +++ b/x/wasm/keeper/legacy_querier.go @@ -28,6 +28,7 @@ const ( ) // NewLegacyQuerier creates a new querier +// Deprecated: the rest support will be removed. You can use the GRPC gateway instead func NewLegacyQuerier(keeper types.ViewKeeper, gasLimit sdk.Gas) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { var ( diff --git a/x/wasm/keeper/recurse_test.go b/x/wasm/keeper/recurse_test.go index 5a16da7878..0c0831aa49 100644 --- a/x/wasm/keeper/recurse_test.go +++ b/x/wasm/keeper/recurse_test.go @@ -4,6 +4,8 @@ import ( "encoding/json" "testing" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/CosmWasm/wasmd/x/wasm/types" wasmvmtypes "github.com/CosmWasm/wasmvm/types" @@ -11,7 +13,6 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" ) type Recurse struct { @@ -146,7 +147,7 @@ func TestGasOnExternalQuery(t *testing.T) { cases := map[string]struct { gasLimit uint64 msg Recurse - expectPanic bool + expOutOfGas bool }{ "no recursion, plenty gas": { gasLimit: 400_000, @@ -167,7 +168,7 @@ func TestGasOnExternalQuery(t *testing.T) { msg: Recurse{ Work: 50, }, - expectPanic: true, + expOutOfGas: true, }, "recursion 4, external gas limit": { // this uses 244708 gas but give less @@ -176,7 +177,7 @@ func TestGasOnExternalQuery(t *testing.T) { Depth: 4, Work: 50, }, - expectPanic: true, + expOutOfGas: true, }, } @@ -188,20 +189,14 @@ func TestGasOnExternalQuery(t *testing.T) { recurse.Contract = contractAddr msg := buildRecurseQuery(t, recurse) - // do the query - path := []string{QueryGetContractState, contractAddr.String(), QueryMethodContractStateSmart} - req := abci.RequestQuery{Data: msg} - if tc.expectPanic { - require.Panics(t, func() { - // this should run out of gas - _, err := NewLegacyQuerier(keeper, tc.gasLimit)(ctx, path, req) - t.Logf("%v", err) - }) - } else { - // otherwise, make sure we get a good success - _, err := NewLegacyQuerier(keeper, tc.gasLimit)(ctx, path, req) - require.NoError(t, err) + querier := NewGrpcQuerier(keeper.cdc, keeper.storeKey, keeper, tc.gasLimit) + req := &types.QuerySmartContractStateRequest{Address: contractAddr.String(), QueryData: msg} + _, gotErr := querier.SmartContractState(sdk.WrapSDKContext(ctx), req) + if tc.expOutOfGas { + require.Error(t, gotErr, sdkerrors.ErrOutOfGas) + return } + require.NoError(t, gotErr) }) } } diff --git a/x/wasm/module.go b/x/wasm/module.go index 8473d7f34e..ea79b23768 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -24,7 +24,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/CosmWasm/wasmd/x/wasm/client/cli" - "github.com/CosmWasm/wasmd/x/wasm/client/rest" + "github.com/CosmWasm/wasmd/x/wasm/client/rest" //nolint:staticcheck "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/CosmWasm/wasmd/x/wasm/simulation" "github.com/CosmWasm/wasmd/x/wasm/types" From 0ce88a4917b22a3dc61c8a11b3c3c84425070143 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 08:03:46 +0000 Subject: [PATCH 014/294] Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9fc233ec7d..8222d96353 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.13.0 + github.com/prometheus/client_golang v1.14.0 github.com/rakyll/statik v0.1.7 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cast v1.5.0 @@ -99,7 +99,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect diff --git a/go.sum b/go.sum index b65bb5e76f..4eace7260b 100644 --- a/go.sum +++ b/go.sum @@ -634,15 +634,16 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= From 5caaab9c0b157c57dfb488c6c5a914b58ad7cca6 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Fri, 11 Nov 2022 09:09:07 +0100 Subject: [PATCH 015/294] Add Developer's guide and best practices (#1075) * Add Developer's guide and best practices * Fix comments --- CODING_GUIDELINES.md | 51 ++++++++++++++++++++ CONTRIBUTING.md | 110 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 CODING_GUIDELINES.md create mode 100644 CONTRIBUTING.md diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md new file mode 100644 index 0000000000..eda2155aea --- /dev/null +++ b/CODING_GUIDELINES.md @@ -0,0 +1,51 @@ +# Coding Guidelines + +This document is an extension to [CONTRIBUTING](./CONTRIBUTING.md) and provides more details about the coding guidelines and requirements. + +## API & Design + +* Code must be well structured: + * packages must have a limited responsibility (different concerns can go to different packages), + * types must be easy to compose, + * think about maintainbility and testability. +* "Depend upon abstractions, [not] concretions". +* Try to limit the number of methods you are exposing. It's easier to expose something later than to hide it. +* Follow agreed-upon design patterns and naming conventions. +* publicly-exposed functions are named logically, have forward-thinking arguments and return types. +* Avoid global variables and global configurators. +* Favor composable and extensible designs. +* Minimize code duplication. +* Limit third-party dependencies. + +Performance: + +* Avoid unnecessary operations or memory allocations. + +Security: + +* Pay proper attention to exploits involving: + * gas usage + * transaction verification and signatures + * malleability + * code must be always deterministic +* Thread safety. If some functionality is not thread-safe, or uses something that is not thread-safe, then clearly indicate the risk on each level. + +## Best practices + +* Use [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) as your code formatter. + +* Always wrap returned errors. + * Doing `if err != nil { return err }` does not include each callers' context. Pushing errors up the stack without context makes it harder to test and debug. Additionally, a short context description makes it easier for the reader to understand the code. Example: + + ```go + if !coins.IsZero() { + if err := k.bank.TransferCoins(ctx, caller, contractAddress, coins); err != nil { + return nil, err + } + } + ``` + + * It would be an improvement to return `return nil, sdkerror.Wrap(err, "lock contract coins")` + * Please notice that fmt.Errorf is not used, because the error handling predates fmt.Errorf and errors.Is + +* Limit the use of aliases, when not used during the refactoring process. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..bb74e97e60 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,110 @@ +# Contributing + +Thank you for considering making contributions to Wasmd! + +Contributing to this repo can mean many things, such as participating in +discussion or proposing code changes. To ensure a smooth workflow for all +contributors, the general procedure for contributing has been established: + +1. Start by browsing [new issues](https://github.com/CosmWasm/wasmd/issues). + * Looking for a good place to start contributing? How about checking out some [good first issues](https://github.com/CosmWasm/wasmd/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [bugs](https://github.com/CosmWasm/wasmd/issues?q=is%3Aopen+is%3Aissue+label%3Abug)? +2. Determine whether a GitHub issue or discussion is more appropriate for your needs: + 1. If the issue you want addressed is a specific proposal or a bug, then open a [new issue](https://github.com/CosmWasm/wasmd/issues/new). + 2. Review existing [issues](https://github.com/CosmWasm/wasmd/issues) to find an issue you'd like to help with. +3. Participate in thoughtful discussion on that issue. +4. If you would like to contribute: + 1. Ensure that the proposal has been accepted. + 2. Ensure that nobody else has already begun working on this issue. If they have, + make sure to contact them to collaborate. + 3. If nobody has been assigned for the issue and you would like to work on it, + make a comment on the issue to inform the community of your intentions + to begin work. +5. To submit your work as a contribution to the repository follow standard GitHub best practices. See [pull request guideline](#pull-requests) below. + +**Note:** For very small or blatantly obvious problems such as typos, you are +not required to an open issue to submit a PR, but be aware that for more complex +problems/features, if a PR is opened before an adequate design discussion has +taken place in a GitHub issue, that PR runs a high likelihood of being rejected. + +## Development Procedure + +* The latest state of development is on `main`. +* `main` must never fail `make lint test test-race`. +* No `--force` onto `main` (except when reverting a broken commit, which should seldom happen). +* Create a branch to start work: + * Fork the repo (core developers must create a branch directly in the Wasmd repo), + branch from the HEAD of `main`, make some commits, and submit a PR to `main`. + * For core developers working within the `wasmd` repo, follow branch name conventions to ensure a clear + ownership of branches: `{issue#}-branch-name`. + * See [Branching Model](#branching-model-and-release) for more details. +* Be sure to run `make format` before every commit. The easiest way + to do this is have your editor run it for you upon saving a file (most of the editors + will do it anyway using a pre-configured setup of the programming language mode). +* Follow the [CODING GUIDELINES](CODING_GUIDELINES.md), which defines criteria for designing and coding a software. + +Code is merged into main through pull request procedure. + +### Testing + +Tests can be executed by running `make test` at the top level of the wasmd repository. + +### Pull Requests + +Before submitting a pull request: + +* merge the latest main `git merge origin/main`, +* run `make lint test` to ensure that all checks and tests pass. + +Then: + +1. If you have something to show, **start with a `Draft` PR**. It's good to have early validation of your work and we highly recommend this practice. A Draft PR also indicates to the community that the work is in progress. + Draft PRs also helps the core team provide early feedback and ensure the work is in the right direction. +2. When the code is complete, change your PR from `Draft` to `Ready for Review`. +3. Be sure to include a relevant changelog entry in the `Unreleased` section of `CHANGELOG.md` (see file for log format). The entry should be on top of all others changes in the section. + +PRs name should start upper case. +Additionally, each PR should only address a single issue. + +NOTE: when merging, GitHub will squash commits and rebase on top of the main. + +## Protobuf + +We use [Protocol Buffers](https://developers.google.com/protocol-buffers) along with [gogoproto](https://github.com/cosmos/gogoproto) to generate code for use in Wasmd. + +For deterministic behavior around Protobuf tooling, everything is containerized using Docker. Make sure to have Docker installed on your machine, or head to [Docker's website](https://docs.docker.com/get-docker/) to install it. + +For formatting code in `.proto` files, you can run `make proto-format` command. + +For linting we use [buf](https://buf.build/). You can use the commands `make proto-lint` to lint your proto files. + +To generate the protobuf stubs, you can run `make proto-gen`. + +We also added the `make proto-all` command to run all the above commands sequentially. + +In order for imports to properly compile in your IDE, you may need to manually set your protobuf path in your IDE's workspace settings/config. + +For example, in vscode your `.vscode/settings.json` should look like: + +```json +{ + "protoc": { + "options": [ + "--proto_path=${workspaceRoot}/proto", + ] + } +} +``` + +## Branching Model and Release + +User-facing repos should adhere to the trunk based development branching model: https://trunkbaseddevelopment.com. User branches should start with a user name, example: `{moniker}/{issue#}-branch-name`. + +Wasmd utilizes [semantic versioning](https://semver.org/). + +### PR Targeting + +Ensure that you base and target your PR on the `main` branch. + +All feature additions and all bug fixes must be targeted against `main`. Exception is for bug fixes which are only related to a released version. In that case, the related bug fix PRs must target against the release branch. + +If needed, we backport a commit from `main` to a release branch (excluding consensus breaking feature, API breaking and similar). \ No newline at end of file From 4c6afb38eb2b93236e8a3fd827f62d8a8994dff1 Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:45:40 +0700 Subject: [PATCH 016/294] Change genesis preserving contract history (#1076) * preserve contract created date on genesis import and add query contract created date * add validate created * fix sims test app import export * add preserve contract history * Make proto-all only * Remove ResetFromGenesis * Add validation Co-authored-by: Alex Peters --- app/sim_test.go | 34 ----- docs/proto/proto-docs.md | 3 +- proto/cosmwasm/wasm/v1/genesis.proto | 2 + proto/cosmwasm/wasm/v1/types.proto | 2 - x/wasm/client/cli/genesis_msg_test.go | 36 ++--- x/wasm/keeper/genesis.go | 14 +- x/wasm/keeper/genesis_test.go | 147 ++++++++++++++++---- x/wasm/keeper/keeper.go | 10 +- x/wasm/keeper/proposal_integration_test.go | 24 +++- x/wasm/keeper/querier.go | 2 - x/wasm/keeper/querier_test.go | 12 +- x/wasm/types/genesis.go | 12 +- x/wasm/types/genesis.pb.go | 154 +++++++++++++++------ x/wasm/types/genesis_test.go | 8 +- x/wasm/types/query.pb.gw.go | 7 +- x/wasm/types/test_fixtures.go | 23 ++- x/wasm/types/types.go | 31 +++-- x/wasm/types/types.pb.go | 2 - x/wasm/types/types_test.go | 39 ++++++ 19 files changed, 390 insertions(+), 172 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 41f729099e..e80c6fcae7 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -8,9 +8,6 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/store" - "github.com/cosmos/cosmos-sdk/store/prefix" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" @@ -196,37 +193,6 @@ func TestAppImportExport(t *testing.T) { // delete persistent tx counter value ctxA.KVStore(app.keys[wasm.StoreKey]).Delete(wasmtypes.TXCounterPrefix) - // reset contract code index in source DB for comparison with dest DB - dropContractHistory := func(s store.KVStore, keys ...[]byte) { - for _, key := range keys { - prefixStore := prefix.NewStore(s, key) - iter := prefixStore.Iterator(nil, nil) - for ; iter.Valid(); iter.Next() { - prefixStore.Delete(iter.Key()) - } - iter.Close() - } - } - prefixes := [][]byte{wasmtypes.ContractCodeHistoryElementPrefix, wasmtypes.ContractByCodeIDAndCreatedSecondaryIndexPrefix} - dropContractHistory(ctxA.KVStore(app.keys[wasm.StoreKey]), prefixes...) - dropContractHistory(ctxB.KVStore(newApp.keys[wasm.StoreKey]), prefixes...) - - normalizeContractInfo := func(ctx sdk.Context, app *WasmApp) { - var index uint64 - app.WasmKeeper.IterateContractInfo(ctx, func(address sdk.AccAddress, info wasmtypes.ContractInfo) bool { - created := &wasmtypes.AbsoluteTxPosition{ - BlockHeight: uint64(0), - TxIndex: index, - } - info.Created = created - store := ctx.KVStore(app.keys[wasm.StoreKey]) - store.Set(wasmtypes.GetContractAddressKey(address), app.appCodec.MustMarshal(&info)) - index++ - return false - }) - } - normalizeContractInfo(ctxA, app) - normalizeContractInfo(ctxB, newApp) // diff both stores for _, skp := range storeKeysPrefixes { storeA := ctxA.KVStore(skp.A) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index d6e5aee1d6..fdf641c81a 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -193,7 +193,7 @@ ContractInfo stores a WASM contract instance | `creator` | [string](#string) | | Creator address who initially instantiated the contract | | `admin` | [string](#string) | | Admin is an optional address that can execute migrations | | `label` | [string](#string) | | Label is optional metadata to be stored with a contract instance. | -| `created` | [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) | | Created Tx position when the contract was instantiated. This data should kept internal and not be exposed via query results. Just use for sorting | +| `created` | [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) | | Created Tx position when the contract was instantiated. | | `ibc_port_id` | [string](#string) | | | | `extension` | [google.protobuf.Any](#google.protobuf.Any) | | Extension is an extension point to store custom metadata within the persistence model. | @@ -568,6 +568,7 @@ Contract struct encompasses ContractAddress, ContractInfo, and ContractState | `contract_address` | [string](#string) | | | | `contract_info` | [ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | | `contract_state` | [Model](#cosmwasm.wasm.v1.Model) | repeated | | +| `contract_code_history` | [ContractCodeHistoryEntry](#cosmwasm.wasm.v1.ContractCodeHistoryEntry) | repeated | | diff --git a/proto/cosmwasm/wasm/v1/genesis.proto b/proto/cosmwasm/wasm/v1/genesis.proto index 87373e18d7..b7622c206a 100644 --- a/proto/cosmwasm/wasm/v1/genesis.proto +++ b/proto/cosmwasm/wasm/v1/genesis.proto @@ -53,6 +53,8 @@ message Contract { string contract_address = 1; ContractInfo contract_info = 2 [ (gogoproto.nullable) = false ]; repeated Model contract_state = 3 [ (gogoproto.nullable) = false ]; + repeated ContractCodeHistoryEntry contract_code_history = 4 + [ (gogoproto.nullable) = false ]; } // Sequence key and value of an id generation counter diff --git a/proto/cosmwasm/wasm/v1/types.proto b/proto/cosmwasm/wasm/v1/types.proto index 8d140248a8..216b24e3b4 100644 --- a/proto/cosmwasm/wasm/v1/types.proto +++ b/proto/cosmwasm/wasm/v1/types.proto @@ -84,8 +84,6 @@ message ContractInfo { // Label is optional metadata to be stored with a contract instance. string label = 4; // Created Tx position when the contract was instantiated. - // This data should kept internal and not be exposed via query results. Just - // use for sorting AbsoluteTxPosition created = 5; string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; diff --git a/x/wasm/client/cli/genesis_msg_test.go b/x/wasm/client/cli/genesis_msg_test.go index a1d24f29cd..cd8a5f3b7b 100644 --- a/x/wasm/client/cli/genesis_msg_test.go +++ b/x/wasm/client/cli/genesis_msg_test.go @@ -391,10 +391,11 @@ func TestExecuteContractCmd(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { - info.Created = nil - }), - ContractState: []types.Model{}, + ContractInfo: types.ContractInfoFixture(), + ContractState: []types.Model{}, + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + types.ContractCodeHistoryEntryFixture(), + }, }, }, }, @@ -473,10 +474,11 @@ func TestExecuteContractCmd(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { - info.Created = nil - }), - ContractState: []types.Model{}, + ContractInfo: types.ContractInfoFixture(), + ContractState: []types.Model{}, + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + types.ContractCodeHistoryEntryFixture(), + }, }, }, }, @@ -500,10 +502,11 @@ func TestExecuteContractCmd(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { - info.Created = nil - }), - ContractState: []types.Model{}, + ContractInfo: types.ContractInfoFixture(), + ContractState: []types.Model{}, + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + types.ContractCodeHistoryEntryFixture(), + }, }, }, }, @@ -528,10 +531,11 @@ func TestExecuteContractCmd(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { - info.Created = nil - }), - ContractState: []types.Model{}, + ContractInfo: types.ContractInfoFixture(), + ContractState: []types.Model{}, + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + types.ContractCodeHistoryEntryFixture(), + }, }, }, }, diff --git a/x/wasm/keeper/genesis.go b/x/wasm/keeper/genesis.go index 7fa5280b9e..2fb152a130 100644 --- a/x/wasm/keeper/genesis.go +++ b/x/wasm/keeper/genesis.go @@ -41,7 +41,7 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki if err != nil { return nil, sdkerrors.Wrapf(err, "address in contract number %d", i) } - err = keeper.importContract(ctx, contractAddr, &contract.ContractInfo, contract.ContractState) + err = keeper.importContract(ctx, contractAddr, &contract.ContractInfo, contract.ContractState, contract.ContractCodeHistory) if err != nil { return nil, sdkerrors.Wrapf(err, "contract number %d", i) } @@ -107,12 +107,14 @@ func ExportGenesis(ctx sdk.Context, keeper *Keeper) *types.GenesisState { state = append(state, types.Model{Key: key, Value: value}) return false }) - // redact contract info - contract.Created = nil + + contractCodeHistory := keeper.GetContractHistory(ctx, addr) + genState.Contracts = append(genState.Contracts, types.Contract{ - ContractAddress: addr.String(), - ContractInfo: contract, - ContractState: state, + ContractAddress: addr.String(), + ContractInfo: contract, + ContractState: state, + ContractCodeHistory: contractCodeHistory, }) return false }) diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index 1d8f29a40f..beba80fe7d 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -12,7 +12,6 @@ import ( "time" "github.com/cosmos/cosmos-sdk/store" - "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" @@ -111,21 +110,10 @@ func TestGenesisExportImport(t *testing.T) { // reset contract code index in source DB for comparison with dest DB wasmKeeper.IterateContractInfo(srcCtx, func(address sdk.AccAddress, info wasmTypes.ContractInfo) bool { creatorAddress := sdk.MustAccAddressFromBech32(info.Creator) - wasmKeeper.removeFromContractCodeSecondaryIndex(srcCtx, address, wasmKeeper.getLastContractHistoryEntry(srcCtx, address)) + history := wasmKeeper.GetContractHistory(srcCtx, address) - prefixStore := prefix.NewStore(srcCtx.KVStore(wasmKeeper.storeKey), types.GetContractCodeHistoryElementPrefix(address)) - iter := prefixStore.Iterator(nil, nil) - - for ; iter.Valid(); iter.Next() { - prefixStore.Delete(iter.Key()) - } - x := &info - newHistory := x.ResetFromGenesis(dstCtx) - wasmKeeper.storeContractInfo(srcCtx, address, x) - wasmKeeper.addToContractCodeSecondaryIndex(srcCtx, address, newHistory) - wasmKeeper.addToContractCreatorSecondaryIndex(srcCtx, creatorAddress, newHistory.Updated, address) - wasmKeeper.appendToContractHistory(srcCtx, address, newHistory) - iter.Close() + wasmKeeper.addToContractCodeSecondaryIndex(srcCtx, address, history[len(history)-1]) + wasmKeeper.addToContractCreatorSecondaryIndex(srcCtx, creatorAddress, history[0].Updated, address) return false }) @@ -272,7 +260,15 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{}`), + }, + }, }, }, Sequences: []types.Sequence{ @@ -293,10 +289,26 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{}`), + }, + }, }, { ContractAddress: BuildContractAddressClassic(1, 2).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{"foo":"bar"}`), + }, + }, }, }, Sequences: []types.Sequence{ @@ -312,7 +324,15 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{"foo":"bar"}`), + }, + }, }, }, Params: types.DefaultParams(), @@ -328,10 +348,26 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{"foo":"bar"}`), + }, + }, }, { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{"other":"value"}`), + }, + }, }, }, Params: types.DefaultParams(), @@ -347,7 +383,7 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), ContractState: []types.Model{ { Key: []byte{0x1}, @@ -358,6 +394,14 @@ func TestGenesisInit(t *testing.T) { Value: []byte("bar"), }, }, + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{"foo":"bar"}`), + }, + }, }, }, Params: types.DefaultParams(), @@ -395,7 +439,15 @@ func TestGenesisInit(t *testing.T) { Contracts: []types.Contract{ { ContractAddress: BuildContractAddressClassic(1, 1).String(), - ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.OnlyGenesisFields), + ContractInfo: types.ContractInfoFixture(func(c *wasmTypes.ContractInfo) { c.CodeID = 1 }, types.RandCreatedFields), + ContractCodeHistory: []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: 1, + Updated: &types.AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()}, + Msg: []byte(`{}`), + }, + }, }, }, Sequences: []types.Sequence{ @@ -459,7 +511,7 @@ func TestGenesisInit(t *testing.T) { } } -func TestImportContractWithCodeHistoryReset(t *testing.T) { +func TestImportContractWithCodeHistoryPreserved(t *testing.T) { genesisTemplate := ` { "params":{ @@ -489,8 +541,32 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) { "code_id": "1", "creator": "cosmos13x849jzd03vne42ynpj25hn8npjecxqrjghd8x", "admin": "cosmos1h5t8zxmjr30e9dqghtlpl40f2zz5cgey6esxtn", - "label": "ȀĴnZV芢毤" - } + "label": "ȀĴnZV芢毤", + "created": { + "block_height" : "100", + "tx_index" : "10" + } + }, + "contract_code_history": [ + { + "operation": "CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT", + "code_id": "1", + "updated": { + "block_height" : "100", + "tx_index" : "10" + }, + "msg": {"foo": "bar"} + }, + { + "operation": "CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE", + "code_id": "1", + "updated": { + "block_height" : "200", + "tx_index" : "10" + }, + "msg": {"other": "msg"} + } + ] } ], "sequences": [ @@ -550,15 +626,28 @@ func TestImportContractWithCodeHistoryReset(t *testing.T) { Creator: contractCreatorAddr, Admin: adminAddr, Label: "ȀĴnZV芢毤", - Created: &types.AbsoluteTxPosition{BlockHeight: 0, TxIndex: 0}, + Created: &types.AbsoluteTxPosition{BlockHeight: 100, TxIndex: 10}, } assert.Equal(t, expContractInfo, *gotContractInfo) expHistory := []types.ContractCodeHistoryEntry{ { - Operation: types.ContractCodeHistoryOperationTypeGenesis, + Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{ + BlockHeight: 100, + TxIndex: 10, + }, + Msg: []byte(`{"foo": "bar"}`), + }, + { + Operation: types.ContractCodeHistoryOperationTypeMigrate, + CodeID: firstCodeID, + Updated: &types.AbsoluteTxPosition{ + BlockHeight: 200, + TxIndex: 10, + }, + Msg: []byte(`{"other": "msg"}`), }, } assert.Equal(t, expHistory, keeper.GetContractHistory(ctx, contractAddr)) diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 3112a26eb5..195a4614ce 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -1062,7 +1062,7 @@ func (k Keeper) importAutoIncrementID(ctx sdk.Context, lastIDKey []byte, val uin return nil } -func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c *types.ContractInfo, state []types.Model) error { +func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c *types.ContractInfo, state []types.Model, entries []types.ContractCodeHistoryEntry) error { if !k.containsCodeInfo(ctx, c.CodeID) { return sdkerrors.Wrapf(types.ErrNotFound, "code id: %d", c.CodeID) } @@ -1074,11 +1074,11 @@ func (k Keeper) importContract(ctx sdk.Context, contractAddr sdk.AccAddress, c * if err != nil { return err } - historyEntry := c.ResetFromGenesis(ctx) - k.appendToContractHistory(ctx, contractAddr, historyEntry) + + k.appendToContractHistory(ctx, contractAddr, entries...) k.storeContractInfo(ctx, contractAddr, c) - k.addToContractCodeSecondaryIndex(ctx, contractAddr, historyEntry) - k.addToContractCreatorSecondaryIndex(ctx, creatorAddress, historyEntry.Updated, contractAddr) + k.addToContractCodeSecondaryIndex(ctx, contractAddr, entries[len(entries)-1]) + k.addToContractCreatorSecondaryIndex(ctx, creatorAddress, entries[0].Updated, contractAddr) return k.importContractState(ctx, contractAddr, state) } diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 5a0305a485..1327ba88e3 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -231,14 +231,18 @@ func TestMigrateProposal(t *testing.T) { contractAddr = BuildContractAddressClassic(1, 1) ) - contractInfoFixture := types.ContractInfoFixture(func(c *types.ContractInfo) { + contractInfo := types.ContractInfoFixture(func(c *types.ContractInfo) { c.Label = "testing" c.Admin = anyAddress.String() + c.Created = types.NewAbsoluteTxPosition(ctx) }) + entries := []types.ContractCodeHistoryEntry{ + {Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: 1, Updated: contractInfo.Created}, + } key, err := hex.DecodeString("636F6E666967") require.NoError(t, err) m := types.Model{Key: key, Value: []byte(`{"verifier":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","beneficiary":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","funder":"AQEBAQEBAQEBAQEBAQEBAQEBAQE="}`)} - require.NoError(t, wasmKeeper.importContract(ctx, contractAddr, &contractInfoFixture, []types.Model{m})) + require.NoError(t, wasmKeeper.importContract(ctx, contractAddr, &contractInfo, []types.Model{m}, entries)) migMsg := struct { Verifier sdk.AccAddress `json:"verifier"` @@ -273,7 +277,7 @@ func TestMigrateProposal(t *testing.T) { assert.Equal(t, anyAddress.String(), cInfo.Admin) assert.Equal(t, "testing", cInfo.Label) expHistory := []types.ContractCodeHistoryEntry{{ - Operation: types.ContractCodeHistoryOperationTypeGenesis, + Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, Updated: types.NewAbsoluteTxPosition(ctx), }, { @@ -469,10 +473,18 @@ func TestAdminProposals(t *testing.T) { InstantiateDefaultPermission: types.AccessTypeNobody, }) - codeInfoFixture := types.CodeInfoFixture(types.WithSHA256CodeHash(wasmCode)) - require.NoError(t, wasmKeeper.importCode(ctx, 1, codeInfoFixture, wasmCode)) + codeInfo := types.CodeInfoFixture(types.WithSHA256CodeHash(wasmCode)) + require.NoError(t, wasmKeeper.importCode(ctx, 1, codeInfo, wasmCode)) + + entries := []types.ContractCodeHistoryEntry{ + { + Operation: types.ContractCodeHistoryOperationTypeInit, + CodeID: 1, + Updated: spec.state.Created, + }, + } - require.NoError(t, wasmKeeper.importContract(ctx, contractAddr, &spec.state, []types.Model{})) + require.NoError(t, wasmKeeper.importContract(ctx, contractAddr, &spec.state, []types.Model{}, entries)) // when stored storedProposal, err := govKeeper.SubmitProposal(ctx, spec.srcProposal) require.NoError(t, err) diff --git a/x/wasm/keeper/querier.go b/x/wasm/keeper/querier.go index 9b23c68d96..ceb0470de6 100644 --- a/x/wasm/keeper/querier.go +++ b/x/wasm/keeper/querier.go @@ -257,8 +257,6 @@ func queryContractInfo(ctx sdk.Context, addr sdk.AccAddress, keeper types.ViewKe if info == nil { return nil, types.ErrNotFound } - // redact the Created field (just used for sorting, not part of public API) - info.Created = nil return &types.QueryContractInfoResponse{ Address: addr.String(), ContractInfo: *info, diff --git a/x/wasm/keeper/querier_test.go b/x/wasm/keeper/querier_test.go index 52a17d0e11..197e6afaa2 100644 --- a/x/wasm/keeper/querier_test.go +++ b/x/wasm/keeper/querier_test.go @@ -560,20 +560,16 @@ func TestQueryContractInfo(t *testing.T) { src: &types.QueryContractInfoRequest{Address: contractAddr.String()}, stored: types.ContractInfoFixture(), expRsp: &types.QueryContractInfoResponse{ - Address: contractAddr.String(), - ContractInfo: types.ContractInfoFixture(func(info *types.ContractInfo) { - info.Created = nil // not returned on queries - }), + Address: contractAddr.String(), + ContractInfo: types.ContractInfoFixture(), }, }, "with extension": { src: &types.QueryContractInfoRequest{Address: contractAddr.String()}, stored: types.ContractInfoFixture(myExtension), expRsp: &types.QueryContractInfoResponse{ - Address: contractAddr.String(), - ContractInfo: types.ContractInfoFixture(myExtension, func(info *types.ContractInfo) { - info.Created = nil // not returned on queries - }), + Address: contractAddr.String(), + ContractInfo: types.ContractInfoFixture(myExtension), }, }, "not found": { diff --git a/x/wasm/types/genesis.go b/x/wasm/types/genesis.go index ba973c6f02..a82893bd90 100644 --- a/x/wasm/types/genesis.go +++ b/x/wasm/types/genesis.go @@ -61,14 +61,22 @@ func (c Contract) ValidateBasic() error { return sdkerrors.Wrap(err, "contract info") } - if c.ContractInfo.Created != nil { - return sdkerrors.Wrap(ErrInvalid, "created must be empty") + if c.ContractInfo.Created == nil { + return sdkerrors.Wrap(ErrInvalid, "created must not be empty") } for i := range c.ContractState { if err := c.ContractState[i].ValidateBasic(); err != nil { return sdkerrors.Wrapf(err, "contract state %d", i) } } + if len(c.ContractCodeHistory) == 0 { + return ErrEmpty.Wrap("code history") + } + for i, v := range c.ContractCodeHistory { + if err := v.ValidateBasic(); err != nil { + return sdkerrors.Wrapf(err, "code history element %d", i) + } + } return nil } diff --git a/x/wasm/types/genesis.pb.go b/x/wasm/types/genesis.pb.go index 926b74c81c..3f7037985a 100644 --- a/x/wasm/types/genesis.pb.go +++ b/x/wasm/types/genesis.pb.go @@ -293,9 +293,10 @@ func (m *Code) GetPinned() bool { // Contract struct encompasses ContractAddress, ContractInfo, and ContractState type Contract struct { - ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - ContractInfo ContractInfo `protobuf:"bytes,2,opt,name=contract_info,json=contractInfo,proto3" json:"contract_info"` - ContractState []Model `protobuf:"bytes,3,rep,name=contract_state,json=contractState,proto3" json:"contract_state"` + ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + ContractInfo ContractInfo `protobuf:"bytes,2,opt,name=contract_info,json=contractInfo,proto3" json:"contract_info"` + ContractState []Model `protobuf:"bytes,3,rep,name=contract_state,json=contractState,proto3" json:"contract_state"` + ContractCodeHistory []ContractCodeHistoryEntry `protobuf:"bytes,4,rep,name=contract_code_history,json=contractCodeHistory,proto3" json:"contract_code_history"` } func (m *Contract) Reset() { *m = Contract{} } @@ -357,6 +358,13 @@ func (m *Contract) GetContractState() []Model { return nil } +func (m *Contract) GetContractCodeHistory() []ContractCodeHistoryEntry { + if m != nil { + return m.ContractCodeHistory + } + return nil +} + // Sequence key and value of an id generation counter type Sequence struct { IDKey []byte `protobuf:"bytes,1,opt,name=id_key,json=idKey,proto3" json:"id_key,omitempty"` @@ -426,48 +434,50 @@ func init() { func init() { proto.RegisterFile("cosmwasm/wasm/v1/genesis.proto", fileDescriptor_2ab3f539b23472a6) } var fileDescriptor_2ab3f539b23472a6 = []byte{ - // 646 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x6e, 0xd3, 0x4e, - 0x10, 0xc7, 0xe3, 0x26, 0x4e, 0x93, 0x69, 0x7e, 0xbf, 0x56, 0xdb, 0xaa, 0x35, 0x06, 0x9c, 0x28, - 0xa0, 0x2a, 0x48, 0x28, 0x51, 0x8b, 0xc4, 0x0d, 0x01, 0x6e, 0x2b, 0x6a, 0x55, 0x95, 0xc0, 0x15, - 0x42, 0x42, 0xaa, 0x22, 0xd7, 0xde, 0x1a, 0x8b, 0xda, 0x1b, 0xb2, 0x9b, 0x52, 0x9f, 0x79, 0x01, - 0x1e, 0x01, 0x5e, 0x06, 0xf5, 0xd8, 0x23, 0xa7, 0x08, 0xa5, 0x37, 0x9e, 0x02, 0xed, 0x1f, 0xbb, - 0x06, 0xa7, 0x17, 0x2b, 0x3b, 0xf3, 0x9d, 0xcf, 0xfc, 0xc9, 0xec, 0x82, 0xe5, 0x13, 0x1a, 0x7f, - 0xf6, 0x68, 0x3c, 0x10, 0x9f, 0xf3, 0xad, 0x41, 0x88, 0x13, 0x4c, 0x23, 0xda, 0x1f, 0x8d, 0x09, - 0x23, 0x68, 0x25, 0xf3, 0xf7, 0xc5, 0xe7, 0x7c, 0xcb, 0x5c, 0x0b, 0x49, 0x48, 0x84, 0x73, 0xc0, - 0x7f, 0x49, 0x9d, 0x79, 0xaf, 0xc4, 0x61, 0xe9, 0x08, 0x2b, 0x8a, 0x79, 0xa7, 0xec, 0xbd, 0x90, - 0xae, 0xee, 0x37, 0x1d, 0x5a, 0xaf, 0x64, 0xca, 0x23, 0xe6, 0x31, 0x8c, 0x9e, 0x42, 0x7d, 0xe4, - 0x8d, 0xbd, 0x98, 0x1a, 0x5a, 0x47, 0xeb, 0x2d, 0x6d, 0x1b, 0xfd, 0x7f, 0x4b, 0xe8, 0xbf, 0x16, - 0x7e, 0xbb, 0x76, 0x39, 0x6d, 0x57, 0x5c, 0xa5, 0x46, 0x7b, 0xa0, 0xfb, 0x24, 0xc0, 0xd4, 0x58, - 0xe8, 0x54, 0x7b, 0x4b, 0xdb, 0xeb, 0xe5, 0xb0, 0x1d, 0x12, 0x60, 0x7b, 0x83, 0x07, 0xfd, 0x9e, - 0xb6, 0x97, 0x85, 0xf8, 0x31, 0x89, 0x23, 0x86, 0xe3, 0x11, 0x4b, 0x5d, 0x19, 0x8d, 0xde, 0x42, - 0xd3, 0x27, 0x09, 0x1b, 0x7b, 0x3e, 0xa3, 0x46, 0x55, 0xa0, 0xcc, 0x79, 0x28, 0x29, 0xb1, 0xef, - 0x2a, 0xdc, 0x6a, 0x1e, 0x54, 0x40, 0xde, 0x90, 0x38, 0x96, 0xe2, 0x4f, 0x13, 0x9c, 0xf8, 0x98, - 0x1a, 0xb5, 0xdb, 0xb0, 0x47, 0x4a, 0x72, 0x83, 0xcd, 0x83, 0x8a, 0xd8, 0xdc, 0x88, 0x8e, 0xa1, - 0x11, 0xe2, 0x64, 0x18, 0xd3, 0x90, 0x1a, 0xba, 0xa0, 0x6e, 0x96, 0xa9, 0xc5, 0xf1, 0xf2, 0xc3, - 0x21, 0x0d, 0xa9, 0x6d, 0xaa, 0x0c, 0x28, 0x8b, 0x2f, 0x24, 0x58, 0x0c, 0xa5, 0xc8, 0xfc, 0xb2, - 0x00, 0x8b, 0x2a, 0x00, 0x3d, 0x07, 0xa0, 0x8c, 0x8c, 0xf1, 0x90, 0xcf, 0x49, 0xfd, 0x37, 0x56, - 0x39, 0xd9, 0x21, 0x0d, 0x8f, 0xb8, 0x8c, 0x0f, 0x7b, 0xbf, 0xe2, 0x36, 0x69, 0x76, 0x40, 0xc7, - 0xb0, 0x16, 0x25, 0x94, 0x79, 0x09, 0x8b, 0x3c, 0xc6, 0x31, 0x72, 0x36, 0xc6, 0x82, 0x40, 0xf5, - 0xe6, 0xa2, 0x9c, 0x9b, 0x80, 0x6c, 0xe4, 0xfb, 0x15, 0x77, 0x35, 0x2a, 0x9b, 0xd1, 0x1b, 0x58, - 0xc1, 0x17, 0xd8, 0x9f, 0x14, 0xd1, 0x55, 0x81, 0x7e, 0x38, 0x17, 0xbd, 0x27, 0xc5, 0x05, 0xec, - 0x32, 0xfe, 0xdb, 0x64, 0xeb, 0x50, 0xa5, 0x93, 0xb8, 0xfb, 0x5d, 0x83, 0x9a, 0xe8, 0xe0, 0x01, - 0x2c, 0xf2, 0xe6, 0x87, 0x51, 0x20, 0xfa, 0xaf, 0xd9, 0x30, 0x9b, 0xb6, 0xeb, 0xdc, 0xe5, 0xec, - 0xba, 0x75, 0xee, 0x72, 0x02, 0xf4, 0x8c, 0x2f, 0x10, 0x17, 0x25, 0xa7, 0x44, 0xf5, 0x66, 0xce, - 0xdf, 0x45, 0x27, 0x39, 0x25, 0x6a, 0x89, 0x1b, 0xbe, 0x3a, 0xa3, 0xfb, 0x00, 0x22, 0xfc, 0x24, - 0x65, 0x98, 0x8a, 0x06, 0x5a, 0xae, 0x00, 0xda, 0xdc, 0x80, 0xd6, 0xa1, 0x3e, 0x8a, 0x92, 0x04, - 0x07, 0x46, 0xad, 0xa3, 0xf5, 0x1a, 0xae, 0x3a, 0x75, 0x7f, 0x68, 0xd0, 0xc8, 0x47, 0xf1, 0x08, - 0x56, 0xb2, 0x11, 0x0c, 0xbd, 0x20, 0x18, 0x63, 0x2a, 0x2f, 0x53, 0xd3, 0x5d, 0xce, 0xec, 0x2f, - 0xa5, 0x19, 0x39, 0xf0, 0x5f, 0x2e, 0x2d, 0x54, 0x6c, 0xdd, 0xbe, 0xf2, 0x85, 0xaa, 0x5b, 0x7e, - 0xc1, 0x86, 0x76, 0xe1, 0xff, 0x1c, 0x45, 0xf9, 0xae, 0xa9, 0xeb, 0xb3, 0x31, 0x67, 0xfc, 0x24, - 0xc0, 0x67, 0x0a, 0x92, 0xe7, 0x17, 0xfb, 0xd9, 0xb5, 0xa1, 0x91, 0xdd, 0x02, 0xd4, 0x81, 0x7a, - 0x14, 0x0c, 0x3f, 0xe2, 0x54, 0x54, 0xdf, 0xb2, 0x9b, 0xb3, 0x69, 0x5b, 0x77, 0x76, 0x0f, 0x70, - 0xea, 0xea, 0x51, 0x70, 0x80, 0x53, 0xb4, 0x06, 0xfa, 0xb9, 0x77, 0x36, 0xc1, 0xa2, 0xec, 0x9a, - 0x2b, 0x0f, 0xf6, 0x8b, 0xcb, 0x99, 0xa5, 0x5d, 0xcd, 0x2c, 0xed, 0xd7, 0xcc, 0xd2, 0xbe, 0x5e, - 0x5b, 0x95, 0xab, 0x6b, 0xab, 0xf2, 0xf3, 0xda, 0xaa, 0xbc, 0xdf, 0x0c, 0x23, 0xf6, 0x61, 0x72, - 0xd2, 0xf7, 0x49, 0x3c, 0xd8, 0x21, 0x34, 0x7e, 0x97, 0xbd, 0x49, 0xc1, 0xe0, 0x42, 0xbe, 0x4d, - 0xe2, 0xd9, 0x3a, 0xa9, 0x8b, 0xc7, 0xe9, 0xc9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x05, - 0x87, 0xde, 0x1f, 0x05, 0x00, 0x00, + // 676 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xe3, 0x24, 0x4e, 0x93, 0x69, 0xa0, 0xd5, 0xb6, 0xb4, 0xc6, 0x80, 0x13, 0x05, 0x54, + 0x05, 0x84, 0x12, 0xb5, 0x48, 0xdc, 0x10, 0xe0, 0xb6, 0xa2, 0x51, 0x55, 0x09, 0x5c, 0x21, 0x24, + 0xa4, 0x2a, 0x72, 0xed, 0xad, 0x6b, 0x51, 0x7b, 0x43, 0x76, 0x53, 0xea, 0x33, 0x2f, 0xc0, 0x23, + 0xc0, 0x9d, 0x07, 0xe9, 0xb1, 0x47, 0x4e, 0x11, 0x4a, 0x6f, 0x3c, 0x05, 0xda, 0x3f, 0x76, 0x0d, + 0x49, 0x2e, 0x56, 0x76, 0xe6, 0x9b, 0xdf, 0xee, 0x7e, 0x99, 0x59, 0xb0, 0x3c, 0x42, 0xa3, 0x2f, + 0x2e, 0x8d, 0xba, 0xe2, 0x73, 0xbe, 0xd9, 0x0d, 0x70, 0x8c, 0x69, 0x48, 0x3b, 0x83, 0x21, 0x61, + 0x04, 0x2d, 0xa7, 0xf9, 0x8e, 0xf8, 0x9c, 0x6f, 0x9a, 0xab, 0x01, 0x09, 0x88, 0x48, 0x76, 0xf9, + 0x2f, 0xa9, 0x33, 0xef, 0x4f, 0x71, 0x58, 0x32, 0xc0, 0x8a, 0x62, 0xde, 0x9d, 0xce, 0x5e, 0xc8, + 0x54, 0xeb, 0xbb, 0x0e, 0xf5, 0x37, 0x72, 0xcb, 0x43, 0xe6, 0x32, 0x8c, 0x9e, 0x43, 0x65, 0xe0, + 0x0e, 0xdd, 0x88, 0x1a, 0x5a, 0x53, 0x6b, 0x2f, 0x6e, 0x19, 0x9d, 0xff, 0x8f, 0xd0, 0x79, 0x2b, + 0xf2, 0x76, 0xf9, 0x72, 0xdc, 0x28, 0x38, 0x4a, 0x8d, 0x76, 0x41, 0xf7, 0x88, 0x8f, 0xa9, 0x51, + 0x6c, 0x96, 0xda, 0x8b, 0x5b, 0x6b, 0xd3, 0x65, 0xdb, 0xc4, 0xc7, 0xf6, 0x3a, 0x2f, 0xfa, 0x33, + 0x6e, 0x2c, 0x09, 0xf1, 0x53, 0x12, 0x85, 0x0c, 0x47, 0x03, 0x96, 0x38, 0xb2, 0x1a, 0xbd, 0x87, + 0x9a, 0x47, 0x62, 0x36, 0x74, 0x3d, 0x46, 0x8d, 0x92, 0x40, 0x99, 0xb3, 0x50, 0x52, 0x62, 0xdf, + 0x53, 0xb8, 0x95, 0xac, 0x28, 0x87, 0xbc, 0x21, 0x71, 0x2c, 0xc5, 0x9f, 0x47, 0x38, 0xf6, 0x30, + 0x35, 0xca, 0xf3, 0xb0, 0x87, 0x4a, 0x72, 0x83, 0xcd, 0x8a, 0xf2, 0xd8, 0x2c, 0x88, 0x8e, 0xa0, + 0x1a, 0xe0, 0xb8, 0x1f, 0xd1, 0x80, 0x1a, 0xba, 0xa0, 0x6e, 0x4c, 0x53, 0xf3, 0xf6, 0xf2, 0xc5, + 0x01, 0x0d, 0xa8, 0x6d, 0xaa, 0x1d, 0x50, 0x5a, 0x9f, 0xdb, 0x60, 0x21, 0x90, 0x22, 0xf3, 0x6b, + 0x11, 0x16, 0x54, 0x01, 0x7a, 0x09, 0x40, 0x19, 0x19, 0xe2, 0x3e, 0xf7, 0x49, 0xfd, 0x37, 0xd6, + 0xf4, 0x66, 0x07, 0x34, 0x38, 0xe4, 0x32, 0x6e, 0xf6, 0x5e, 0xc1, 0xa9, 0xd1, 0x74, 0x81, 0x8e, + 0x60, 0x35, 0x8c, 0x29, 0x73, 0x63, 0x16, 0xba, 0x8c, 0x63, 0xa4, 0x37, 0x46, 0x51, 0xa0, 0xda, + 0x33, 0x51, 0xbd, 0x9b, 0x82, 0xd4, 0xf2, 0xbd, 0x82, 0xb3, 0x12, 0x4e, 0x87, 0xd1, 0x3b, 0x58, + 0xc6, 0x17, 0xd8, 0x1b, 0xe5, 0xd1, 0x25, 0x81, 0x7e, 0x34, 0x13, 0xbd, 0x2b, 0xc5, 0x39, 0xec, + 0x12, 0xfe, 0x37, 0x64, 0xeb, 0x50, 0xa2, 0xa3, 0xa8, 0xf5, 0x43, 0x83, 0xb2, 0xb8, 0xc1, 0x43, + 0x58, 0xe0, 0x97, 0xef, 0x87, 0xbe, 0xb8, 0x7f, 0xd9, 0x86, 0xc9, 0xb8, 0x51, 0xe1, 0xa9, 0xde, + 0x8e, 0x53, 0xe1, 0xa9, 0x9e, 0x8f, 0x5e, 0xf0, 0x06, 0xe2, 0xa2, 0xf8, 0x84, 0xa8, 0xbb, 0x99, + 0xb3, 0x7b, 0xb1, 0x17, 0x9f, 0x10, 0xd5, 0xc4, 0x55, 0x4f, 0xad, 0xd1, 0x03, 0x00, 0x51, 0x7e, + 0x9c, 0x30, 0x4c, 0xc5, 0x05, 0xea, 0x8e, 0x00, 0xda, 0x3c, 0x80, 0xd6, 0xa0, 0x32, 0x08, 0xe3, + 0x18, 0xfb, 0x46, 0xb9, 0xa9, 0xb5, 0xab, 0x8e, 0x5a, 0xb5, 0x7e, 0x16, 0xa1, 0x9a, 0x59, 0xf1, + 0x18, 0x96, 0x53, 0x0b, 0xfa, 0xae, 0xef, 0x0f, 0x31, 0x95, 0xc3, 0x54, 0x73, 0x96, 0xd2, 0xf8, + 0x6b, 0x19, 0x46, 0x3d, 0xb8, 0x95, 0x49, 0x73, 0x27, 0xb6, 0xe6, 0xb7, 0x7c, 0xee, 0xd4, 0x75, + 0x2f, 0x17, 0x43, 0x3b, 0x70, 0x3b, 0x43, 0x51, 0xde, 0x6b, 0x6a, 0x7c, 0xd6, 0x67, 0xd8, 0x4f, + 0x7c, 0x7c, 0xa6, 0x20, 0xd9, 0xfe, 0x72, 0xfc, 0x7d, 0xb8, 0x93, 0x51, 0x84, 0x11, 0xa7, 0x21, + 0x6f, 0xa1, 0x44, 0x0d, 0xcd, 0x93, 0xf9, 0x07, 0x13, 0x1d, 0x27, 0xc5, 0xbb, 0x31, 0x1b, 0x26, + 0x8a, 0x9f, 0x4d, 0x66, 0x2e, 0xdf, 0xb2, 0xa1, 0x9a, 0xce, 0x1a, 0x6a, 0x42, 0x25, 0xf4, 0xfb, + 0x9f, 0x70, 0x22, 0x3c, 0xaa, 0xdb, 0xb5, 0xc9, 0xb8, 0xa1, 0xf7, 0x76, 0xf6, 0x71, 0xe2, 0xe8, + 0xa1, 0xbf, 0x8f, 0x13, 0xb4, 0x0a, 0xfa, 0xb9, 0x7b, 0x36, 0xc2, 0xc2, 0x9c, 0xb2, 0x23, 0x17, + 0xf6, 0xab, 0xcb, 0x89, 0xa5, 0x5d, 0x4d, 0x2c, 0xed, 0xf7, 0xc4, 0xd2, 0xbe, 0x5d, 0x5b, 0x85, + 0xab, 0x6b, 0xab, 0xf0, 0xeb, 0xda, 0x2a, 0x7c, 0xdc, 0x08, 0x42, 0x76, 0x3a, 0x3a, 0xee, 0x78, + 0x24, 0xea, 0x6e, 0x13, 0x1a, 0x7d, 0x48, 0x5f, 0x3e, 0xbf, 0x7b, 0x21, 0x5f, 0x40, 0xf1, 0x38, + 0x1e, 0x57, 0xc4, 0x13, 0xf8, 0xec, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xb6, 0x2c, 0x20, + 0x85, 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -732,6 +742,20 @@ func (m *Contract) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ContractCodeHistory) > 0 { + for iNdEx := len(m.ContractCodeHistory) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ContractCodeHistory[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } if len(m.ContractState) > 0 { for iNdEx := len(m.ContractState) - 1; iNdEx >= 0; iNdEx-- { { @@ -938,6 +962,12 @@ func (m *Contract) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.ContractCodeHistory) > 0 { + for _, e := range m.ContractCodeHistory { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -1626,6 +1656,40 @@ func (m *Contract) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractCodeHistory", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractCodeHistory = append(m.ContractCodeHistory, ContractCodeHistoryEntry{}) + if err := m.ContractCodeHistory[len(m.ContractCodeHistory)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/wasm/types/genesis_test.go b/x/wasm/types/genesis_test.go index 3ef424e7e5..5ddcb20885 100644 --- a/x/wasm/types/genesis_test.go +++ b/x/wasm/types/genesis_test.go @@ -157,7 +157,7 @@ func TestContractValidateBasic(t *testing.T) { srcMutator: func(c *Contract) { c.ContractInfo.Created = &AbsoluteTxPosition{} }, - expError: true, + expError: false, }, "contract state invalid": { srcMutator: func(c *Contract) { @@ -165,6 +165,12 @@ func TestContractValidateBasic(t *testing.T) { }, expError: true, }, + "contract history invalid": { + srcMutator: func(c *Contract) { + c.ContractCodeHistory = []ContractCodeHistoryEntry{{}} + }, + expError: true, + }, } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { diff --git a/x/wasm/types/query.pb.gw.go b/x/wasm/types/query.pb.gw.go index 527cac4e74..4bffee3d7c 100644 --- a/x/wasm/types/query.pb.gw.go +++ b/x/wasm/types/query.pb.gw.go @@ -868,6 +868,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ContractsByCreator_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -875,6 +877,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ContractsByCreator_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1155,9 +1158,9 @@ var ( pattern_Query_PinnedCodes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "pinned"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmwasm", "wasm", "v1", "codes", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ContractsByCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmwasm", "wasm", "v1", "contracts", "creator", "creator_address"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ContractsByCreator_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmwasm", "wasm", "v1", "contracts", "creator", "creator_address"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index de07f175de..22da3520d6 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -87,9 +87,12 @@ func ContractFixture(mutators ...func(*Contract)) Contract { fixture := Contract{ ContractAddress: anyAddress, - ContractInfo: ContractInfoFixture(OnlyGenesisFields), + ContractInfo: ContractInfoFixture(RandCreatedFields), ContractState: []Model{{Key: []byte("anyKey"), Value: []byte("anyValue")}}, } + fixture.ContractCodeHistory = []ContractCodeHistoryEntry{ContractCodeHistoryEntryFixture(func(e *ContractCodeHistoryEntry) { + e.Updated = fixture.ContractInfo.Created + })} for _, m := range mutators { m(&fixture) @@ -101,6 +104,10 @@ func OnlyGenesisFields(info *ContractInfo) { info.Created = nil } +func RandCreatedFields(info *ContractInfo) { + info.Created = &AbsoluteTxPosition{BlockHeight: rand.Uint64(), TxIndex: rand.Uint64()} +} + func ContractInfoFixture(mutators ...func(*ContractInfo)) ContractInfo { const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" @@ -117,6 +124,20 @@ func ContractInfoFixture(mutators ...func(*ContractInfo)) ContractInfo { return fixture } +// ContractCodeHistoryEntryFixture test fixture +func ContractCodeHistoryEntryFixture(mutators ...func(*ContractCodeHistoryEntry)) ContractCodeHistoryEntry { + fixture := ContractCodeHistoryEntry{ + Operation: ContractCodeHistoryOperationTypeInit, + CodeID: 1, + Updated: ContractInfoFixture().Created, + Msg: []byte(`{"foo":"bar"}`), + } + for _, m := range mutators { + m(&fixture) + } + return fixture +} + func WithSHA256CodeHash(wasmCode []byte) func(info *CodeInfo) { return func(info *CodeInfo) { codeHash := sha256.Sum256(wasmCode) diff --git a/x/wasm/types/types.go b/x/wasm/types/types.go index 6453c5f1d0..4a0e198f03 100644 --- a/x/wasm/types/types.go +++ b/x/wasm/types/types.go @@ -171,16 +171,6 @@ func (c *ContractInfo) AddMigration(ctx sdk.Context, codeID uint64, msg []byte) return h } -// ResetFromGenesis resets contracts timestamp and history. -func (c *ContractInfo) ResetFromGenesis(ctx sdk.Context) ContractCodeHistoryEntry { - c.Created = NewAbsoluteTxPosition(ctx) - return ContractCodeHistoryEntry{ - Operation: ContractCodeHistoryOperationTypeGenesis, - CodeID: c.CodeID, - Updated: c.Created, - } -} - // AdminAddr convert into sdk.AccAddress or nil when not set func (c *ContractInfo) AdminAddr() sdk.AccAddress { if c.Admin == "" { @@ -253,6 +243,27 @@ func (a *AbsoluteTxPosition) Bytes() []byte { return r } +// ValidateBasic syntax checks +func (c ContractCodeHistoryEntry) ValidateBasic() error { + var found bool + for _, v := range AllCodeHistoryTypes { + if c.Operation == v { + found = true + break + } + } + if !found { + return ErrInvalid.Wrap("operation") + } + if c.CodeID == 0 { + return ErrEmpty.Wrap("code id") + } + if c.Updated == nil { + return ErrEmpty.Wrap("updated") + } + return sdkerrors.Wrap(c.Msg.ValidateBasic(), "msg") +} + // NewEnv initializes the environment for a contract instance func NewEnv(ctx sdk.Context, contractAddr sdk.AccAddress) wasmvmtypes.Env { // safety checks before casting below diff --git a/x/wasm/types/types.pb.go b/x/wasm/types/types.pb.go index 7b41c98394..d53952253e 100644 --- a/x/wasm/types/types.pb.go +++ b/x/wasm/types/types.pb.go @@ -296,8 +296,6 @@ type ContractInfo struct { // Label is optional metadata to be stored with a contract instance. Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` // Created Tx position when the contract was instantiated. - // This data should kept internal and not be exposed via query results. Just - // use for sorting Created *AbsoluteTxPosition `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` IBCPortID string `protobuf:"bytes,6,opt,name=ibc_port_id,json=ibcPortId,proto3" json:"ibc_port_id,omitempty"` // Extension is an extension point to store custom metadata within the diff --git a/x/wasm/types/types_test.go b/x/wasm/types/types_test.go index be270ddeb3..25df828023 100644 --- a/x/wasm/types/types_test.go +++ b/x/wasm/types/types_test.go @@ -706,3 +706,42 @@ func TestAccessTypeSubset(t *testing.T) { }) } } + +func TestContractCodeHistoryEntryValidation(t *testing.T) { + specs := map[string]struct { + src ContractCodeHistoryEntry + expErr bool + }{ + "all good": { + src: ContractCodeHistoryEntryFixture(), + }, + "unknown operation": { + src: ContractCodeHistoryEntryFixture(func(entry *ContractCodeHistoryEntry) { + entry.Operation = 0 + }), + expErr: true, + }, + "empty code id": { + src: ContractCodeHistoryEntryFixture(func(entry *ContractCodeHistoryEntry) { + entry.CodeID = 0 + }), + expErr: true, + }, + "empty updated": { + src: ContractCodeHistoryEntryFixture(func(entry *ContractCodeHistoryEntry) { + entry.Updated = nil + }), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} From 9cbf64d967fa1298929b242defe9e4253ad82a21 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 11 Nov 2022 09:47:59 +0100 Subject: [PATCH 017/294] Return contract history updates --- x/wasm/keeper/querier.go | 1 - x/wasm/keeper/querier_test.go | 22 ++++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/x/wasm/keeper/querier.go b/x/wasm/keeper/querier.go index ceb0470de6..cd573ab5a3 100644 --- a/x/wasm/keeper/querier.go +++ b/x/wasm/keeper/querier.go @@ -68,7 +68,6 @@ func (q grpcQuerier) ContractHistory(c context.Context, req *types.QueryContract if err := q.cdc.Unmarshal(value, &e); err != nil { return false, err } - e.Updated = nil // redact r = append(r, e) } return true, nil diff --git a/x/wasm/keeper/querier_test.go b/x/wasm/keeper/querier_test.go index 197e6afaa2..9568ad97d5 100644 --- a/x/wasm/keeper/querier_test.go +++ b/x/wasm/keeper/querier_test.go @@ -330,7 +330,7 @@ func TestQueryContractHistory(t *testing.T) { srcHistory: []types.ContractCodeHistoryEntry{{ Operation: types.ContractCodeHistoryOperationTypeGenesis, CodeID: firstCodeID, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, Msg: []byte(`"init message"`), }}, req: types.QueryContractHistoryRequest{Address: myContractBech32Addr}, @@ -338,23 +338,24 @@ func TestQueryContractHistory(t *testing.T) { Operation: types.ContractCodeHistoryOperationTypeGenesis, CodeID: firstCodeID, Msg: []byte(`"init message"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, }}, }, "response with multiple entries": { srcHistory: []types.ContractCodeHistoryEntry{{ Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, Msg: []byte(`"init message"`), }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 2, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 3, TxIndex: 4}, Msg: []byte(`"migrate message 1"`), }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 3, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 5, TxIndex: 6}, Msg: []byte(`"migrate message 2"`), }}, req: types.QueryContractHistoryRequest{Address: myContractBech32Addr}, @@ -362,26 +363,29 @@ func TestQueryContractHistory(t *testing.T) { Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, Msg: []byte(`"init message"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 2, Msg: []byte(`"migrate message 1"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 3, TxIndex: 4}, }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 3, Msg: []byte(`"migrate message 2"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 5, TxIndex: 6}, }}, }, "with pagination offset": { srcHistory: []types.ContractCodeHistoryEntry{{ Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, Msg: []byte(`"init message"`), }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 2, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 3, TxIndex: 4}, Msg: []byte(`"migrate message 1"`), }}, req: types.QueryContractHistoryRequest{ @@ -394,18 +398,19 @@ func TestQueryContractHistory(t *testing.T) { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 2, Msg: []byte(`"migrate message 1"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 3, TxIndex: 4}, }}, }, "with pagination limit": { srcHistory: []types.ContractCodeHistoryEntry{{ Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, Msg: []byte(`"init message"`), }, { Operation: types.ContractCodeHistoryOperationTypeMigrate, CodeID: 2, - Updated: types.NewAbsoluteTxPosition(ctx), + Updated: &types.AbsoluteTxPosition{BlockHeight: 3, TxIndex: 4}, Msg: []byte(`"migrate message 1"`), }}, req: types.QueryContractHistoryRequest{ @@ -418,6 +423,7 @@ func TestQueryContractHistory(t *testing.T) { Operation: types.ContractCodeHistoryOperationTypeInit, CodeID: firstCodeID, Msg: []byte(`"init message"`), + Updated: &types.AbsoluteTxPosition{BlockHeight: 1, TxIndex: 2}, }}, }, "unknown contract address": { From cf81eb8ea6828dd6b03a96ed166267cf64befc06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Nov 2022 09:50:53 +0100 Subject: [PATCH 018/294] Bump github.com/spf13/viper from 1.13.0 to 1.14.0 (#1082) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 68 +++++-- go.sum | 575 ++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 516 insertions(+), 127 deletions(-) diff --git a/go.mod b/go.mod index 9fc233ec7d..3a30b24408 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.18 require ( github.com/CosmWasm/wasmvm v1.1.1 github.com/cosmos/cosmos-proto v1.0.0-alpha8 - github.com/cosmos/cosmos-sdk v0.45.10 + github.com/cosmos/cosmos-sdk v0.46.1 github.com/cosmos/gogoproto v1.4.2 github.com/cosmos/iavl v0.19.4 github.com/cosmos/ibc-go/v3 v3.3.1 - github.com/cosmos/interchain-accounts v0.1.0 + github.com/cosmos/interchain-accounts v0.4.0 github.com/dvsekhvalnov/jose2go v1.5.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 @@ -23,33 +23,45 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.5.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.13.0 - github.com/stretchr/testify v1.8.0 - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca + github.com/spf13/viper v1.14.0 + github.com/stretchr/testify v1.8.1 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/tendermint v0.34.22 github.com/tendermint/tm-db v0.6.7 - google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b - google.golang.org/grpc v1.50.0 + google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e + google.golang.org/grpc v1.50.1 gopkg.in/yaml.v2 v2.4.0 ) require ( - filippo.io/edwards25519 v1.0.0-beta.2 // indirect + cloud.google.com/go v0.104.0 // indirect + cloud.google.com/go/compute v1.12.1 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/iam v0.3.0 // indirect + cloud.google.com/go/storage v1.23.0 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/math v1.0.0-beta.3 // indirect + filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect github.com/armon/go-metrics v0.4.0 // indirect + github.com/aws/aws-sdk-go v1.40.45 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/btcsuite/btcd v0.22.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/confio/ics23/go v0.7.0 // indirect github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 // indirect github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect @@ -61,28 +73,39 @@ require ( github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect github.com/golang/glog v1.0.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.6.0 // indirect + github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.6.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect - github.com/improbable-eng/grpc-web v0.14.1 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/lib/pq v1.10.6 // indirect @@ -93,6 +116,8 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -107,24 +132,31 @@ require ( github.com/rs/cors v1.8.2 // indirect github.com/rs/zerolog v1.27.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/afero v1.9.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/zondax/hid v0.9.0 // indirect + github.com/ulikunitz/xz v0.5.8 // indirect + github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect go.etcd.io/bbolt v1.3.6 // indirect + go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect - golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect + golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect + golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect + golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/text v0.4.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.102.0 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index b65bb5e76f..09f720ec87 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,13 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -16,14 +18,43 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -34,36 +65,36 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0 h1:wWRIaDURQA8xxHguFCshYepGlrWIrbBnAmc7wfg07qY= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= +cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/math v1.0.0-beta.3 h1:TbZxSopz2LqjJ7aXYfn7nJSb8vNaBklW6BLpcei1qwM= +cosmossdk.io/math v1.0.0-beta.3/go.mod h1:3LYasri3Zna4XpbrTNdKsWmD5fHHkaNAod/mNT9XdE4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= -filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= +filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= +git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/CosmWasm/wasmvm v1.1.1 h1:0xtdrmmsP9fibe+x42WcMkp5aQ738BICgcH3FNVLzm4= github.com/CosmWasm/wasmvm v1.1.1/go.mod h1:ei0xpvomwSdONsxDuONzV7bL1jSET1M8brEx0FCXc+A= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -72,7 +103,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= @@ -81,16 +112,18 @@ github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1: github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -99,29 +132,47 @@ github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.40.45 h1:QN1nsY27ssD/JmW4s83qmSb+uL6DG4GmCDzjmJB4xUI= +github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -129,9 +180,14 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -139,18 +195,26 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= -github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= +github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= +github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= +github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= +github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -162,8 +226,8 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= -github.com/cosmos/cosmos-sdk v0.45.10 h1:YRf1N6C7OFCc8FJ5wuhcnDDySJNDn5DxSscVgbeXgz4= -github.com/cosmos/cosmos-sdk v0.45.10/go.mod h1:CbfWNs4PuxxsvRD/snQuSBDwIhtsD7rIDTVQyYMKTa0= +github.com/cosmos/cosmos-sdk v0.46.1 h1:7vUZXMyrmEb4xtBYpz1TobtrcnpgiZTi+tVjc0XWB4o= +github.com/cosmos/cosmos-sdk v0.46.1/go.mod h1:2+o8Qw8qnE02V+lQVZDJFQ8tri/hsiA5GmWaPERqVa0= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -177,8 +241,10 @@ github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-go/v3 v3.3.1 h1:i8o3iPSPN8fr7AjCPQnHEKz/VfeMrxc8mjvgAw6txWk= github.com/cosmos/ibc-go/v3 v3.3.1/go.mod h1:V1nliDk/5q5KWr0mup7M76oN4SY0IOU371SKbCV2wN0= -github.com/cosmos/interchain-accounts v0.1.0 h1:QmuwNsf1Hxl3P5GSGt7Z+JeuHPiZw4Z34R/038P5T6s= -github.com/cosmos/interchain-accounts v0.1.0/go.mod h1:Fv6LXDs+0ng4mIDVWwEJMXbAIMxY4kiq+A7Bw1Fb9AY= +github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 h1:FpmkSFqRGwFZPL4HNLJ0V2L4/ILyG+tcVy59+EBn7q4= +github.com/cosmos/ibc-go/v6 v6.0.0-alpha1/go.mod h1:F2p2yeQlr4+L/YslhlY+Rk1uHXAJ2yKPPo6/uDUsYpc= +github.com/cosmos/interchain-accounts v0.4.0 h1:EMkYnvh6xROqs86YVaUS5dL/Q8yS9W8AcOsMj94qoW8= +github.com/cosmos/interchain-accounts v0.4.0/go.mod h1:0n1OaiiqrVObeBTeC4Y67skKC5al46MPpiAZSQlHfok= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= @@ -189,17 +255,23 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -207,52 +279,60 @@ github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70d github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= +github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -271,6 +351,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -278,8 +360,9 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -290,8 +373,12 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -299,13 +386,17 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -322,18 +413,19 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -342,17 +434,25 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -365,12 +465,33 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -381,11 +502,11 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= @@ -405,8 +526,13 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY= +github.com/hashicorp/go-getter v1.6.1/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -414,45 +540,66 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= -github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -468,32 +615,44 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -504,17 +663,21 @@ github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= @@ -522,6 +685,9 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -533,15 +699,19 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -549,6 +719,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -564,8 +736,7 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -573,8 +744,7 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -592,18 +762,18 @@ github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= -github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -611,9 +781,11 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -623,6 +795,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -646,6 +819,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -664,7 +838,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -674,16 +848,15 @@ github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzy github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= @@ -696,7 +869,10 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -713,8 +889,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -730,18 +906,18 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= -github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= +github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= +github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -749,12 +925,13 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= @@ -765,11 +942,15 @@ github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjc github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= -github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= +github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -780,20 +961,29 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 h1:O9XLFXGkVswDFmH9LaYpqu+r/AAFWqr0DL6V00KEVFg= +github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -806,12 +996,15 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -831,14 +1024,19 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -849,6 +1047,7 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -861,22 +1060,21 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -911,18 +1109,32 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -932,8 +1144,19 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -944,6 +1167,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -954,6 +1179,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -963,6 +1189,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -973,6 +1200,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -992,9 +1220,8 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1002,22 +1229,51 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= @@ -1030,13 +1286,18 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1061,7 +1322,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1090,11 +1351,26 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1115,12 +1391,36 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1129,6 +1429,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1136,6 +1437,7 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= @@ -1163,11 +1465,56 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b h1:SfSkJugek6xm7lWywqth4r2iTrYLpD8lOj1nMIIhMNM= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1180,15 +1527,19 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= @@ -1223,10 +1574,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 400eff8108496d9084288a02b399bcdb149c0d39 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 11 Nov 2022 09:55:43 +0100 Subject: [PATCH 019/294] Revert "Bump github.com/spf13/viper from 1.13.0 to 1.14.0 (#1082)" This reverts commit cf81eb8ea6828dd6b03a96ed166267cf64befc06. --- go.mod | 68 ++----- go.sum | 575 +++++++++++---------------------------------------------- 2 files changed, 127 insertions(+), 516 deletions(-) diff --git a/go.mod b/go.mod index 3a30b24408..9fc233ec7d 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.18 require ( github.com/CosmWasm/wasmvm v1.1.1 github.com/cosmos/cosmos-proto v1.0.0-alpha8 - github.com/cosmos/cosmos-sdk v0.46.1 + github.com/cosmos/cosmos-sdk v0.45.10 github.com/cosmos/gogoproto v1.4.2 github.com/cosmos/iavl v0.19.4 github.com/cosmos/ibc-go/v3 v3.3.1 - github.com/cosmos/interchain-accounts v0.4.0 + github.com/cosmos/interchain-accounts v0.1.0 github.com/dvsekhvalnov/jose2go v1.5.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 @@ -23,45 +23,33 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.5.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.14.0 - github.com/stretchr/testify v1.8.1 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/spf13/viper v1.13.0 + github.com/stretchr/testify v1.8.0 + github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca github.com/tendermint/tendermint v0.34.22 github.com/tendermint/tm-db v0.6.7 - google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e - google.golang.org/grpc v1.50.1 + google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b + google.golang.org/grpc v1.50.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.104.0 // indirect - cloud.google.com/go/compute v1.12.1 // indirect - cloud.google.com/go/compute/metadata v0.2.1 // indirect - cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/storage v1.23.0 // indirect - cosmossdk.io/errors v1.0.0-beta.7 // indirect - cosmossdk.io/math v1.0.0-beta.3 // indirect - filippo.io/edwards25519 v1.0.0-rc.1 // indirect + filippo.io/edwards25519 v1.0.0-beta.2 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect github.com/armon/go-metrics v0.4.0 // indirect - github.com/aws/aws-sdk-go v1.40.45 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/btcsuite/btcd v0.22.1 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect + github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect github.com/confio/ics23/go v0.7.0 // indirect github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 // indirect github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect @@ -73,39 +61,28 @@ require ( github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.6.0 // indirect - github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.6.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect + github.com/improbable-eng/grpc-web v0.14.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/lib/pq v1.10.6 // indirect @@ -116,8 +93,6 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -132,31 +107,24 @@ require ( github.com/rs/cors v1.8.2 // indirect github.com/rs/zerolog v1.27.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/spf13/afero v1.9.2 // indirect + github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/ulikunitz/xz v0.5.8 // indirect - github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect + github.com/zondax/hid v0.9.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect - golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect - golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect + golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect + golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect - golang.org/x/text v0.4.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.102.0 // indirect - google.golang.org/appengine v1.6.7 // indirect + golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 09f720ec87..b65bb5e76f 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,11 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -18,43 +16,14 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -65,36 +34,36 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0 h1:wWRIaDURQA8xxHguFCshYepGlrWIrbBnAmc7wfg07qY= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= -cosmossdk.io/math v1.0.0-beta.3 h1:TbZxSopz2LqjJ7aXYfn7nJSb8vNaBklW6BLpcei1qwM= -cosmossdk.io/math v1.0.0-beta.3/go.mod h1:3LYasri3Zna4XpbrTNdKsWmD5fHHkaNAod/mNT9XdE4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= -git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= +filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= +filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/CosmWasm/wasmvm v1.1.1 h1:0xtdrmmsP9fibe+x42WcMkp5aQ738BICgcH3FNVLzm4= github.com/CosmWasm/wasmvm v1.1.1/go.mod h1:ei0xpvomwSdONsxDuONzV7bL1jSET1M8brEx0FCXc+A= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -103,7 +72,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= +github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= @@ -112,18 +81,16 @@ github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1: github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -132,47 +99,29 @@ github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= +github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.40.45 h1:QN1nsY27ssD/JmW4s83qmSb+uL6DG4GmCDzjmJB4xUI= -github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -180,14 +129,9 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -195,26 +139,18 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= -github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= -github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= +github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= +github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -226,8 +162,8 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= -github.com/cosmos/cosmos-sdk v0.46.1 h1:7vUZXMyrmEb4xtBYpz1TobtrcnpgiZTi+tVjc0XWB4o= -github.com/cosmos/cosmos-sdk v0.46.1/go.mod h1:2+o8Qw8qnE02V+lQVZDJFQ8tri/hsiA5GmWaPERqVa0= +github.com/cosmos/cosmos-sdk v0.45.10 h1:YRf1N6C7OFCc8FJ5wuhcnDDySJNDn5DxSscVgbeXgz4= +github.com/cosmos/cosmos-sdk v0.45.10/go.mod h1:CbfWNs4PuxxsvRD/snQuSBDwIhtsD7rIDTVQyYMKTa0= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -241,10 +177,8 @@ github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-go/v3 v3.3.1 h1:i8o3iPSPN8fr7AjCPQnHEKz/VfeMrxc8mjvgAw6txWk= github.com/cosmos/ibc-go/v3 v3.3.1/go.mod h1:V1nliDk/5q5KWr0mup7M76oN4SY0IOU371SKbCV2wN0= -github.com/cosmos/ibc-go/v6 v6.0.0-alpha1 h1:FpmkSFqRGwFZPL4HNLJ0V2L4/ILyG+tcVy59+EBn7q4= -github.com/cosmos/ibc-go/v6 v6.0.0-alpha1/go.mod h1:F2p2yeQlr4+L/YslhlY+Rk1uHXAJ2yKPPo6/uDUsYpc= -github.com/cosmos/interchain-accounts v0.4.0 h1:EMkYnvh6xROqs86YVaUS5dL/Q8yS9W8AcOsMj94qoW8= -github.com/cosmos/interchain-accounts v0.4.0/go.mod h1:0n1OaiiqrVObeBTeC4Y67skKC5al46MPpiAZSQlHfok= +github.com/cosmos/interchain-accounts v0.1.0 h1:QmuwNsf1Hxl3P5GSGt7Z+JeuHPiZw4Z34R/038P5T6s= +github.com/cosmos/interchain-accounts v0.1.0/go.mod h1:Fv6LXDs+0ng4mIDVWwEJMXbAIMxY4kiq+A7Bw1Fb9AY= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= @@ -255,23 +189,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -279,60 +207,52 @@ github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70d github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= +github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -351,8 +271,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -360,9 +278,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -373,12 +290,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -386,17 +299,13 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -413,19 +322,18 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -434,25 +342,17 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -465,33 +365,12 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -502,11 +381,11 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= @@ -526,13 +405,8 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY= -github.com/hashicorp/go-getter v1.6.1/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -540,66 +414,45 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= -github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= +github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= +github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= -github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= +github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= +github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -615,44 +468,32 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -663,21 +504,17 @@ github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= @@ -685,9 +522,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -699,19 +533,15 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -719,8 +549,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -736,7 +564,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= +github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -744,7 +573,8 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -762,18 +592,18 @@ github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -781,11 +611,9 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -795,7 +623,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -819,7 +646,6 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -838,7 +664,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -848,15 +674,16 @@ github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzy github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= @@ -869,10 +696,7 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -889,8 +713,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -906,18 +730,18 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= -github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= +github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= +github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= +github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -925,13 +749,12 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= @@ -942,15 +765,11 @@ github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjc github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= -github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -961,29 +780,20 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= -github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 h1:O9XLFXGkVswDFmH9LaYpqu+r/AAFWqr0DL6V00KEVFg= -github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -996,15 +806,12 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1024,19 +831,14 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1047,7 +849,6 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1060,21 +861,22 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1109,32 +911,18 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1144,19 +932,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1167,8 +944,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1179,7 +954,6 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1189,7 +963,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1200,7 +973,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1220,8 +992,9 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1229,51 +1002,22 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= +golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= @@ -1286,18 +1030,13 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1322,7 +1061,7 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1351,26 +1090,11 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1391,36 +1115,12 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1429,7 +1129,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1437,7 +1136,6 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= @@ -1465,56 +1163,11 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b h1:SfSkJugek6xm7lWywqth4r2iTrYLpD8lOj1nMIIhMNM= +google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1527,19 +1180,15 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= @@ -1574,16 +1223,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 5c39daee99b838482ec1bdd980bfa0a56213ec34 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Fri, 11 Nov 2022 13:39:16 +0100 Subject: [PATCH 020/294] Contract authz - redesign (#1077) * Add contract authz proto * Implement contract autorization * Register contract authz * Add contract-authz tests * Consume gas for contract authz * Add contract authz cli * Update cli usage * Model spike * Add max funds limit * Redesign authz model * Start e2e test * Full e2e test * Test filter and limits * Test accept * Fix description * No linter warning Co-authored-by: Giancarlos Salas --- Makefile | 3 +- app/test_helpers.go | 10 +- docs/proto/proto-docs.md | 173 +++ proto/cosmwasm/wasm/v1/authz.proto | 109 ++ tests/e2e/README.md | 3 + tests/e2e/grants_test.go | 116 ++ x/wasm/client/cli/tx.go | 58 + x/wasm/ibctesting/chain.go | 41 +- x/wasm/ibctesting/faucet.go | 52 + x/wasm/relay_test.go | 4 +- x/wasm/types/authz.go | 534 ++++++++ x/wasm/types/authz.pb.go | 1865 ++++++++++++++++++++++++++++ x/wasm/types/authz_test.go | 728 +++++++++++ x/wasm/types/codec.go | 38 + x/wasm/types/errors.go | 12 +- x/wasm/types/json_matching.go | 24 +- x/wasm/types/json_matching_test.go | 81 +- x/wasm/types/query.pb.go | 6 +- x/wasm/types/tx.go | 36 + x/wasm/types/tx.pb.go | 6 +- 20 files changed, 3790 insertions(+), 109 deletions(-) create mode 100644 proto/cosmwasm/wasm/v1/authz.proto create mode 100644 tests/e2e/README.md create mode 100644 tests/e2e/grants_test.go create mode 100644 x/wasm/ibctesting/faucet.go create mode 100644 x/wasm/types/authz.go create mode 100644 x/wasm/types/authz.pb.go create mode 100644 x/wasm/types/authz_test.go diff --git a/Makefile b/Makefile index 6ca03f3e38..d85996fbe9 100644 --- a/Makefile +++ b/Makefile @@ -149,8 +149,9 @@ test-sim-multi-seed-short: runsim ############################################################################### format-tools: - go install mvdan.cc/gofumpt@v0.3.1 + go install mvdan.cc/gofumpt@v0.4.0 go install github.com/client9/misspell/cmd/misspell@v0.3.4 + go install golang.org/x/tools/cmd/goimports@latest lint: format-tools golangci-lint run --tests=false diff --git a/app/test_helpers.go b/app/test_helpers.go index ceff625168..d15e155560 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -363,7 +363,7 @@ func SignCheckDeliver( // ibc testing package causes checkState and deliverState to diverge in block time. func SignAndDeliver( t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, + chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey, ) (sdk.GasInfo, *sdk.Result, error) { tx, err := helpers.GenTx( txCfg, @@ -381,14 +381,6 @@ func SignAndDeliver( app.BeginBlock(abci.RequestBeginBlock{Header: header}) gInfo, res, err := app.Deliver(txCfg.TxEncoder(), tx) - if expPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - app.EndBlock(abci.RequestEndBlock{}) app.Commit() diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index fdf641c81a..dedd98bd21 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -4,6 +4,17 @@ ## Table of Contents +- [cosmwasm/wasm/v1/authz.proto](#cosmwasm/wasm/v1/authz.proto) + - [AcceptedMessageKeysFilter](#cosmwasm.wasm.v1.AcceptedMessageKeysFilter) + - [AcceptedMessagesFilter](#cosmwasm.wasm.v1.AcceptedMessagesFilter) + - [AllowAllMessagesFilter](#cosmwasm.wasm.v1.AllowAllMessagesFilter) + - [CombinedLimit](#cosmwasm.wasm.v1.CombinedLimit) + - [ContractExecutionAuthorization](#cosmwasm.wasm.v1.ContractExecutionAuthorization) + - [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) + - [ContractMigrationAuthorization](#cosmwasm.wasm.v1.ContractMigrationAuthorization) + - [MaxCallsLimit](#cosmwasm.wasm.v1.MaxCallsLimit) + - [MaxFundsLimit](#cosmwasm.wasm.v1.MaxFundsLimit) + - [cosmwasm/wasm/v1/types.proto](#cosmwasm/wasm/v1/types.proto) - [AbsoluteTxPosition](#cosmwasm.wasm.v1.AbsoluteTxPosition) - [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) @@ -90,6 +101,168 @@ + +

Top

+ +## cosmwasm/wasm/v1/authz.proto + + + + + +### AcceptedMessageKeysFilter +AcceptedMessageKeysFilter accept only the specific contract message keys in +the json object to be executed. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `keys` | [string](#string) | repeated | Messages is the list of unique keys | + + + + + + + + +### AcceptedMessagesFilter +AcceptedMessagesFilter accept only the specific raw contract messages to be +executed. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `messages` | [bytes](#bytes) | repeated | Messages is the list of raw contract messages | + + + + + + + + +### AllowAllMessagesFilter +AllowAllMessagesFilter is a wildcard to allow any type of contract payload +message. +Since: wasmd 0.30 + + + + + + + + +### CombinedLimit +CombinedLimit defines the maximal amounts that can be sent to a contract and +the maximal number of calls executable. Both need to remain >0 to be valid. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `calls_remaining` | [uint64](#uint64) | | Remaining number that is decremented on each execution | +| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amounts is the maximal amount of tokens transferable to the contract. | + + + + + + + + +### ContractExecutionAuthorization +ContractExecutionAuthorization defines authorization for wasm execute. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `grants` | [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) | repeated | Grants for contract executions | + + + + + + + + +### ContractGrant +ContractGrant a granted permission for a single contract +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract` | [string](#string) | | Contract is the bech32 address of the smart contract | +| `limit` | [google.protobuf.Any](#google.protobuf.Any) | | Limit defines execution limits that are enforced and updated when the grant is applied. When the limit lapsed the grant is removed. | +| `filter` | [google.protobuf.Any](#google.protobuf.Any) | | Filter define more fine-grained control on the message payload passed to the contract in the operation. When no filter applies on execution, the operation is prohibited. | + + + + + + + + +### ContractMigrationAuthorization +ContractMigrationAuthorization defines authorization for wasm contract +migration. Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `grants` | [ContractGrant](#cosmwasm.wasm.v1.ContractGrant) | repeated | Grants for contract migrations | + + + + + + + + +### MaxCallsLimit +MaxCallsLimit limited number of calls to the contract. No funds transferable. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `remaining` | [uint64](#uint64) | | Remaining number that is decremented on each execution | + + + + + + + + +### MaxFundsLimit +MaxFundsLimit defines the maximal amounts that can be sent to the contract. +Since: wasmd 0.30 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `amounts` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Amounts is the maximal amount of tokens transferable to the contract. | + + + + + + + + + + + + + + +

Top

diff --git a/proto/cosmwasm/wasm/v1/authz.proto b/proto/cosmwasm/wasm/v1/authz.proto new file mode 100644 index 0000000000..96ecbfb38d --- /dev/null +++ b/proto/cosmwasm/wasm/v1/authz.proto @@ -0,0 +1,109 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 +message ContractExecutionAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // Grants for contract executions + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. Since: wasmd 0.30 +message ContractMigrationAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // Grants for contract migrations + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +message ContractGrant { + // Contract is the bech32 address of the smart contract + string contract = 1; + + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + google.protobuf.Any limit = 2 + [ (cosmos_proto.accepts_interface) = "ContractAuthzLimitX" ]; + + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + google.protobuf.Any filter = 3 + [ (cosmos_proto.accepts_interface) = "ContractAuthzFilterX" ]; +} + +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +message MaxCallsLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 remaining = 1; +} + +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +message MaxFundsLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; + + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +message CombinedLimit { + option (cosmos_proto.implements_interface) = "ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 calls_remaining = 1; + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +message AllowAllMessagesFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; +} + +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 +message AcceptedMessageKeysFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; + + // Messages is the list of unique keys + repeated string keys = 1; +} + +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +message AcceptedMessagesFilter { + option (cosmos_proto.implements_interface) = "ContractAuthzFilterX"; + + // Messages is the list of raw contract messages + repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; +} diff --git a/tests/e2e/README.md b/tests/e2e/README.md new file mode 100644 index 0000000000..dae38fe2df --- /dev/null +++ b/tests/e2e/README.md @@ -0,0 +1,3 @@ +# End To End Testing - e2e + +Scenario tests that run against on or multiple chain instances. diff --git a/tests/e2e/grants_test.go b/tests/e2e/grants_test.go new file mode 100644 index 0000000000..0920fa0a3d --- /dev/null +++ b/tests/e2e/grants_test.go @@ -0,0 +1,116 @@ +package e2e_test + +import ( + "fmt" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/x/wasm/ibctesting" + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestGrants(t *testing.T) { + // Given a contract by address A + // And a grant for address B by A created + // When B sends an execute with tokens from A + // Then the grant is executed as defined + // And + // - balance A reduced (on success) + // - balance B not touched + + chain := ibctesting.NewCoordinator(t, 1).GetChain(ibctesting.GetChainID(0)) + codeID := chain.StoreCodeFile("../../x/wasm/keeper/testdata/reflect_1_1.wasm").CodeID + contractAddr := chain.InstantiateContract(codeID, []byte(`{}`)) + require.NotEmpty(t, contractAddr) + + granterAddr := chain.SenderAccount.GetAddress() + granteePrivKey := secp256k1.GenPrivKey() + granteeAddr := sdk.AccAddress(granteePrivKey.PubKey().Address().Bytes()) + otherPrivKey := secp256k1.GenPrivKey() + otherAddr := sdk.AccAddress(otherPrivKey.PubKey().Address().Bytes()) + + chain.Fund(granteeAddr, sdk.NewInt(1_000_000)) + chain.Fund(otherAddr, sdk.NewInt(1_000_000)) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + + myAmount := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2_000_000)) + + specs := map[string]struct { + limit types.ContractAuthzLimitX + filter types.ContractAuthzFilterX + transferAmount sdk.Coin + senderKey cryptotypes.PrivKey + expErr *sdkerrors.Error + }{ + "in limits and filter": { + limit: types.NewMaxFundsLimit(myAmount), + filter: types.NewAllowAllMessagesFilter(), + transferAmount: myAmount, + senderKey: granteePrivKey, + }, + "exceed limits": { + limit: types.NewMaxFundsLimit(myAmount), + filter: types.NewAllowAllMessagesFilter(), + transferAmount: myAmount.Add(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + senderKey: granteePrivKey, + expErr: sdkerrors.ErrUnauthorized, + }, + "not match filter": { + limit: types.NewMaxFundsLimit(myAmount), + filter: types.NewAcceptedMessageKeysFilter("foo"), + transferAmount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()), + senderKey: granteePrivKey, + expErr: sdkerrors.ErrUnauthorized, + }, + "non authorized sender address": { // sanity check - testing sdk + limit: types.NewMaxFundsLimit(myAmount), + filter: types.NewAllowAllMessagesFilter(), + senderKey: otherPrivKey, + transferAmount: myAmount, + expErr: sdkerrors.ErrUnauthorized, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + // setup grant + grant, err := types.NewContractGrant(contractAddr, spec.limit, spec.filter) + require.NoError(t, err) + authorization := types.NewContractExecutionAuthorization(*grant) + grantMsg, err := authz.NewMsgGrant(granterAddr, granteeAddr, authorization, time.Now().Add(time.Hour)) + require.NoError(t, err) + _, err = chain.SendMsgs(grantMsg) + require.NoError(t, err) + + granterStartBalance := chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount + + // when + anyValidReflectMsg := []byte(fmt.Sprintf(`{"reflect_msg": {"msgs": [{"bank":{"burn":{"amount":[{"denom":%q, "amount": %q}]}}}]}}`, sdk.DefaultBondDenom, myAmount.Amount.String())) + execMsg := authz.NewMsgExec(spec.senderKey.PubKey().Address().Bytes(), []sdk.Msg{&types.MsgExecuteContract{ + Sender: granterAddr.String(), + Contract: contractAddr.String(), + Msg: anyValidReflectMsg, + Funds: sdk.NewCoins(spec.transferAmount), + }}) + _, gotErr := chain.SendNonDefaultSenderMsgs(spec.senderKey, &execMsg) + + // then + if spec.expErr != nil { + require.ErrorIs(t, gotErr, spec.expErr) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + assert.Equal(t, granterStartBalance, chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount) + return + } + require.NoError(t, gotErr) + assert.Equal(t, sdk.NewInt(1_000_000), chain.Balance(granteeAddr, sdk.DefaultBondDenom).Amount) + assert.Equal(t, granterStartBalance.Sub(spec.transferAmount.Amount), chain.Balance(granterAddr, sdk.DefaultBondDenom).Amount) + }) + } +} diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 7e4c6e36f0..d8227f7cd3 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -32,6 +32,9 @@ const ( flagInstantiateByAddress = "instantiate-only-address" flagInstantiateByAnyOfAddress = "instantiate-anyof-addresses" flagUnpinCode = "unpin-code" + flagAllowedMsgs = "allow-msgs" + flagRunOnce = "run-once" + flagExpiration = "expiration" ) // GetTxCmd returns the transaction commands for this module @@ -52,6 +55,7 @@ func GetTxCmd() *cobra.Command { MigrateContractCmd(), UpdateContractAdminCmd(), ClearContractAdminCmd(), + GrantAuthorizationCmd(), ) return txCmd } @@ -377,3 +381,57 @@ func parseExecuteArgs(contractAddr string, execMsg string, sender sdk.AccAddress Msg: []byte(execMsg), }, nil } + +func GrantAuthorizationCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "grant [grantee] [contract_addr_bech32] --allow-msgs [msg1,msg2,...]", + Short: "Grant authorization to an address", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + grantee, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + contract, err := sdk.AccAddressFromBech32(args[1]) + if err != nil { + return err + } + + msgs, err := cmd.Flags().GetStringSlice(flagAllowedMsgs) + if err != nil { + return err + } + + once, err := cmd.Flags().GetBool(flagRunOnce) + if err != nil { + return err + } + + exp, err := cmd.Flags().GetInt64(flagExpiration) + if err != nil { + return err + } + if exp == 0 { + return errors.New("expiration must be set") + } + _ = clientCtx + _ = grantee + _ = msgs + _ = once + _ = contract + + return errors.New("not implemented") + }, + } + flags.AddTxFlagsToCmd(cmd) + cmd.Flags().StringSlice(flagAllowedMsgs, []string{}, "Allowed msgs") + cmd.Flags().Bool(flagRunOnce, false, "Allow to execute only once") + cmd.Flags().Int64(flagExpiration, 0, "The Unix timestamp.") + return cmd +} diff --git a/x/wasm/ibctesting/chain.go b/x/wasm/ibctesting/chain.go index 8d0adfb72a..fb24372d8a 100644 --- a/x/wasm/ibctesting/chain.go +++ b/x/wasm/ibctesting/chain.go @@ -145,7 +145,7 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { return chain.QueryProofAtHeight(key, chain.App.LastBlockHeight()) } -// QueryProof performs an abci query with the given key and returns the proto encoded merkle proof +// QueryProofAtHeight performs an abci query with the given key and returns the proto encoded merkle proof // for the query and the height at which the proof will succeed on a tendermint verifier. func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) { res := chain.App.Query(abci.RequestQuery{ @@ -251,50 +251,15 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { chain.ChainID, []uint64{chain.SenderAccount.GetAccountNumber()}, []uint64{chain.SenderAccount.GetSequence()}, - true, true, chain.SenderPrivKey, + chain.SenderPrivKey, ) - if err != nil { - return nil, err - } // SignAndDeliver calls app.Commit() chain.NextBlock() - - // increment sequence for successful transaction execution - err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) if err != nil { - return nil, err + return r, err } - chain.Coordinator.IncrementTime() - - chain.captureIBCEvents(r) - - return r, nil -} - -func (chain *TestChain) SendMsgsExpPass(expPass bool, msgs ...sdk.Msg) (*sdk.Result, error) { - // ensure the chain has the latest time - chain.Coordinator.UpdateTimeForChain(chain) - - _, r, err := app.SignAndDeliver( - chain.t, - chain.TxConfig, - chain.App.BaseApp, - chain.GetContext().BlockHeader(), - msgs, - chain.ChainID, - []uint64{chain.SenderAccount.GetAccountNumber()}, - []uint64{chain.SenderAccount.GetSequence()}, - true, expPass, chain.SenderPrivKey, - ) - if err != nil { - return nil, err - } - - // SignAndDeliver calls app.Commit() - chain.NextBlock() - // increment sequence for successful transaction execution err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) if err != nil { diff --git a/x/wasm/ibctesting/faucet.go b/x/wasm/ibctesting/faucet.go new file mode 100644 index 0000000000..d5098c34c8 --- /dev/null +++ b/x/wasm/ibctesting/faucet.go @@ -0,0 +1,52 @@ +package ibctesting + +import ( + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/app" +) + +// Fund an address with the given amount in default denom +func (chain *TestChain) Fund(addr sdk.AccAddress, amount sdk.Int) { + require.NoError(chain.t, chain.sendMsgs(&banktypes.MsgSend{ + FromAddress: chain.SenderAccount.GetAddress().String(), + ToAddress: addr.String(), + Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), + })) +} + +// SendNonDefaultSenderMsgs delivers a transaction through the application. It returns the result and error if one +// occurred. +func (chain *TestChain) SendNonDefaultSenderMsgs(senderPrivKey cryptotypes.PrivKey, msgs ...sdk.Msg) (*sdk.Result, error) { + require.NotEqual(chain.t, chain.SenderPrivKey, senderPrivKey, "use SendMsgs method") + + // ensure the chain has the latest time + chain.Coordinator.UpdateTimeForChain(chain) + + addr := sdk.AccAddress(senderPrivKey.PubKey().Address().Bytes()) + account := chain.App.AccountKeeper.GetAccount(chain.GetContext(), addr) + require.NotNil(chain.t, account) + _, r, err := app.SignAndDeliver( + chain.t, + chain.TxConfig, + chain.App.BaseApp, + chain.GetContext().BlockHeader(), + msgs, + chain.ChainID, + []uint64{account.GetAccountNumber()}, + []uint64{account.GetSequence()}, + senderPrivKey, + ) + + // SignAndDeliver calls app.Commit() + chain.NextBlock() + chain.Coordinator.IncrementTime() + if err != nil { + return r, err + } + chain.captureIBCEvents(r) + return r, nil +} diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index 7645f42365..4e72bd84f6 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -416,7 +416,7 @@ func TestContractEmulateIBCTransferMessageOnDiffContractIBCChannel(t *testing.T) }.GetBytes(), Funds: sdk.NewCoins(coinToSendToB), } - _, err := chainA.SendMsgsExpPass(false, startMsg) + _, err := chainA.SendMsgs(startMsg) require.Error(t, err) } @@ -519,7 +519,7 @@ func TestContractHandlesChannelCloseNotOwned(t *testing.T) { Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - _, err := chainA.SendMsgsExpPass(false, closeIBCChannelMsg) + _, err := chainA.SendMsgs(closeIBCChannelMsg) require.Error(t, err) } diff --git a/x/wasm/types/authz.go b/x/wasm/types/authz.go new file mode 100644 index 0000000000..10dd2606c9 --- /dev/null +++ b/x/wasm/types/authz.go @@ -0,0 +1,534 @@ +package types + +import ( + "strings" + + "github.com/gogo/protobuf/proto" + + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authztypes "github.com/cosmos/cosmos-sdk/x/authz" +) + +const gasDeserializationCostPerByte = uint64(1) + +var ( + _ authztypes.Authorization = &ContractExecutionAuthorization{} + _ authztypes.Authorization = &ContractMigrationAuthorization{} + _ cdctypes.UnpackInterfacesMessage = &ContractExecutionAuthorization{} + _ cdctypes.UnpackInterfacesMessage = &ContractMigrationAuthorization{} +) + +// AuthzableWasmMsg is abstract wasm tx message that is supported in authz +type AuthzableWasmMsg interface { + GetFunds() sdk.Coins + GetMsg() RawContractMessage + GetContract() string + ValidateBasic() error +} + +// NewContractExecutionAuthorization constructor +func NewContractExecutionAuthorization(grants ...ContractGrant) *ContractExecutionAuthorization { + return &ContractExecutionAuthorization{ + Grants: grants, + } +} + +// MsgTypeURL implements Authorization.MsgTypeURL. +func (a ContractExecutionAuthorization) MsgTypeURL() string { + return sdk.MsgTypeURL(&MsgExecuteContract{}) +} + +// NewAuthz factory method to create an Authorization with updated grants +func (a ContractExecutionAuthorization) NewAuthz(g []ContractGrant) authztypes.Authorization { + return NewContractExecutionAuthorization(g...) +} + +// Accept implements Authorization.Accept. +func (a *ContractExecutionAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { + return AcceptGrantedMessage[*MsgExecuteContract](ctx, a.Grants, msg, a) +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a ContractExecutionAuthorization) ValidateBasic() error { + return validateGrants(a.Grants) +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (a ContractExecutionAuthorization) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + for _, g := range a.Grants { + if err := g.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + +// NewContractMigrationAuthorization constructor +func NewContractMigrationAuthorization(grants ...ContractGrant) *ContractMigrationAuthorization { + return &ContractMigrationAuthorization{ + Grants: grants, + } +} + +// MsgTypeURL implements Authorization.MsgTypeURL. +func (a ContractMigrationAuthorization) MsgTypeURL() string { + return sdk.MsgTypeURL(&MsgMigrateContract{}) +} + +// Accept implements Authorization.Accept. +func (a *ContractMigrationAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) { + return AcceptGrantedMessage[*MsgMigrateContract](ctx, a.Grants, msg, a) +} + +// NewAuthz factory method to create an Authorization with updated grants +func (a ContractMigrationAuthorization) NewAuthz(g []ContractGrant) authztypes.Authorization { + return NewContractMigrationAuthorization(g...) +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a ContractMigrationAuthorization) ValidateBasic() error { + return validateGrants(a.Grants) +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (a ContractMigrationAuthorization) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + for _, g := range a.Grants { + if err := g.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + +func validateGrants(g []ContractGrant) error { + if len(g) == 0 { + return ErrEmpty.Wrap("grants") + } + for i, v := range g { + if err := v.ValidateBasic(); err != nil { + return sdkerrors.Wrapf(err, "position %d", i) + } + } + // allow multiple grants for a contract: + // contractA:doThis:1,doThat:* has with different counters for different methods + return nil +} + +// ContractAuthzFactory factory to create an updated Authorization object +type ContractAuthzFactory interface { + NewAuthz([]ContractGrant) authztypes.Authorization +} + +// AcceptGrantedMessage determines whether this grant permits the provided sdk.Msg to be performed, +// and if so provides an upgraded authorization instance. +func AcceptGrantedMessage[T AuthzableWasmMsg](ctx sdk.Context, grants []ContractGrant, msg sdk.Msg, factory ContractAuthzFactory) (authztypes.AcceptResponse, error) { + exec, ok := msg.(T) + if !ok { + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch") + } + if exec.GetMsg() == nil { + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("empty message") + } + if err := exec.ValidateBasic(); err != nil { + return authztypes.AcceptResponse{}, err + } + + // iterate though all grants + for i, g := range grants { + if g.Contract != exec.GetContract() { + continue + } + + // first check limits + result, err := g.GetLimit().Accept(ctx, exec) + switch { + case err != nil: + return authztypes.AcceptResponse{}, sdkerrors.Wrap(err, "limit") + case result == nil: // sanity check + return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("limit result must not be nil") + case !result.Accepted: + // not applicable, continue with next grant + continue + } + + // then check permission set + ok, err := g.GetFilter().Accept(ctx, exec.GetMsg()) + switch { + case err != nil: + return authztypes.AcceptResponse{}, sdkerrors.Wrap(err, "filter") + case !ok: + // no limit update and continue with next grant + continue + } + + // finally do limit state updates in result + switch { + case result.DeleteLimit: + updatedGrants := append(grants[0:i], grants[i+1:]...) //nolint:gocritic + if len(updatedGrants) == 0 { // remove when empty + return authztypes.AcceptResponse{Accept: true, Delete: true}, nil + } + newAuthz := factory.NewAuthz(updatedGrants) + if err := newAuthz.ValidateBasic(); err != nil { // sanity check + return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) + } + return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil + case result.UpdateLimit != nil: + obj, err := g.WithNewLimits(result.UpdateLimit) + if err != nil { + return authztypes.AcceptResponse{}, err + } + newAuthz := factory.NewAuthz(append(append(grants[0:i], *obj), grants[i+1:]...)) + if err := newAuthz.ValidateBasic(); err != nil { // sanity check + return authztypes.AcceptResponse{}, ErrInvalid.Wrapf("new grant state: %s", err) + } + return authztypes.AcceptResponse{Accept: true, Updated: newAuthz}, nil + default: // accepted without a limit state update + return authztypes.AcceptResponse{Accept: true}, nil + } + } + return authztypes.AcceptResponse{Accept: false}, nil +} + +// ContractAuthzLimitX define execution limits that are enforced and updated when the grant +// is applied. When the limit lapsed the grant is removed. +type ContractAuthzLimitX interface { + Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) + ValidateBasic() error +} + +// ContractAuthzLimitAcceptResult result of the ContractAuthzLimitX.Accept method +type ContractAuthzLimitAcceptResult struct { + // Accepted is true when limit applies + Accepted bool + // DeleteLimit when set it is the end of life for this limit. Grant is removed from persistent store + DeleteLimit bool + // UpdateLimit update persistent state with new value + UpdateLimit ContractAuthzLimitX +} + +// ContractAuthzFilterX define more fine-grained control on the message payload passed +// to the contract in the operation. When no filter applies on execution, the +// operation is prohibited. +type ContractAuthzFilterX interface { + // Accept returns applicable or error + Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) + ValidateBasic() error +} + +var _ cdctypes.UnpackInterfacesMessage = &ContractGrant{} + +// NewContractGrant constructor +func NewContractGrant(contract sdk.AccAddress, limit ContractAuthzLimitX, filter ContractAuthzFilterX) (*ContractGrant, error) { + pFilter, ok := filter.(proto.Message) + if !ok { + return nil, sdkerrors.ErrInvalidType.Wrap("filter is not a proto type") + } + anyFilter, err := cdctypes.NewAnyWithValue(pFilter) + if err != nil { + return nil, sdkerrors.Wrap(err, "filter") + } + return ContractGrant{ + Contract: contract.String(), + Filter: anyFilter, + }.WithNewLimits(limit) +} + +// WithNewLimits factory method to create a new grant with given limit +func (g ContractGrant) WithNewLimits(limit ContractAuthzLimitX) (*ContractGrant, error) { + pLimit, ok := limit.(proto.Message) + if !ok { + return nil, sdkerrors.ErrInvalidType.Wrap("limit is not a proto type") + } + anyLimit, err := cdctypes.NewAnyWithValue(pLimit) + if err != nil { + return nil, sdkerrors.Wrap(err, "limit") + } + + return &ContractGrant{ + Contract: g.Contract, + Limit: anyLimit, + Filter: g.Filter, + }, nil +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (g ContractGrant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error { + var f ContractAuthzFilterX + if err := unpacker.UnpackAny(g.Filter, &f); err != nil { + return sdkerrors.Wrap(err, "filter") + } + var l ContractAuthzLimitX + if err := unpacker.UnpackAny(g.Limit, &l); err != nil { + return sdkerrors.Wrap(err, "limit") + } + return nil +} + +// GetLimit returns the cached value from the ContractGrant.Limit if present. +func (g ContractGrant) GetLimit() ContractAuthzLimitX { + if g.Limit == nil { + return &UndefinedLimit{} + } + a, ok := g.Limit.GetCachedValue().(ContractAuthzLimitX) + if !ok { + return &UndefinedLimit{} + } + return a +} + +// GetFilter returns the cached value from the ContractGrant.Filter if present. +func (g ContractGrant) GetFilter() ContractAuthzFilterX { + if g.Filter == nil { + return &UndefinedFilter{} + } + a, ok := g.Filter.GetCachedValue().(ContractAuthzFilterX) + if !ok { + return &UndefinedFilter{} + } + return a +} + +// ValidateBasic validates the grant +func (g ContractGrant) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(g.Contract); err != nil { + return sdkerrors.Wrap(err, "contract") + } + // execution limits + if err := g.GetLimit().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "limit") + } + // filter + if err := g.GetFilter().ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "filter") + } + return nil +} + +// UndefinedFilter null object that is always rejected in execution +type UndefinedFilter struct{} + +// Accept always returns error +func (f *UndefinedFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + return false, sdkerrors.ErrNotFound.Wrapf("undefined filter") +} + +// ValidateBasic always returns error +func (f UndefinedFilter) ValidateBasic() error { + return sdkerrors.ErrInvalidType.Wrapf("undefined filter") +} + +// NewAllowAllMessagesFilter constructor +func NewAllowAllMessagesFilter() *AllowAllMessagesFilter { + return &AllowAllMessagesFilter{} +} + +// Accept accepts any valid json message content. +func (f *AllowAllMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + return true, msg.ValidateBasic() +} + +// ValidateBasic returns always nil +func (f AllowAllMessagesFilter) ValidateBasic() error { + return nil +} + +// NewAcceptedMessageKeysFilter constructor +func NewAcceptedMessageKeysFilter(acceptedKeys ...string) *AcceptedMessageKeysFilter { + return &AcceptedMessageKeysFilter{Keys: acceptedKeys} +} + +// Accept only payload messages which contain one of the accepted key names in the json object. +func (f *AcceptedMessageKeysFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + gasForDeserialization := gasDeserializationCostPerByte * uint64(len(msg)) + ctx.GasMeter().ConsumeGas(gasForDeserialization, "contract authorization") + + ok, err := isJSONObjectWithTopLevelKey(msg, f.Keys) + if err != nil { + return false, sdkerrors.ErrUnauthorized.Wrapf("not an allowed msg: %s", err.Error()) + } + return ok, nil +} + +// ValidateBasic validates the filter +func (f AcceptedMessageKeysFilter) ValidateBasic() error { + if len(f.Keys) == 0 { + return ErrEmpty.Wrap("keys") + } + idx := make(map[string]struct{}, len(f.Keys)) + for _, m := range f.Keys { + if m == "" { + return ErrEmpty.Wrap("key") + } + if m != strings.TrimSpace(m) { + return ErrInvalid.Wrapf("key %q contains whitespaces", m) + } + if _, exists := idx[m]; exists { + return ErrDuplicate.Wrapf("key %q", m) + } + idx[m] = struct{}{} + } + return nil +} + +// NewAcceptedMessagesFilter constructor +func NewAcceptedMessagesFilter(msgs ...RawContractMessage) *AcceptedMessagesFilter { + return &AcceptedMessagesFilter{Messages: msgs} +} + +// Accept only payload messages which are equal to the granted one. +func (f *AcceptedMessagesFilter) Accept(ctx sdk.Context, msg RawContractMessage) (bool, error) { + for _, v := range f.Messages { + if v.Equal(msg) { + return true, nil + } + } + return false, nil +} + +// ValidateBasic validates the filter +func (f AcceptedMessagesFilter) ValidateBasic() error { + if len(f.Messages) == 0 { + return ErrEmpty.Wrap("messages") + } + idx := make(map[string]struct{}, len(f.Messages)) + for _, m := range f.Messages { + if len(m) == 0 { + return ErrEmpty.Wrap("message") + } + if err := m.ValidateBasic(); err != nil { + return err + } + if _, exists := idx[string(m)]; exists { + return ErrDuplicate.Wrap("message") + } + idx[string(m)] = struct{}{} + } + return nil +} + +var ( + _ ContractAuthzLimitX = &UndefinedLimit{} + _ ContractAuthzLimitX = &MaxCallsLimit{} + _ ContractAuthzLimitX = &MaxFundsLimit{} + _ ContractAuthzLimitX = &CombinedLimit{} +) + +// UndefinedLimit null object that is always rejected in execution +type UndefinedLimit struct{} + +// ValidateBasic always returns error +func (u UndefinedLimit) ValidateBasic() error { + return sdkerrors.ErrInvalidType.Wrapf("undefined limit") +} + +// Accept always returns error +func (u UndefinedLimit) Accept(ctx sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + return nil, sdkerrors.ErrNotFound.Wrapf("undefined filter") +} + +// NewMaxCallsLimit constructor +func NewMaxCallsLimit(number uint64) *MaxCallsLimit { + return &MaxCallsLimit{Remaining: number} +} + +// Accept only the defined number of message calls. No token transfers to the contract allowed. +func (m MaxCallsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + if !msg.GetFunds().Empty() { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil + } + switch n := m.Remaining; n { + case 0: // sanity check + return nil, sdkerrors.ErrUnauthorized.Wrap("no calls left") + case 1: + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + default: + return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &MaxCallsLimit{Remaining: n - 1}}, nil + } +} + +// ValidateBasic validates the limit +func (m MaxCallsLimit) ValidateBasic() error { + if m.Remaining == 0 { + return ErrEmpty.Wrap("remaining calls") + } + return nil +} + +// NewMaxFundsLimit constructor +// A panic will occur if the coin set is not valid. +func NewMaxFundsLimit(max ...sdk.Coin) *MaxFundsLimit { + return &MaxFundsLimit{Amounts: sdk.NewCoins(max...)} +} + +// Accept until the defined budget for token transfers to the contract is spent +func (m MaxFundsLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + if msg.GetFunds().Empty() { // no state changes required + return &ContractAuthzLimitAcceptResult{Accepted: true}, nil + } + if !msg.GetFunds().IsAllLTE(m.Amounts) { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil + } + newAmounts := m.Amounts.Sub(msg.GetFunds()) + if newAmounts.IsZero() { + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + } + return &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: &MaxFundsLimit{Amounts: newAmounts}}, nil +} + +// ValidateBasic validates the limit +func (m MaxFundsLimit) ValidateBasic() error { + if err := m.Amounts.Validate(); err != nil { + return err + } + if m.Amounts.IsZero() { + return ErrEmpty.Wrap("amounts") + } + return nil +} + +// NewCombinedLimit constructor +// A panic will occur if the coin set is not valid. +func NewCombinedLimit(maxCalls uint64, maxAmounts ...sdk.Coin) *CombinedLimit { + return &CombinedLimit{CallsRemaining: maxCalls, Amounts: sdk.NewCoins(maxAmounts...)} +} + +// Accept until the max calls is reached or the token budget is spent. +func (l CombinedLimit) Accept(_ sdk.Context, msg AuthzableWasmMsg) (*ContractAuthzLimitAcceptResult, error) { + transferFunds := msg.GetFunds() + if !transferFunds.IsAllLTE(l.Amounts) { + return &ContractAuthzLimitAcceptResult{Accepted: false}, nil // does not apply + } + switch n := l.CallsRemaining; n { + case 0: // sanity check + return nil, sdkerrors.ErrUnauthorized.Wrap("no calls left") + case 1: + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + default: + remainingAmounts := l.Amounts.Sub(transferFunds) + if remainingAmounts.IsZero() { + return &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, nil + } + return &ContractAuthzLimitAcceptResult{ + Accepted: true, + UpdateLimit: NewCombinedLimit(n-1, remainingAmounts...), + }, nil + } +} + +// ValidateBasic validates the limit +func (l CombinedLimit) ValidateBasic() error { + if l.CallsRemaining == 0 { + return ErrEmpty.Wrap("remaining calls") + } + if l.Amounts.IsZero() { + return ErrEmpty.Wrap("amounts") + } + if err := l.Amounts.Validate(); err != nil { + return sdkerrors.Wrap(err, "amounts") + } + return nil +} diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go new file mode 100644 index 0000000000..549b558aa1 --- /dev/null +++ b/x/wasm/types/authz.pb.go @@ -0,0 +1,1865 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmwasm/wasm/v1/authz.proto + +package types + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types1 "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +var ( + _ = fmt.Errorf + _ = math.Inf +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 +type ContractExecutionAuthorization struct { + // Grants for contract executions + Grants []ContractGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` +} + +func (m *ContractExecutionAuthorization) Reset() { *m = ContractExecutionAuthorization{} } +func (m *ContractExecutionAuthorization) String() string { return proto.CompactTextString(m) } +func (*ContractExecutionAuthorization) ProtoMessage() {} +func (*ContractExecutionAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{0} +} + +func (m *ContractExecutionAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractExecutionAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractExecutionAuthorization.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractExecutionAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractExecutionAuthorization.Merge(m, src) +} + +func (m *ContractExecutionAuthorization) XXX_Size() int { + return m.Size() +} + +func (m *ContractExecutionAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_ContractExecutionAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractExecutionAuthorization proto.InternalMessageInfo + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. Since: wasmd 0.30 +type ContractMigrationAuthorization struct { + // Grants for contract migrations + Grants []ContractGrant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants"` +} + +func (m *ContractMigrationAuthorization) Reset() { *m = ContractMigrationAuthorization{} } +func (m *ContractMigrationAuthorization) String() string { return proto.CompactTextString(m) } +func (*ContractMigrationAuthorization) ProtoMessage() {} +func (*ContractMigrationAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{1} +} + +func (m *ContractMigrationAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractMigrationAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractMigrationAuthorization.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractMigrationAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractMigrationAuthorization.Merge(m, src) +} + +func (m *ContractMigrationAuthorization) XXX_Size() int { + return m.Size() +} + +func (m *ContractMigrationAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_ContractMigrationAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractMigrationAuthorization proto.InternalMessageInfo + +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +type ContractGrant struct { + // Contract is the bech32 address of the smart contract + Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + Limit *types.Any `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + Filter *types.Any `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (m *ContractGrant) Reset() { *m = ContractGrant{} } +func (m *ContractGrant) String() string { return proto.CompactTextString(m) } +func (*ContractGrant) ProtoMessage() {} +func (*ContractGrant) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{2} +} + +func (m *ContractGrant) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *ContractGrant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractGrant.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *ContractGrant) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractGrant.Merge(m, src) +} + +func (m *ContractGrant) XXX_Size() int { + return m.Size() +} + +func (m *ContractGrant) XXX_DiscardUnknown() { + xxx_messageInfo_ContractGrant.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractGrant proto.InternalMessageInfo + +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +type MaxCallsLimit struct { + // Remaining number that is decremented on each execution + Remaining uint64 `protobuf:"varint,1,opt,name=remaining,proto3" json:"remaining,omitempty"` +} + +func (m *MaxCallsLimit) Reset() { *m = MaxCallsLimit{} } +func (m *MaxCallsLimit) String() string { return proto.CompactTextString(m) } +func (*MaxCallsLimit) ProtoMessage() {} +func (*MaxCallsLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{3} +} + +func (m *MaxCallsLimit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MaxCallsLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaxCallsLimit.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MaxCallsLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxCallsLimit.Merge(m, src) +} + +func (m *MaxCallsLimit) XXX_Size() int { + return m.Size() +} + +func (m *MaxCallsLimit) XXX_DiscardUnknown() { + xxx_messageInfo_MaxCallsLimit.DiscardUnknown(m) +} + +var xxx_messageInfo_MaxCallsLimit proto.InternalMessageInfo + +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +type MaxFundsLimit struct { + // Amounts is the maximal amount of tokens transferable to the contract. + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` +} + +func (m *MaxFundsLimit) Reset() { *m = MaxFundsLimit{} } +func (m *MaxFundsLimit) String() string { return proto.CompactTextString(m) } +func (*MaxFundsLimit) ProtoMessage() {} +func (*MaxFundsLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{4} +} + +func (m *MaxFundsLimit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MaxFundsLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaxFundsLimit.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MaxFundsLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxFundsLimit.Merge(m, src) +} + +func (m *MaxFundsLimit) XXX_Size() int { + return m.Size() +} + +func (m *MaxFundsLimit) XXX_DiscardUnknown() { + xxx_messageInfo_MaxFundsLimit.DiscardUnknown(m) +} + +var xxx_messageInfo_MaxFundsLimit proto.InternalMessageInfo + +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +type CombinedLimit struct { + // Remaining number that is decremented on each execution + CallsRemaining uint64 `protobuf:"varint,1,opt,name=calls_remaining,json=callsRemaining,proto3" json:"calls_remaining,omitempty"` + // Amounts is the maximal amount of tokens transferable to the contract. + Amounts github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,2,rep,name=amounts,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amounts"` +} + +func (m *CombinedLimit) Reset() { *m = CombinedLimit{} } +func (m *CombinedLimit) String() string { return proto.CompactTextString(m) } +func (*CombinedLimit) ProtoMessage() {} +func (*CombinedLimit) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{5} +} + +func (m *CombinedLimit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *CombinedLimit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CombinedLimit.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *CombinedLimit) XXX_Merge(src proto.Message) { + xxx_messageInfo_CombinedLimit.Merge(m, src) +} + +func (m *CombinedLimit) XXX_Size() int { + return m.Size() +} + +func (m *CombinedLimit) XXX_DiscardUnknown() { + xxx_messageInfo_CombinedLimit.DiscardUnknown(m) +} + +var xxx_messageInfo_CombinedLimit proto.InternalMessageInfo + +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +type AllowAllMessagesFilter struct{} + +func (m *AllowAllMessagesFilter) Reset() { *m = AllowAllMessagesFilter{} } +func (m *AllowAllMessagesFilter) String() string { return proto.CompactTextString(m) } +func (*AllowAllMessagesFilter) ProtoMessage() {} +func (*AllowAllMessagesFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{6} +} + +func (m *AllowAllMessagesFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AllowAllMessagesFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AllowAllMessagesFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *AllowAllMessagesFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AllowAllMessagesFilter.Merge(m, src) +} + +func (m *AllowAllMessagesFilter) XXX_Size() int { + return m.Size() +} + +func (m *AllowAllMessagesFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AllowAllMessagesFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AllowAllMessagesFilter proto.InternalMessageInfo + +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 +type AcceptedMessageKeysFilter struct { + // Messages is the list of unique keys + Keys []string `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (m *AcceptedMessageKeysFilter) Reset() { *m = AcceptedMessageKeysFilter{} } +func (m *AcceptedMessageKeysFilter) String() string { return proto.CompactTextString(m) } +func (*AcceptedMessageKeysFilter) ProtoMessage() {} +func (*AcceptedMessageKeysFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{7} +} + +func (m *AcceptedMessageKeysFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AcceptedMessageKeysFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AcceptedMessageKeysFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *AcceptedMessageKeysFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AcceptedMessageKeysFilter.Merge(m, src) +} + +func (m *AcceptedMessageKeysFilter) XXX_Size() int { + return m.Size() +} + +func (m *AcceptedMessageKeysFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AcceptedMessageKeysFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AcceptedMessageKeysFilter proto.InternalMessageInfo + +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +type AcceptedMessagesFilter struct { + // Messages is the list of raw contract messages + Messages []RawContractMessage `protobuf:"bytes,1,rep,name=messages,proto3,casttype=RawContractMessage" json:"messages,omitempty"` +} + +func (m *AcceptedMessagesFilter) Reset() { *m = AcceptedMessagesFilter{} } +func (m *AcceptedMessagesFilter) String() string { return proto.CompactTextString(m) } +func (*AcceptedMessagesFilter) ProtoMessage() {} +func (*AcceptedMessagesFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_36ff3a20cf32b258, []int{8} +} + +func (m *AcceptedMessagesFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *AcceptedMessagesFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AcceptedMessagesFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *AcceptedMessagesFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AcceptedMessagesFilter.Merge(m, src) +} + +func (m *AcceptedMessagesFilter) XXX_Size() int { + return m.Size() +} + +func (m *AcceptedMessagesFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AcceptedMessagesFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AcceptedMessagesFilter proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ContractExecutionAuthorization)(nil), "cosmwasm.wasm.v1.ContractExecutionAuthorization") + proto.RegisterType((*ContractMigrationAuthorization)(nil), "cosmwasm.wasm.v1.ContractMigrationAuthorization") + proto.RegisterType((*ContractGrant)(nil), "cosmwasm.wasm.v1.ContractGrant") + proto.RegisterType((*MaxCallsLimit)(nil), "cosmwasm.wasm.v1.MaxCallsLimit") + proto.RegisterType((*MaxFundsLimit)(nil), "cosmwasm.wasm.v1.MaxFundsLimit") + proto.RegisterType((*CombinedLimit)(nil), "cosmwasm.wasm.v1.CombinedLimit") + proto.RegisterType((*AllowAllMessagesFilter)(nil), "cosmwasm.wasm.v1.AllowAllMessagesFilter") + proto.RegisterType((*AcceptedMessageKeysFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessageKeysFilter") + proto.RegisterType((*AcceptedMessagesFilter)(nil), "cosmwasm.wasm.v1.AcceptedMessagesFilter") +} + +func init() { proto.RegisterFile("cosmwasm/wasm/v1/authz.proto", fileDescriptor_36ff3a20cf32b258) } + +var fileDescriptor_36ff3a20cf32b258 = []byte{ + // 578 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x4d, 0x8f, 0xd2, 0x40, + 0x18, 0xa6, 0xbb, 0x2b, 0x2e, 0xb3, 0xe2, 0x47, 0x25, 0x08, 0x64, 0x53, 0x08, 0x07, 0xe5, 0x42, + 0x2b, 0x78, 0x23, 0xf1, 0x00, 0x28, 0xc6, 0x28, 0x97, 0x5e, 0xdc, 0x78, 0xd9, 0x4c, 0xcb, 0x50, + 0x26, 0xdb, 0x76, 0x48, 0x67, 0xca, 0xd7, 0x9f, 0xd0, 0xdf, 0xe1, 0x99, 0x83, 0x3f, 0x81, 0x70, + 0xda, 0xa3, 0xa7, 0x55, 0xe1, 0x5f, 0x78, 0x32, 0x9d, 0x99, 0xb2, 0x40, 0xc2, 0x1e, 0xf5, 0x52, + 0xe6, 0xfd, 0x78, 0x9e, 0xf7, 0x99, 0xf7, 0x7d, 0x19, 0x70, 0x6e, 0x13, 0xea, 0x8d, 0x21, 0xf5, + 0x0c, 0xfe, 0x19, 0xd5, 0x0c, 0x18, 0xb2, 0xc1, 0x4c, 0x1f, 0x06, 0x84, 0x11, 0xf5, 0x71, 0x1c, + 0xd5, 0xf9, 0x67, 0x54, 0x2b, 0x64, 0x1c, 0xe2, 0x10, 0x1e, 0x34, 0xa2, 0x93, 0xc8, 0x2b, 0xe4, + 0xa3, 0x3c, 0x42, 0x2f, 0x45, 0x40, 0x18, 0x32, 0xa4, 0x09, 0xcb, 0xb0, 0x20, 0x45, 0xc6, 0xa8, + 0x66, 0x21, 0x06, 0x6b, 0x86, 0x4d, 0xb0, 0x1f, 0x43, 0x1d, 0x42, 0x1c, 0x17, 0x19, 0xdc, 0xb2, + 0xc2, 0xbe, 0x01, 0xfd, 0xa9, 0x08, 0x95, 0x03, 0xa0, 0xb5, 0x89, 0xcf, 0x02, 0x68, 0xb3, 0xb7, + 0x13, 0x64, 0x87, 0x0c, 0x13, 0xbf, 0x19, 0xb2, 0x01, 0x09, 0xf0, 0x0c, 0x46, 0x86, 0xfa, 0x1a, + 0x24, 0x9d, 0x00, 0xfa, 0x8c, 0xe6, 0x94, 0xd2, 0x71, 0xe5, 0xac, 0x5e, 0xd4, 0xf7, 0x05, 0xeb, + 0x31, 0xc3, 0xbb, 0x28, 0xaf, 0x75, 0xb2, 0xb8, 0x29, 0x26, 0x4c, 0x09, 0x6a, 0x3c, 0x59, 0xce, + 0xab, 0xe9, 0x1d, 0xc6, 0xed, 0x9a, 0x5d, 0xec, 0x04, 0xf0, 0x5f, 0xd4, 0xfc, 0xae, 0x80, 0xf4, + 0x0e, 0x44, 0x2d, 0x80, 0x53, 0x5b, 0x3a, 0x72, 0x4a, 0x49, 0xa9, 0xa4, 0xcc, 0x8d, 0xad, 0xb6, + 0xc1, 0x3d, 0x17, 0x7b, 0x98, 0xe5, 0x8e, 0x4a, 0x4a, 0xe5, 0xac, 0x9e, 0xd1, 0x45, 0x03, 0xf5, + 0xb8, 0x81, 0x7a, 0xd3, 0x9f, 0xb6, 0x9e, 0x2d, 0xe7, 0xd5, 0xa7, 0x31, 0x67, 0x54, 0x6d, 0xf6, + 0x31, 0xc2, 0x5c, 0x98, 0x02, 0xab, 0x76, 0x40, 0xb2, 0x8f, 0x5d, 0x86, 0x82, 0xdc, 0xf1, 0x1d, + 0x2c, 0xb9, 0xe5, 0xbc, 0x9a, 0xd9, 0x61, 0xe9, 0x70, 0xd0, 0x85, 0x29, 0xd1, 0xe5, 0x0e, 0x48, + 0x77, 0xe1, 0xa4, 0x0d, 0x5d, 0x97, 0xf2, 0x02, 0xea, 0x39, 0x48, 0x05, 0xc8, 0x83, 0xd8, 0xc7, + 0xbe, 0xc3, 0xa5, 0x9f, 0x98, 0xb7, 0x8e, 0xc6, 0x21, 0x59, 0xe5, 0x2f, 0x0a, 0x27, 0xea, 0x84, + 0x7e, 0x4f, 0x12, 0x21, 0x70, 0x1f, 0x7a, 0x24, 0xbc, 0xed, 0x73, 0x5e, 0x97, 0x7b, 0x15, 0x6d, + 0x92, 0x2e, 0x37, 0x49, 0x6f, 0x13, 0xec, 0xb7, 0x5e, 0x46, 0x1d, 0xfe, 0xf6, 0xb3, 0x58, 0x71, + 0x30, 0x1b, 0x84, 0x96, 0x6e, 0x13, 0x4f, 0x2e, 0xa1, 0xfc, 0xa9, 0xd2, 0xde, 0x95, 0xc1, 0xa6, + 0x43, 0x44, 0x39, 0x80, 0x9a, 0x31, 0xf7, 0x61, 0x45, 0x62, 0x28, 0x9e, 0x85, 0x7d, 0xd4, 0x13, + 0x8a, 0x5e, 0x80, 0x47, 0x76, 0x74, 0xd1, 0xcb, 0xfd, 0x0b, 0x3e, 0xe4, 0x6e, 0x33, 0xf6, 0x6e, + 0x4b, 0x3f, 0xfa, 0x1f, 0xd2, 0xeb, 0x20, 0xdb, 0x74, 0x5d, 0x32, 0x6e, 0xba, 0x6e, 0x17, 0x51, + 0x0a, 0x1d, 0x44, 0xc5, 0xdc, 0x1a, 0x07, 0x07, 0x5a, 0x7e, 0x0f, 0xf2, 0x4d, 0xdb, 0x46, 0x43, + 0x86, 0x7a, 0x12, 0xf3, 0x01, 0x4d, 0x25, 0x4c, 0x55, 0xc1, 0xc9, 0x15, 0x9a, 0x8a, 0x41, 0xa4, + 0x4c, 0x7e, 0xbe, 0x83, 0xaa, 0x0f, 0xb2, 0x7b, 0x54, 0x31, 0x4f, 0x1d, 0x9c, 0x7a, 0xd2, 0xc3, + 0xb9, 0x1e, 0xb4, 0xb2, 0x7f, 0x6e, 0x8a, 0xaa, 0x09, 0xc7, 0x9b, 0xff, 0x9c, 0x08, 0x9b, 0x9b, + 0xbc, 0xc3, 0x75, 0x5a, 0x6f, 0x16, 0xbf, 0xb5, 0xc4, 0x62, 0xa5, 0x29, 0xd7, 0x2b, 0x4d, 0xf9, + 0xb5, 0xd2, 0x94, 0xaf, 0x6b, 0x2d, 0x71, 0xbd, 0xd6, 0x12, 0x3f, 0xd6, 0x5a, 0xe2, 0xf3, 0xf3, + 0xad, 0x86, 0xb6, 0x09, 0xf5, 0x3e, 0xc5, 0x6f, 0x5c, 0xcf, 0x98, 0x88, 0xb7, 0x8e, 0x37, 0xd5, + 0x4a, 0xf2, 0x8d, 0x7f, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0x13, 0xc8, 0x1d, 0x99, 0x09, 0x05, + 0x00, 0x00, +} + +func (m *ContractExecutionAuthorization) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractExecutionAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractExecutionAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Grants) > 0 { + for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ContractMigrationAuthorization) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractMigrationAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractMigrationAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Grants) > 0 { + for iNdEx := len(m.Grants) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Grants[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ContractGrant) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ContractGrant) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Filter != nil { + { + size, err := m.Filter.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Limit != nil { + { + size, err := m.Limit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MaxCallsLimit) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaxCallsLimit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaxCallsLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Remaining != 0 { + i = encodeVarintAuthz(dAtA, i, uint64(m.Remaining)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MaxFundsLimit) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaxFundsLimit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaxFundsLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *CombinedLimit) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CombinedLimit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CombinedLimit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Amounts) > 0 { + for iNdEx := len(m.Amounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Amounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.CallsRemaining != 0 { + i = encodeVarintAuthz(dAtA, i, uint64(m.CallsRemaining)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AllowAllMessagesFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AllowAllMessagesFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AllowAllMessagesFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *AcceptedMessageKeysFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AcceptedMessageKeysFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AcceptedMessageKeysFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Keys) > 0 { + for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Keys[iNdEx]) + copy(dAtA[i:], m.Keys[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Keys[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AcceptedMessagesFilter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AcceptedMessagesFilter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AcceptedMessagesFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Messages[iNdEx]) + copy(dAtA[i:], m.Messages[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.Messages[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthz(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} + +func (m *ContractExecutionAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Grants) > 0 { + for _, e := range m.Grants { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *ContractMigrationAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Grants) > 0 { + for _, e := range m.Grants { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *ContractGrant) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + if m.Limit != nil { + l = m.Limit.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + if m.Filter != nil { + l = m.Filter.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + return n +} + +func (m *MaxCallsLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Remaining != 0 { + n += 1 + sovAuthz(uint64(m.Remaining)) + } + return n +} + +func (m *MaxFundsLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *CombinedLimit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CallsRemaining != 0 { + n += 1 + sovAuthz(uint64(m.CallsRemaining)) + } + if len(m.Amounts) > 0 { + for _, e := range m.Amounts { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *AllowAllMessagesFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *AcceptedMessageKeysFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Keys) > 0 { + for _, s := range m.Keys { + l = len(s) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *AcceptedMessagesFilter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, b := range m.Messages { + l = len(b) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func sovAuthz(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} + +func sozAuthz(x uint64) (n int) { + return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func (m *ContractExecutionAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractExecutionAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractExecutionAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Grants = append(m.Grants, ContractGrant{}) + if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *ContractMigrationAuthorization) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractMigrationAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractMigrationAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Grants", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Grants = append(m.Grants, ContractGrant{}) + if err := m.Grants[len(m.Grants)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *ContractGrant) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ContractGrant: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractGrant: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Limit == nil { + m.Limit = &types.Any{} + } + if err := m.Limit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Filter == nil { + m.Filter = &types.Any{} + } + if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *MaxCallsLimit) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MaxCallsLimit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MaxCallsLimit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Remaining", wireType) + } + m.Remaining = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Remaining |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *MaxFundsLimit) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MaxFundsLimit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MaxFundsLimit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amounts = append(m.Amounts, types1.Coin{}) + if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *CombinedLimit) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CombinedLimit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CombinedLimit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CallsRemaining", wireType) + } + m.CallsRemaining = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CallsRemaining |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amounts = append(m.Amounts, types1.Coin{}) + if err := m.Amounts[len(m.Amounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AllowAllMessagesFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllowAllMessagesFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllowAllMessagesFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AcceptedMessageKeysFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AcceptedMessageKeysFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AcceptedMessageKeysFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *AcceptedMessagesFilter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AcceptedMessagesFilter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AcceptedMessagesFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, make([]byte, postIndex-iNdEx)) + copy(m.Messages[len(m.Messages)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func skipAuthz(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAuthz + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAuthz + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAuthz + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAuthz = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAuthz = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAuthz = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/wasm/types/authz_test.go b/x/wasm/types/authz_test.go new file mode 100644 index 0000000000..06747693fc --- /dev/null +++ b/x/wasm/types/authz_test.go @@ -0,0 +1,728 @@ +package types + +import ( + "math" + "testing" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authztypes "github.com/cosmos/cosmos-sdk/x/authz" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestContractAuthzFilterValidate(t *testing.T) { + specs := map[string]struct { + src ContractAuthzFilterX + expErr bool + }{ + "allow all": { + src: &AllowAllMessagesFilter{}, + }, + "allow keys - single": { + src: NewAcceptedMessageKeysFilter("foo"), + }, + "allow keys - multi": { + src: NewAcceptedMessageKeysFilter("foo", "bar"), + }, + "allow keys - empty": { + src: NewAcceptedMessageKeysFilter(), + expErr: true, + }, + "allow keys - duplicates": { + src: NewAcceptedMessageKeysFilter("foo", "foo"), + expErr: true, + }, + "allow keys - whitespaces": { + src: NewAcceptedMessageKeysFilter(" foo"), + expErr: true, + }, + "allow keys - empty key": { + src: NewAcceptedMessageKeysFilter("", "bar"), + expErr: true, + }, + "allow keys - whitespace key": { + src: NewAcceptedMessageKeysFilter(" ", "bar"), + expErr: true, + }, + "allow message - single": { + src: NewAcceptedMessagesFilter([]byte(`{}`)), + }, + "allow message - multiple": { + src: NewAcceptedMessagesFilter([]byte(`{}`), []byte(`{"foo":"bar"}`)), + }, + "allow message - multiple with empty": { + src: NewAcceptedMessagesFilter([]byte(`{}`), nil), + expErr: true, + }, + "allow message - duplicate": { + src: NewAcceptedMessagesFilter([]byte(`{}`), []byte(`{}`)), + expErr: true, + }, + "allow message - non json": { + src: NewAcceptedMessagesFilter([]byte("non-json")), + expErr: true, + }, + "allow message - empty": { + src: NewAcceptedMessagesFilter(), + expErr: true, + }, + "allow all message - always valid": { + src: NewAllowAllMessagesFilter(), + }, + "undefined - always invalid": { + src: &UndefinedFilter{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestContractAuthzFilterAccept(t *testing.T) { + specs := map[string]struct { + filter ContractAuthzFilterX + src RawContractMessage + exp bool + expGasConsumed sdk.Gas + expErr bool + }{ + "allow all - accepts json obj": { + filter: &AllowAllMessagesFilter{}, + src: []byte(`{}`), + exp: true, + }, + "allow all - accepts json array": { + filter: &AllowAllMessagesFilter{}, + src: []byte(`[{},{}]`), + exp: true, + }, + "allow all - rejects non json msg": { + filter: &AllowAllMessagesFilter{}, + src: []byte(``), + expErr: true, + }, + "allowed key - single": { + filter: NewAcceptedMessageKeysFilter("foo"), + src: []byte(`{"foo": "bar"}`), + exp: true, + expGasConsumed: sdk.Gas(len(`{"foo": "bar"}`)), + }, + "allowed key - multiple": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`{"other": "value"}`), + exp: true, + expGasConsumed: sdk.Gas(len(`{"other": "value"}`)), + }, + "allowed key - non accepted key": { + filter: NewAcceptedMessageKeysFilter("foo"), + src: []byte(`{"bar": "value"}`), + exp: false, + expGasConsumed: sdk.Gas(len(`{"bar": "value"}`)), + }, + "allowed key - unsupported array msg": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`[{"foo":"bar"}]`), + expErr: false, + expGasConsumed: sdk.Gas(len(`[{"foo":"bar"}]`)), + }, + "allowed key - invalid msg": { + filter: NewAcceptedMessageKeysFilter("foo", "other"), + src: []byte(`not a json msg`), + expErr: true, + }, + "allow message - single": { + filter: NewAcceptedMessagesFilter([]byte(`{}`)), + src: []byte(`{}`), + exp: true, + }, + "allow message - multiple": { + filter: NewAcceptedMessagesFilter([]byte(`[{"foo":"bar"}]`), []byte(`{"other":"value"}`)), + src: []byte(`[{"foo":"bar"}]`), + exp: true, + }, + "allow message - no match": { + filter: NewAcceptedMessagesFilter([]byte(`{"foo":"bar"}`)), + src: []byte(`{"other":"value"}`), + exp: false, + }, + "allow all message - always accept valid": { + filter: NewAllowAllMessagesFilter(), + src: []byte(`{"other":"value"}`), + exp: true, + }, + "allow all message - always reject invalid json": { + filter: NewAllowAllMessagesFilter(), + src: []byte(`not json`), + expErr: true, + }, + "undefined - always errors": { + filter: &UndefinedFilter{}, + src: []byte(`{"foo":"bar"}`), + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gm := sdk.NewGasMeter(1_000_000) + allowed, gotErr := spec.filter.Accept(sdk.Context{}.WithGasMeter(gm), spec.src) + + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, allowed) + assert.Equal(t, spec.expGasConsumed, gm.GasConsumed()) + }) + } +} + +func TestContractAuthzLimitValidate(t *testing.T) { + oneToken := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) + specs := map[string]struct { + src ContractAuthzLimitX + expErr bool + }{ + "max calls": { + src: NewMaxCallsLimit(1), + }, + "max calls - max uint64": { + src: NewMaxCallsLimit(math.MaxUint64), + }, + "max calls - empty": { + src: NewMaxCallsLimit(0), + expErr: true, + }, + "max funds": { + src: NewMaxFundsLimit(oneToken), + }, + "max funds - empty coins": { + src: NewMaxFundsLimit(), + expErr: true, + }, + "max funds - duplicates": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, oneToken}}, + expErr: true, + }, + "max funds - contains empty value": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, sdk.NewCoin("other", sdk.ZeroInt())}.Sort()}, + expErr: true, + }, + "max funds - unsorted": { + src: &MaxFundsLimit{Amounts: sdk.Coins{oneToken, sdk.NewCoin("other", sdk.OneInt())}}, + expErr: true, + }, + "combined": { + src: NewCombinedLimit(1, oneToken), + }, + "combined - empty calls": { + src: NewCombinedLimit(0, oneToken), + expErr: true, + }, + "combined - empty amounts": { + src: NewCombinedLimit(1), + expErr: true, + }, + "combined - invalid amounts": { + src: &CombinedLimit{CallsRemaining: 1, Amounts: sdk.Coins{oneToken, oneToken}}, + expErr: true, + }, + "undefined": { + src: &UndefinedLimit{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestContractAuthzLimitAccept(t *testing.T) { + oneToken := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) + otherToken := sdk.NewCoin("other", sdk.OneInt()) + specs := map[string]struct { + limit ContractAuthzLimitX + src AuthzableWasmMsg + exp *ContractAuthzLimitAcceptResult + expErr bool + }{ + "max calls - updated": { + limit: NewMaxCallsLimit(2), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxCallsLimit(1)}, + }, + "max calls - removed": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max calls - accepted with zero fund set": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.ZeroInt()))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max calls - rejected with some fund transfer": { + limit: NewMaxCallsLimit(1), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max calls - invalid": { + limit: &MaxCallsLimit{}, + src: &MsgExecuteContract{}, + expErr: true, + }, + "max funds - single updated": { + limit: NewMaxFundsLimit(oneToken.Add(oneToken)), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxFundsLimit(oneToken)}, + }, + "max funds - single removed": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max funds - single with unknown token": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - single exceeds limit": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken.Add(oneToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - single with additional token send": { + limit: NewMaxFundsLimit(oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max funds - multi with other left": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewMaxFundsLimit(otherToken)}, + }, + "max funds - multi with all used": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max funds - multi with no tokens sent": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true}, + }, + "max funds - multi with other exceeds limit": { + limit: NewMaxFundsLimit(oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken.Add(otherToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max combined - multi amounts one consumed": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, otherToken)}, + }, + "max combined - multi amounts none consumed": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, oneToken, otherToken)}, + }, + "max combined - removed on last execution": { + limit: NewCombinedLimit(1, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max combined - removed on last token": { + limit: NewCombinedLimit(2, oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, DeleteLimit: true}, + }, + "max combined - update with token and calls remaining": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: true, UpdateLimit: NewCombinedLimit(1, otherToken)}, + }, + "max combined - multi with other exceeds limit": { + limit: NewCombinedLimit(2, oneToken, otherToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(oneToken, otherToken.Add(otherToken))}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "max combined - with unknown token": { + limit: NewCombinedLimit(2, oneToken), + src: &MsgExecuteContract{Funds: sdk.NewCoins(otherToken)}, + exp: &ContractAuthzLimitAcceptResult{Accepted: false}, + }, + "undefined": { + limit: &UndefinedLimit{}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotResult, gotErr := spec.limit.Accept(sdk.Context{}, spec.src) + // then + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, gotResult) + }) + } +} + +func TestValidateContractGrant(t *testing.T) { + specs := map[string]struct { + setup func(t *testing.T) ContractGrant + expErr bool + }{ + "all good": { + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + }, + }, + "invalid address": { + setup: func(t *testing.T) ContractGrant { + return mustGrant([]byte{}, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + }, + expErr: true, + }, + "invalid limit": { + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + }, + expErr: true, + }, + + "invalid filter ": { + setup: func(t *testing.T) ContractGrant { + return mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + }, + expErr: true, + }, + "empty limit": { + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + r.Limit = nil + return r + }, + expErr: true, + }, + + "empty filter ": { + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + r.Filter = nil + return r + }, + expErr: true, + }, + "wrong limit type": { + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(0), NewAllowAllMessagesFilter()) + r.Limit = r.Filter + return r + }, + expErr: true, + }, + + "wrong filter type": { + setup: func(t *testing.T) ContractGrant { + r := mustGrant(randBytes(ContractAddrLen), NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter()) + r.Filter = r.Limit + return r + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.setup(t).ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestValidateContractAuthorization(t *testing.T) { + validGrant, err := NewContractGrant(randBytes(SDKAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + invalidGrant, err := NewContractGrant(randBytes(SDKAddrLen), NewMaxCallsLimit(1), NewAllowAllMessagesFilter()) + require.NoError(t, err) + invalidGrant.Limit = nil + + specs := map[string]struct { + setup func(t *testing.T) validatable + expErr bool + }{ + "contract execution": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant) + }, + }, + "contract execution - duplicate grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *validGrant) + }, + }, + "contract execution - invalid grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *invalidGrant) + }, + expErr: true, + }, + "contract execution - empty grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization() + }, + expErr: true, + }, + "contract migration": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant) + }, + }, + "contract migration - duplicate grants": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *validGrant) + }, + }, + "contract migration - invalid grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization(*validGrant, *invalidGrant) + }, + expErr: true, + }, + "contract migration - empty grant": { + setup: func(t *testing.T) validatable { + return NewContractMigrationAuthorization() + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotErr := spec.setup(t).ValidateBasic() + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} + +func TestAcceptGrantedMessage(t *testing.T) { + myContractAddr := sdk.AccAddress(randBytes(SDKAddrLen)) + otherContractAddr := sdk.AccAddress(randBytes(SDKAddrLen)) + specs := map[string]struct { + auth authztypes.Authorization + msg sdk.Msg + expResult authztypes.AcceptResponse + expErr *sdkerrors.Error + }{ + "accepted and updated - contract execution": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(2), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + "accepted and not updated - limit not touched": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: true}, + }, + "accepted and removed - single": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: true, Delete: true}, + }, + "accepted and updated - multi, one removed": { + auth: NewContractExecutionAuthorization( + mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + ), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + "accepted and updated - multi, one updated": { + auth: NewContractExecutionAuthorization( + mustGrant(otherContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("bar")), + mustGrant(myContractAddr, NewCombinedLimit(2, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("foo")), + ), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractExecutionAuthorization( + mustGrant(otherContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter()), + mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), NewAcceptedMessageKeysFilter("bar")), + mustGrant(myContractAddr, NewCombinedLimit(1, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), NewAcceptedMessageKeysFilter("foo")), + ), + }, + }, + "not accepted - no matching contract address": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - max calls but tokens": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - funds exceeds limit": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxFundsLimit(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2))), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "not accepted - no matching filter": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAcceptedMessageKeysFilter("other"))), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + Funds: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), + }, + expResult: authztypes.AcceptResponse{Accept: false}, + }, + "invalid msg type - contract execution": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgMigrateContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + CodeID: 1, + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "payload is empty": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "payload is invalid": { + auth: NewContractExecutionAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`not json`), + }, + expErr: ErrInvalid, + }, + "invalid grant": { + auth: NewContractExecutionAuthorization(ContractGrant{Contract: myContractAddr.String()}), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrNotFound, + }, + "invalid msg type - contract migration": { + auth: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + msg: &MsgExecuteContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + Msg: []byte(`{"foo":"bar"}`), + }, + expErr: sdkerrors.ErrInvalidType, + }, + "accepted and updated - contract migration": { + auth: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(2), NewAllowAllMessagesFilter())), + msg: &MsgMigrateContract{ + Sender: sdk.AccAddress(randBytes(SDKAddrLen)).String(), + Contract: myContractAddr.String(), + CodeID: 1, + Msg: []byte(`{"foo":"bar"}`), + }, + expResult: authztypes.AcceptResponse{ + Accept: true, + Updated: NewContractMigrationAuthorization(mustGrant(myContractAddr, NewMaxCallsLimit(1), NewAllowAllMessagesFilter())), + }, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + ctx := sdk.Context{}.WithGasMeter(sdk.NewInfiniteGasMeter()) + gotResult, gotErr := spec.auth.Accept(ctx, spec.msg) + if spec.expErr != nil { + require.ErrorIs(t, gotErr, spec.expErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expResult, gotResult) + }) + } +} + +func mustGrant(contract sdk.AccAddress, limit ContractAuthzLimitX, filter ContractAuthzFilterX) ContractGrant { + g, err := NewContractGrant(contract, limit, filter) + if err != nil { + panic(err) + } + return *g +} diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index f1cd6f557f..5148da1346 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -6,6 +6,7 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" + "github.com/cosmos/cosmos-sdk/x/authz" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -29,6 +30,21 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&UpdateAdminProposal{}, "wasm/UpdateAdminProposal", nil) cdc.RegisterConcrete(&ClearAdminProposal{}, "wasm/ClearAdminProposal", nil) cdc.RegisterConcrete(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal", nil) + + cdc.RegisterInterface((*ContractInfoExtension)(nil), nil) + + cdc.RegisterInterface((*ContractAuthzFilterX)(nil), nil) + cdc.RegisterConcrete(&AllowAllMessagesFilter{}, "wasm/AllowAllMessagesFilter", nil) + cdc.RegisterConcrete(&AcceptedMessageKeysFilter{}, "wasm/AcceptedMessageKeysFilter", nil) + cdc.RegisterConcrete(&AcceptedMessagesFilter{}, "wasm/AcceptedMessagesFilter", nil) + + cdc.RegisterInterface((*ContractAuthzLimitX)(nil), nil) + cdc.RegisterConcrete(&MaxCallsLimit{}, "wasm/MaxCallsLimit", nil) + cdc.RegisterConcrete(&MaxFundsLimit{}, "wasm/MaxFundsLimit", nil) + cdc.RegisterConcrete(&CombinedLimit{}, "wasm/CombinedLimit", nil) + + cdc.RegisterConcrete(&ContractExecutionAuthorization{}, "wasm/ContractExecutionAuthorization", nil) + cdc.RegisterConcrete(&ContractMigrationAuthorization{}, "wasm/ContractMigrationAuthorization", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -60,6 +76,28 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterInterface("ContractInfoExtension", (*ContractInfoExtension)(nil)) + registry.RegisterInterface("ContractAuthzFilterX", (*ContractAuthzFilterX)(nil)) + registry.RegisterImplementations( + (*ContractAuthzFilterX)(nil), + &AllowAllMessagesFilter{}, + &AcceptedMessageKeysFilter{}, + &AcceptedMessagesFilter{}, + ) + + registry.RegisterInterface("ContractAuthzLimitX", (*ContractAuthzLimitX)(nil)) + registry.RegisterImplementations( + (*ContractAuthzLimitX)(nil), + &MaxCallsLimit{}, + &MaxFundsLimit{}, + &CombinedLimit{}, + ) + + registry.RegisterImplementations( + (*authz.Authorization)(nil), + &ContractExecutionAuthorization{}, + &ContractMigrationAuthorization{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/wasm/types/errors.go b/x/wasm/types/errors.go index 7accd72bcb..a7e0464612 100644 --- a/x/wasm/types/errors.go +++ b/x/wasm/types/errors.go @@ -73,17 +73,7 @@ var ( // error if an address does not belong to a contract (just for registration) _ = sdkErrors.Register(DefaultCodespace, 22, "no such contract") - // ErrNotAJSONObject error if given data is not a JSON object - ErrNotAJSONObject = sdkErrors.Register(DefaultCodespace, 23, "not a JSON object") - - // ErrNoTopLevelKey error if a JSON object has no top-level key - ErrNoTopLevelKey = sdkErrors.Register(DefaultCodespace, 24, "no top-level key") - - // ErrMultipleTopLevelKeys error if a JSON object has more than one top-level key - ErrMultipleTopLevelKeys = sdkErrors.Register(DefaultCodespace, 25, "multiple top-level keys") - - // ErrTopKevelKeyNotAllowed error if a JSON object has a top-level key that is not allowed - ErrTopKevelKeyNotAllowed = sdkErrors.Register(DefaultCodespace, 26, "top-level key is not allowed") + // code 23 -26 were used for json parser // ErrExceedMaxQueryStackSize error if max query stack size is exceeded ErrExceedMaxQueryStackSize = sdkErrors.Register(DefaultCodespace, 27, "max query stack size exceeded") diff --git a/x/wasm/types/json_matching.go b/x/wasm/types/json_matching.go index cfa8522650..34ff76d35d 100644 --- a/x/wasm/types/json_matching.go +++ b/x/wasm/types/json_matching.go @@ -2,34 +2,32 @@ package types import ( "encoding/json" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// IsJSONObjectWithTopLevelKey checks if the given bytes are a valid JSON object +// isJSONObjectWithTopLevelKey returns true if the given bytes are a valid JSON object // with exactly one top-level key that is contained in the list of allowed keys. -func IsJSONObjectWithTopLevelKey(jsonBytes []byte, allowedKeys []string) error { - document := map[string]interface{}{} - if err := json.Unmarshal(jsonBytes, &document); err != nil { - return sdkerrors.Wrap(ErrNotAJSONObject, "failed to unmarshal JSON to map") +func isJSONObjectWithTopLevelKey(jsonBytes RawContractMessage, allowedKeys []string) (bool, error) { + if err := jsonBytes.ValidateBasic(); err != nil { + return false, err } - if len(document) == 0 { - return sdkerrors.Wrap(ErrNoTopLevelKey, "JSON object has no top-level key") + document := map[string]interface{}{} + if err := json.Unmarshal(jsonBytes, &document); err != nil { + return false, nil // not a map } - if len(document) > 1 { - return sdkerrors.Wrap(ErrMultipleTopLevelKeys, "JSON object has multiple top-level keys") + if len(document) != 1 { + return false, nil // unsupported type } // Loop is executed exactly once for topLevelKey := range document { for _, allowedKey := range allowedKeys { if allowedKey == topLevelKey { - return nil + return true, nil } } - return sdkerrors.Wrapf(ErrTopKevelKeyNotAllowed, "JSON object has a top-level key which is not allowed: '%s'", topLevelKey) + return false, nil } panic("Reached unreachable code. This is a bug.") diff --git a/x/wasm/types/json_matching_test.go b/x/wasm/types/json_matching_test.go index 17f7684872..01d2d3efd3 100644 --- a/x/wasm/types/json_matching_test.go +++ b/x/wasm/types/json_matching_test.go @@ -1,8 +1,11 @@ package types import ( + "encoding/json" "testing" + "github.com/stretchr/testify/assert" + // sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" ) @@ -11,105 +14,121 @@ func TestIsJSONObjectWithTopLevelKey(t *testing.T) { specs := map[string]struct { src []byte allowedKeys []string - exp error + expResult bool + expErr error }{ "happy": { src: []byte(`{"msg": {"foo":"bar"}}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 1": { src: []byte(`{"claim": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 2": { src: []byte(`{"burn": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with many allowed keys 3": { src: []byte(`{"mint": {"foo":"bar"}}`), allowedKeys: []string{"claim", "swap", "burn", "mint"}, - exp: nil, + expResult: true, }, "happy with number": { src: []byte(`{"msg": 123}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with array": { src: []byte(`{"msg": [1, 2, 3, 4]}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with null": { src: []byte(`{"msg": null}`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, "happy with whitespace": { src: []byte(`{ "msg": null }`), allowedKeys: []string{"msg"}, - exp: nil, + expResult: true, }, - "happy with excaped key": { + "happy with escaped key": { src: []byte(`{"event\u2468thing": {"foo":"bar"}}`), allowedKeys: []string{"event⑨thing"}, - exp: nil, + expResult: true, }, // Invalid JSON object "errors for bytes that are no JSON": { src: []byte(`nope`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, + expErr: ErrInvalid, }, - "errors for valid JSON (string)": { + "false for valid JSON (string)": { src: []byte(`"nope"`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, + expResult: false, }, - "errors for valid JSON (array)": { + "false for valid JSON (array)": { src: []byte(`[1, 2, 3]`), allowedKeys: []string{"claim"}, - exp: ErrNotAJSONObject, - }, + expResult: false, + }, + // not supported: https://github.com/golang/go/issues/24415 + //"errors for duplicate key": { + // src: []byte(`{"claim": "foo", "claim":"bar"}`), + // allowedKeys: []string{"claim"}, + // expErr: ErrNotAJSONObject, + //}, // Not one top-level key - "errors for no top-level key": { + "false for no top-level key": { src: []byte(`{}`), allowedKeys: []string{"claim"}, - exp: ErrNoTopLevelKey, + expResult: false, }, - "errors for multiple top-level keys": { + "false for multiple top-level keys": { src: []byte(`{"claim": {}, "and_swap": {}}`), allowedKeys: []string{"claim"}, - exp: ErrMultipleTopLevelKeys, + expResult: false, }, // Wrong top-level key - "errors for wrong top-level key 1": { + "wrong top-level key 1": { src: []byte(`{"claim": {}}`), allowedKeys: []string{""}, - exp: ErrTopKevelKeyNotAllowed, + expResult: false, }, - "errors for wrong top-level key 2": { + "wrong top-level key 2": { src: []byte(`{"claim": {}}`), allowedKeys: []string{"swap", "burn", "mint"}, - exp: ErrTopKevelKeyNotAllowed, + expResult: false, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { - result := IsJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) - if spec.exp == nil { - require.NoError(t, result) - } else { - require.Error(t, result) - require.Contains(t, result.Error(), spec.exp.Error()) + exists, gotErr := isJSONObjectWithTopLevelKey(spec.src, spec.allowedKeys) + if spec.expErr != nil { + assert.ErrorIs(t, gotErr, spec.expErr) + return } + require.NoError(t, gotErr) + assert.Equal(t, spec.expResult, exists) }) } } + +func TestDuplicateKeyGivesSameResult(t *testing.T) { + jsonBytes := []byte(`{"event⑨thing": "foo", "event⑨thing":"bar"}`) + for i := 0; i < 10000; i++ { + document := map[string]interface{}{} + require.NoError(t, json.Unmarshal(jsonBytes, &document)) + assert.Equal(t, "bar", document["event⑨thing"]) + } +} diff --git a/x/wasm/types/query.pb.go b/x/wasm/types/query.pb.go index bb08b7571c..68b15e39fa 100644 --- a/x/wasm/types/query.pb.go +++ b/x/wasm/types/query.pb.go @@ -1288,8 +1288,10 @@ func (this *QueryCodeResponse) Equal(that interface{}) bool { } // Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +var ( + _ context.Context + _ grpc.ClientConn +) // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. diff --git a/x/wasm/types/tx.go b/x/wasm/types/tx.go index 9630777f29..dd6f6284cd 100644 --- a/x/wasm/types/tx.go +++ b/x/wasm/types/tx.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "encoding/json" "errors" "strings" @@ -41,6 +42,11 @@ func (r RawContractMessage) Bytes() []byte { return r } +// Equal content is equal json. Byte equal but this can change in the future. +func (r RawContractMessage) Equal(o RawContractMessage) bool { + return bytes.Equal(r.Bytes(), o.Bytes()) +} + func (msg MsgStoreCode) Route() string { return RouterKey } @@ -163,6 +169,21 @@ func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{senderAddr} } +// GetMsg returns the payload message send to the contract +func (msg MsgExecuteContract) GetMsg() RawContractMessage { + return msg.Msg +} + +// GetFunds returns tokens send to the contract +func (msg MsgExecuteContract) GetFunds() sdk.Coins { + return msg.Funds +} + +// GetContract returns the bech32 address of the contract +func (msg MsgExecuteContract) GetContract() string { + return msg.Contract +} + func (msg MsgMigrateContract) Route() string { return RouterKey } @@ -201,6 +222,21 @@ func (msg MsgMigrateContract) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{senderAddr} } +// GetMsg returns the payload message send to the contract +func (msg MsgMigrateContract) GetMsg() RawContractMessage { + return msg.Msg +} + +// GetFunds returns tokens send to the contract +func (msg MsgMigrateContract) GetFunds() sdk.Coins { + return sdk.NewCoins() +} + +// GetContract returns the bech32 address of the contract +func (msg MsgMigrateContract) GetContract() string { + return msg.Contract +} + func (msg MsgUpdateAdmin) Route() string { return RouterKey } diff --git a/x/wasm/types/tx.pb.go b/x/wasm/types/tx.pb.go index f81b1106e0..4670ba2b0b 100644 --- a/x/wasm/types/tx.pb.go +++ b/x/wasm/types/tx.pb.go @@ -778,8 +778,10 @@ var fileDescriptor_4f74d82755520264 = []byte{ } // Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +var ( + _ context.Context + _ grpc.ClientConn +) // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. From ef9a84dda82538265ce1686812481ebc58da097c Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:04:04 +0100 Subject: [PATCH 021/294] Add StoreAndInstantiateContract gov proposal (#1074) * Add StoreAndInstantiateContract gov proposal * Add integration tests * Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Remove exposed functions * Add tests * Add Developer's guide and best practices (#1075) * Add Developer's guide and best practices * Fix comments * Change genesis preserving contract history (#1076) * preserve contract created date on genesis import and add query contract created date * add validate created * fix sims test app import export * add preserve contract history * Make proto-all only * Remove ResetFromGenesis * Add validation Co-authored-by: Alex Peters * Return contract history updates * Bump github.com/spf13/viper from 1.13.0 to 1.14.0 (#1082) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Revert "Bump github.com/spf13/viper from 1.13.0 to 1.14.0 (#1082)" This reverts commit cf81eb8ea6828dd6b03a96ed166267cf64befc06. * Add cli and refactor code * Contract authz - redesign (#1077) * Add contract authz proto * Implement contract autorization * Register contract authz * Add contract-authz tests * Consume gas for contract authz * Add contract authz cli * Update cli usage * Model spike * Add max funds limit * Redesign authz model * Start e2e test * Full e2e test * Test filter and limits * Test accept * Fix description * No linter warning Co-authored-by: Giancarlos Salas * Add StoreAndInstantiateContract gov proposal * Add integration tests * Remove exposed functions * Add tests * Add cli and refactor code * Fix comments Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: GNaD13 <89174180+GNaD13@users.noreply.github.com> Co-authored-by: Alex Peters Co-authored-by: Giancarlos Salas --- docs/proto/proto-docs.md | 26 + proto/cosmwasm/wasm/v1/proposal.proto | 28 + x/wasm/Governance.md | 3 +- x/wasm/client/cli/gov_tx.go | 306 ++++----- x/wasm/client/proposal_handler.go | 1 + x/wasm/client/rest/gov.go | 9 + x/wasm/keeper/proposal_handler.go | 40 ++ x/wasm/keeper/proposal_integration_test.go | 60 ++ x/wasm/types/codec.go | 2 + x/wasm/types/proposal.go | 145 +++- x/wasm/types/proposal.pb.go | 757 +++++++++++++++++++-- x/wasm/types/proposal_test.go | 114 ++++ x/wasm/types/test_fixtures.go | 35 + 13 files changed, 1292 insertions(+), 234 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index dedd98bd21..ef464a9f38 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -64,6 +64,7 @@ - [InstantiateContractProposal](#cosmwasm.wasm.v1.InstantiateContractProposal) - [MigrateContractProposal](#cosmwasm.wasm.v1.MigrateContractProposal) - [PinCodesProposal](#cosmwasm.wasm.v1.PinCodesProposal) + - [StoreAndInstantiateContractProposal](#cosmwasm.wasm.v1.StoreAndInstantiateContractProposal) - [StoreCodeProposal](#cosmwasm.wasm.v1.StoreCodeProposal) - [SudoContractProposal](#cosmwasm.wasm.v1.SudoContractProposal) - [UnpinCodesProposal](#cosmwasm.wasm.v1.UnpinCodesProposal) @@ -984,6 +985,31 @@ wasmvm cache. + + +### StoreAndInstantiateContractProposal +StoreAndInstantiateContractProposal gov proposal content type to store +and instantiate the contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | +| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | +| `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | + + + + + + ### StoreCodeProposal diff --git a/proto/cosmwasm/wasm/v1/proposal.proto b/proto/cosmwasm/wasm/v1/proposal.proto index 25bf2700b1..a4e57b7dd9 100644 --- a/proto/cosmwasm/wasm/v1/proposal.proto +++ b/proto/cosmwasm/wasm/v1/proposal.proto @@ -172,3 +172,31 @@ message UpdateInstantiateConfigProposal { repeated AccessConfigUpdate access_config_updates = 3 [ (gogoproto.nullable) = false ]; } + +// StoreAndInstantiateContractProposal gov proposal content type to store +// and instantiate the contract. +message StoreAndInstantiateContractProposal { + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; + // InstantiatePermission to apply on contract creation, optional + AccessConfig instantiate_permission = 5; + // UnpinCode code on upload, optional + bool unpin_code = 6; + // Admin is an optional address that can execute migrations + string admin = 7; + // Label is optional metadata to be stored with a constract instance. + string label = 8; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 9 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 10 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} diff --git a/x/wasm/Governance.md b/x/wasm/Governance.md index cd7d0ae2cb..da47240c14 100644 --- a/x/wasm/Governance.md +++ b/x/wasm/Governance.md @@ -17,7 +17,8 @@ We have added 9 new wasm specific proposal types that cover the contract's live * `ClearAdminProposal` - clear admin for a contract to prevent further migrations * `PinCodes` - pin the given code ids in cache. This trades memory for reduced startup time and lowers gas cost * `UnpinCodes` - unpin the given code ids from the cache. This frees up memory and returns to standard speed and gas cost -* `UpdateInstantiateConfigProposal` - update instantiate permissions to a list of given code ids. +* `UpdateInstantiateConfigProposal` - update instantiate permissions to a list of given code ids. +* `StoreAndInstantiateContractProposal` - upload and instantiate a wasm contract. For details see the proposal type [implementation](https://github.com/CosmWasm/wasmd/blob/master/x/wasm/types/proposal.go) diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 01f7aaf80e..131ccda57d 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -23,7 +23,7 @@ func ProposalStoreCodeCmd() *cobra.Command { Short: "Submit a wasm binary proposal", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -39,22 +39,6 @@ func ProposalStoreCodeCmd() *cobra.Command { if len(runAs) == 0 { return errors.New("run-as address is required") } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } unpinCode, err := cmd.Flags().GetBool(flagUnpinCode) if err != nil { @@ -103,7 +87,7 @@ func ProposalInstantiateContractCmd() *cobra.Command { Short: "Submit an instantiate wasm contract proposal", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -120,22 +104,6 @@ func ProposalInstantiateContractCmd() *cobra.Command { if len(runAs) == 0 { return errors.New("run-as address is required") } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } content := types.InstantiateContractProposal{ Title: proposalTitle, @@ -173,35 +141,122 @@ func ProposalInstantiateContractCmd() *cobra.Command { return cmd } -func ProposalMigrateContractCmd() *cobra.Command { +func ProposalStoreAndInstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "migrate-contract [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args]", - Short: "Submit a migrate wasm contract to a new code version proposal", - Args: cobra.ExactArgs(3), + Use: "store-instantiate [wasm file] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address] --admin [address,optional] --amount [coins,optional]", + Short: "Submit and instantiate a wasm contract proposal", + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } - src, err := parseMigrateContractArgs(args, clientCtx) + src, err := parseStoreCodeArgs(args[0], clientCtx.FromAddress, cmd.Flags()) + if err != nil { + return err + } + runAs, err := cmd.Flags().GetString(flagRunAs) + if err != nil { + return fmt.Errorf("run-as: %s", err) + } + if len(runAs) == 0 { + return errors.New("run-as address is required") + } + + unpinCode, err := cmd.Flags().GetBool(flagUnpinCode) if err != nil { return err } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) + amountStr, err := cmd.Flags().GetString(flagAmount) + if err != nil { + return fmt.Errorf("amount: %s", err) + } + amount, err := sdk.ParseCoinsNormalized(amountStr) + if err != nil { + return fmt.Errorf("amount: %s", err) + } + label, err := cmd.Flags().GetString(flagLabel) + if err != nil { + return fmt.Errorf("label: %s", err) + } + if label == "" { + return errors.New("label is required on all contracts") + } + adminStr, err := cmd.Flags().GetString(flagAdmin) if err != nil { - return fmt.Errorf("proposal title: %s", err) + return fmt.Errorf("admin: %s", err) } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) + noAdmin, err := cmd.Flags().GetBool(flagNoAdmin) if err != nil { - return fmt.Errorf("proposal description: %s", err) + return fmt.Errorf("no-admin: %s", err) + } + + // ensure sensible admin is set (or explicitly immutable) + if adminStr == "" && !noAdmin { + return fmt.Errorf("you must set an admin or explicitly pass --no-admin to make it immutible (wasmd issue #719)") + } + if adminStr != "" && noAdmin { + return fmt.Errorf("you set an admin and passed --no-admin, those cannot both be true") + } + + content := types.StoreAndInstantiateContractProposal{ + Title: proposalTitle, + Description: proposalDescr, + RunAs: runAs, + WASMByteCode: src.WASMByteCode, + InstantiatePermission: src.InstantiatePermission, + UnpinCode: unpinCode, + Admin: adminStr, + Label: label, + Msg: []byte(args[1]), + Funds: amount, + } + + msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress()) + if err != nil { + return err + } + if err = msg.ValidateBasic(); err != nil { + return err } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + SilenceUsage: true, + } + + cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator. It is the creator of the contract and passed to the contract as sender on proposal execution") + cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional") + cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional") + cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional") + cmd.Flags().Bool(flagUnpinCode, false, "Unpin code on upload, optional") + cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") + cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") + cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") + cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") + + // proposal flags + cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") + cmd.Flags().String(cli.FlagDescription, "", "Description of proposal") + cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal") + return cmd +} + +func ProposalMigrateContractCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "migrate-contract [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args]", + Short: "Submit a migrate wasm contract to a new code version proposal", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } - deposit, err := sdk.ParseCoinsNormalized(depositArg) + + src, err := parseMigrateContractArgs(args, clientCtx) if err != nil { return err } @@ -240,7 +295,7 @@ func ProposalExecuteContractCmd() *cobra.Command { Short: "Submit a execute wasm contract proposal (run by any address)", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -263,22 +318,6 @@ func ProposalExecuteContractCmd() *cobra.Command { if len(runAs) == 0 { return errors.New("run-as address is required") } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } content := types.ExecuteContractProposal{ Title: proposalTitle, @@ -317,7 +356,7 @@ func ProposalSudoContractCmd() *cobra.Command { Short: "Submit a sudo wasm contract proposal (to call privileged commands)", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -325,23 +364,6 @@ func ProposalSudoContractCmd() *cobra.Command { contract := args[0] sudoMsg := []byte(args[1]) - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } - content := types.SudoContractProposal{ Title: proposalTitle, Description: proposalDescr, @@ -375,7 +397,7 @@ func ProposalUpdateContractAdminCmd() *cobra.Command { Short: "Submit a new admin for a contract proposal", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -385,23 +407,6 @@ func ProposalUpdateContractAdminCmd() *cobra.Command { return err } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return fmt.Errorf("deposit: %s", err) - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } - content := types.UpdateAdminProposal{ Title: proposalTitle, Description: proposalDescr, @@ -434,24 +439,7 @@ func ProposalClearContractAdminCmd() *cobra.Command { Short: "Submit a clear admin for a contract to prevent further migrations proposal", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return fmt.Errorf("deposit: %s", err) - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -487,27 +475,11 @@ func ProposalPinCodesCmd() *cobra.Command { Short: "Submit a pin code proposal for pinning a code to cache", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return fmt.Errorf("deposit: %s", err) - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } codeIds, err := parsePinCodesArgs(args) if err != nil { return err @@ -556,27 +528,11 @@ func ProposalUnpinCodesCmd() *cobra.Command { Short: "Submit a unpin code proposal for unpinning a code to cache", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return fmt.Errorf("deposit: %s", err) - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) - if err != nil { - return err - } codeIds, err := parsePinCodesArgs(args) if err != nil { return err @@ -673,24 +629,7 @@ Example: $ %s tx gov submit-proposal update-instantiate-config 1:nobody 2:everybody 3:%s1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm,%s1vx8knpllrj7n963p9ttd80w47kpacrhuts497x `, version.AppName, bech32Prefix, bech32Prefix)), RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return fmt.Errorf("proposal title: %s", err) - } - proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return fmt.Errorf("proposal description: %s", err) - } - depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return fmt.Errorf("deposit: %s", err) - } - deposit, err := sdk.ParseCoinsNormalized(depositArg) + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) if err != nil { return err } @@ -722,3 +661,32 @@ $ %s tx gov submit-proposal update-instantiate-config 1:nobody 2:everybody 3:%s1 cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal") return cmd } + +func getProposalInfo(cmd *cobra.Command) (client.Context, string, string, sdk.Coins, error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return client.Context{}, "", "", nil, err + } + + proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle) + if err != nil { + return clientCtx, proposalTitle, "", nil, err + } + + proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription) + if err != nil { + return client.Context{}, proposalTitle, proposalDescr, nil, err + } + + depositArg, err := cmd.Flags().GetString(cli.FlagDeposit) + if err != nil { + return client.Context{}, proposalTitle, proposalDescr, nil, err + } + + deposit, err := sdk.ParseCoinsNormalized(depositArg) + if err != nil { + return client.Context{}, proposalTitle, proposalDescr, deposit, err + } + + return clientCtx, proposalTitle, proposalDescr, deposit, nil +} diff --git a/x/wasm/client/proposal_handler.go b/x/wasm/client/proposal_handler.go index 9d90d48df8..db51f7b3ac 100644 --- a/x/wasm/client/proposal_handler.go +++ b/x/wasm/client/proposal_handler.go @@ -20,4 +20,5 @@ var ProposalHandlers = []govclient.ProposalHandler{ govclient.NewProposalHandler(cli.ProposalPinCodesCmd, rest.PinCodeProposalHandler), govclient.NewProposalHandler(cli.ProposalUnpinCodesCmd, rest.UnpinCodeProposalHandler), govclient.NewProposalHandler(cli.ProposalUpdateInstantiateConfigCmd, rest.UpdateInstantiateConfigProposalHandler), + govclient.NewProposalHandler(cli.ProposalStoreAndInstantiateContractCmd, rest.EmptyRestHandler), } diff --git a/x/wasm/client/rest/gov.go b/x/wasm/client/rest/gov.go index f730cb4696..3a27d2f0d7 100644 --- a/x/wasm/client/rest/gov.go +++ b/x/wasm/client/rest/gov.go @@ -525,3 +525,12 @@ func toStdTxResponse(cliCtx client.Context, w http.ResponseWriter, data wasmProp } tx.WriteGeneratedTxResponse(cliCtx, w, baseReq, msg) } + +func EmptyRestHandler(cliCtx client.Context) govrest.ProposalRESTHandler { + return govrest.ProposalRESTHandler{ + SubRoute: "unsupported", + Handler: func(w http.ResponseWriter, r *http.Request) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "Legacy REST Routes are not supported for gov proposals") + }, + } +} diff --git a/x/wasm/keeper/proposal_handler.go b/x/wasm/keeper/proposal_handler.go index 29b736b00b..b39a8c4238 100644 --- a/x/wasm/keeper/proposal_handler.go +++ b/x/wasm/keeper/proposal_handler.go @@ -49,6 +49,8 @@ func NewWasmProposalHandlerX(k types.ContractOpsKeeper, enabledProposalTypes []t return handleUnpinCodesProposal(ctx, k, *c) case *types.UpdateInstantiateConfigProposal: return handleUpdateInstantiateConfigProposal(ctx, k, *c) + case *types.StoreAndInstantiateContractProposal: + return handleStoreAndInstantiateContractProposal(ctx, k, *c) default: return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized wasm proposal content type: %T", c) } @@ -103,6 +105,44 @@ func handleInstantiateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p typ return nil } +func handleStoreAndInstantiateContractProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.StoreAndInstantiateContractProposal) error { + if err := p.ValidateBasic(); err != nil { + return err + } + runAsAddr, err := sdk.AccAddressFromBech32(p.RunAs) + if err != nil { + return sdkerrors.Wrap(err, "run as address") + } + var adminAddr sdk.AccAddress + if p.Admin != "" { + if adminAddr, err = sdk.AccAddressFromBech32(p.Admin); err != nil { + return sdkerrors.Wrap(err, "admin") + } + } + + codeID, _, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission) + if err != nil { + return err + } + + if !p.UnpinCode { + if err := k.PinCode(ctx, codeID); err != nil { + return err + } + } + + _, data, err := k.Instantiate(ctx, codeID, runAsAddr, adminAddr, p.Msg, p.Label, p.Funds) + if err != nil { + return err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeGovContractResult, + sdk.NewAttribute(types.AttributeKeyResultDataHex, hex.EncodeToString(data)), + )) + return nil +} + func handleMigrateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.MigrateContractProposal) error { if err := p.ValidateBasic(); err != nil { return err diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 1327ba88e3..8055ca385a 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -210,6 +210,66 @@ func TestInstantiateProposal_NoAdmin(t *testing.T) { require.NotEmpty(t, em.Events()[2].Attributes[0]) } +func TestStoreAndInstantiateContractProposal(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, "staking") + govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper + wasmKeeper.SetParams(ctx, types.Params{ + CodeUploadAccess: types.AllowNobody, + InstantiateDefaultPermission: types.AccessTypeNobody, + }) + + wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") + require.NoError(t, err) + + var ( + oneAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, types.ContractAddrLen) + otherAddress sdk.AccAddress = bytes.Repeat([]byte{0x2}, types.ContractAddrLen) + ) + + src := types.StoreAndInstantiateContractProposalFixture(func(p *types.StoreAndInstantiateContractProposal) { + p.WASMByteCode = wasmCode + p.RunAs = oneAddress.String() + p.Admin = otherAddress.String() + p.Label = "testing" + }) + em := sdk.NewEventManager() + + // when stored + storedProposal, err := govKeeper.SubmitProposal(ctx, src) + require.NoError(t, err) + + // and proposal execute + handler := govKeeper.Router().GetRoute(storedProposal.ProposalRoute()) + err = handler(ctx.WithEventManager(em), storedProposal.GetContent()) + require.NoError(t, err) + + // then + contractAddr, err := sdk.AccAddressFromBech32("cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr") + require.NoError(t, err) + + cInfo := wasmKeeper.GetContractInfo(ctx, contractAddr) + require.NotNil(t, cInfo) + assert.Equal(t, oneAddress.String(), cInfo.Creator) + assert.Equal(t, otherAddress.String(), cInfo.Admin) + assert.Equal(t, "testing", cInfo.Label) + expHistory := []types.ContractCodeHistoryEntry{{ + Operation: types.ContractCodeHistoryOperationTypeInit, + CodeID: cInfo.CodeID, + Updated: types.NewAbsoluteTxPosition(ctx), + Msg: src.Msg, + }} + assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddr)) + // and event + require.Len(t, em.Events(), 5, "%#v", em.Events()) + require.Equal(t, types.EventTypeStoreCode, em.Events()[0].Type) + require.Equal(t, types.EventTypePinCode, em.Events()[1].Type) + require.Equal(t, types.EventTypeInstantiate, em.Events()[2].Type) + require.Equal(t, types.WasmModuleEventType, em.Events()[3].Type) + require.Equal(t, types.EventTypeGovContractResult, em.Events()[4].Type) + require.Len(t, em.Events()[4].Attributes, 1) + require.NotEmpty(t, em.Events()[4].Attributes[0]) +} + func TestMigrateProposal(t *testing.T) { ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index 5148da1346..64b4f28e41 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -45,6 +45,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&ContractExecutionAuthorization{}, "wasm/ContractExecutionAuthorization", nil) cdc.RegisterConcrete(&ContractMigrationAuthorization{}, "wasm/ContractMigrationAuthorization", nil) + cdc.RegisterConcrete(&StoreAndInstantiateContractProposal{}, "wasm/StoreAndInstantiateContractProposal", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -72,6 +73,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &PinCodesProposal{}, &UnpinCodesProposal{}, &UpdateInstantiateConfigProposal{}, + &StoreAndInstantiateContractProposal{}, ) registry.RegisterInterface("ContractInfoExtension", (*ContractInfoExtension)(nil)) diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index bb2ba16d6b..0b8f943264 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -13,16 +13,17 @@ import ( type ProposalType string const ( - ProposalTypeStoreCode ProposalType = "StoreCode" - ProposalTypeInstantiateContract ProposalType = "InstantiateContract" - ProposalTypeMigrateContract ProposalType = "MigrateContract" - ProposalTypeSudoContract ProposalType = "SudoContract" - ProposalTypeExecuteContract ProposalType = "ExecuteContract" - ProposalTypeUpdateAdmin ProposalType = "UpdateAdmin" - ProposalTypeClearAdmin ProposalType = "ClearAdmin" - ProposalTypePinCodes ProposalType = "PinCodes" - ProposalTypeUnpinCodes ProposalType = "UnpinCodes" - ProposalTypeUpdateInstantiateConfig ProposalType = "UpdateInstantiateConfig" + ProposalTypeStoreCode ProposalType = "StoreCode" + ProposalTypeInstantiateContract ProposalType = "InstantiateContract" + ProposalTypeMigrateContract ProposalType = "MigrateContract" + ProposalTypeSudoContract ProposalType = "SudoContract" + ProposalTypeExecuteContract ProposalType = "ExecuteContract" + ProposalTypeUpdateAdmin ProposalType = "UpdateAdmin" + ProposalTypeClearAdmin ProposalType = "ClearAdmin" + ProposalTypePinCodes ProposalType = "PinCodes" + ProposalTypeUnpinCodes ProposalType = "UnpinCodes" + ProposalTypeUpdateInstantiateConfig ProposalType = "UpdateInstantiateConfig" + ProposalTypeStoreAndInstantiateContractProposal ProposalType = "StoreAndInstantiateContract" ) // DisableAllProposals contains no wasm gov types. @@ -40,6 +41,7 @@ var EnableAllProposals = []ProposalType{ ProposalTypePinCodes, ProposalTypeUnpinCodes, ProposalTypeUpdateInstantiateConfig, + ProposalTypeStoreAndInstantiateContractProposal, } // ConvertToProposals maps each key to a ProposalType and returns a typed list. @@ -71,6 +73,7 @@ func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypePinCodes)) govtypes.RegisterProposalType(string(ProposalTypeUnpinCodes)) govtypes.RegisterProposalType(string(ProposalTypeUpdateInstantiateConfig)) + govtypes.RegisterProposalType(string(ProposalTypeStoreAndInstantiateContractProposal)) govtypes.RegisterProposalTypeCodec(&StoreCodeProposal{}, "wasm/StoreCodeProposal") govtypes.RegisterProposalTypeCodec(&InstantiateContractProposal{}, "wasm/InstantiateContractProposal") govtypes.RegisterProposalTypeCodec(&MigrateContractProposal{}, "wasm/MigrateContractProposal") @@ -81,6 +84,7 @@ func init() { // register new content types with the sdk govtypes.RegisterProposalTypeCodec(&PinCodesProposal{}, "wasm/PinCodesProposal") govtypes.RegisterProposalTypeCodec(&UnpinCodesProposal{}, "wasm/UnpinCodesProposal") govtypes.RegisterProposalTypeCodec(&UpdateInstantiateConfigProposal{}, "wasm/UpdateInstantiateConfigProposal") + govtypes.RegisterProposalTypeCodec(&StoreAndInstantiateContractProposal{}, "wasm/StoreAndInstantiateContractProposal") } func NewStoreCodeProposal( @@ -250,6 +254,127 @@ func (p InstantiateContractProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewStoreAndInstantiateContractProposal( + title string, + description string, + runAs string, + wasmBz []byte, + permission *AccessConfig, + unpinCode bool, + admin string, + label string, + msg RawContractMessage, + funds sdk.Coins, +) *StoreAndInstantiateContractProposal { + return &StoreAndInstantiateContractProposal{ + Title: title, + Description: description, + RunAs: runAs, + WASMByteCode: wasmBz, + InstantiatePermission: permission, + UnpinCode: unpinCode, + Admin: admin, + Label: label, + Msg: msg, + Funds: funds, + } +} + +// ProposalRoute returns the routing key of a parameter change proposal. +func (p StoreAndInstantiateContractProposal) ProposalRoute() string { return RouterKey } + +// GetTitle returns the title of the proposal +func (p *StoreAndInstantiateContractProposal) GetTitle() string { return p.Title } + +// GetDescription returns the human readable description of the proposal +func (p StoreAndInstantiateContractProposal) GetDescription() string { return p.Description } + +// ProposalType returns the type +func (p StoreAndInstantiateContractProposal) ProposalType() string { + return string(ProposalTypeStoreAndInstantiateContractProposal) +} + +// ValidateBasic validates the proposal +func (p StoreAndInstantiateContractProposal) ValidateBasic() error { + if err := validateProposalCommons(p.Title, p.Description); err != nil { + return err + } + if _, err := sdk.AccAddressFromBech32(p.RunAs); err != nil { + return sdkerrors.Wrap(err, "run as") + } + + if err := validateWasmCode(p.WASMByteCode); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "code bytes %s", err.Error()) + } + + if p.InstantiatePermission != nil { + if err := p.InstantiatePermission.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "instantiate permission") + } + } + + if err := ValidateLabel(p.Label); err != nil { + return err + } + + if !p.Funds.IsValid() { + return sdkerrors.ErrInvalidCoins + } + + if len(p.Admin) != 0 { + if _, err := sdk.AccAddressFromBech32(p.Admin); err != nil { + return err + } + } + if err := p.Msg.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "payload msg") + } + return nil +} + +// String implements the Stringer interface. +func (p StoreAndInstantiateContractProposal) String() string { + return fmt.Sprintf(`Store And Instantiate Coontract Proposal: + Title: %s + Description: %s + Run as: %s + WasmCode: %X + Instantiate permission: %s + Unpin code: %t + Admin: %s + Label: %s + Msg: %q + Funds: %s +`, p.Title, p.Description, p.RunAs, p.WASMByteCode, p.InstantiatePermission, p.UnpinCode, p.Admin, p.Label, p.Msg, p.Funds) +} + +// MarshalYAML pretty prints the wasm byte code and the init message +func (p StoreAndInstantiateContractProposal) MarshalYAML() (interface{}, error) { + return struct { + Title string `yaml:"title"` + Description string `yaml:"description"` + RunAs string `yaml:"run_as"` + WASMByteCode string `yaml:"wasm_byte_code"` + InstantiatePermission *AccessConfig `yaml:"instantiate_permission"` + UnpinCode bool `yaml:"unpin_code"` + Admin string `yaml:"admin"` + Label string `yaml:"label"` + Msg string `yaml:"msg"` + Funds sdk.Coins `yaml:"funds"` + }{ + Title: p.Title, + Description: p.Description, + RunAs: p.RunAs, + WASMByteCode: base64.StdEncoding.EncodeToString(p.WASMByteCode), + InstantiatePermission: p.InstantiatePermission, + UnpinCode: p.UnpinCode, + Admin: p.Admin, + Label: p.Label, + Msg: string(p.Msg), + Funds: p.Funds, + }, nil +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p MigrateContractProposal) ProposalRoute() string { return RouterKey } diff --git a/x/wasm/types/proposal.pb.go b/x/wasm/types/proposal.pb.go index 0e87ce5fca..27a9ed0b9f 100644 --- a/x/wasm/types/proposal.pb.go +++ b/x/wasm/types/proposal.pb.go @@ -583,6 +583,68 @@ func (m *UpdateInstantiateConfigProposal) XXX_DiscardUnknown() { var xxx_messageInfo_UpdateInstantiateConfigProposal proto.InternalMessageInfo +// StoreAndInstantiateContractProposal gov proposal content type to store +// and instantiate the contract. +type StoreAndInstantiateContractProposal struct { + // Title is a short summary + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + // Description is a human readable text + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // RunAs is the address that is passed to the contract's environment as sender + RunAs string `protobuf:"bytes,3,opt,name=run_as,json=runAs,proto3" json:"run_as,omitempty"` + // WASMByteCode can be raw or gzip compressed + WASMByteCode []byte `protobuf:"bytes,4,opt,name=wasm_byte_code,json=wasmByteCode,proto3" json:"wasm_byte_code,omitempty"` + // InstantiatePermission to apply on contract creation, optional + InstantiatePermission *AccessConfig `protobuf:"bytes,5,opt,name=instantiate_permission,json=instantiatePermission,proto3" json:"instantiate_permission,omitempty"` + // UnpinCode code on upload, optional + UnpinCode bool `protobuf:"varint,6,opt,name=unpin_code,json=unpinCode,proto3" json:"unpin_code,omitempty"` + // Admin is an optional address that can execute migrations + Admin string `protobuf:"bytes,7,opt,name=admin,proto3" json:"admin,omitempty"` + // Label is optional metadata to be stored with a constract instance. + Label string `protobuf:"bytes,8,opt,name=label,proto3" json:"label,omitempty"` + // Msg json encoded message to be passed to the contract on instantiation + Msg RawContractMessage `protobuf:"bytes,9,opt,name=msg,proto3,casttype=RawContractMessage" json:"msg,omitempty"` + // Funds coins that are transferred to the contract on instantiation + Funds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,10,rep,name=funds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"funds"` +} + +func (m *StoreAndInstantiateContractProposal) Reset() { *m = StoreAndInstantiateContractProposal{} } +func (*StoreAndInstantiateContractProposal) ProtoMessage() {} +func (*StoreAndInstantiateContractProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_be6422d717c730cb, []int{11} +} + +func (m *StoreAndInstantiateContractProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *StoreAndInstantiateContractProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StoreAndInstantiateContractProposal.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *StoreAndInstantiateContractProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_StoreAndInstantiateContractProposal.Merge(m, src) +} + +func (m *StoreAndInstantiateContractProposal) XXX_Size() int { + return m.Size() +} + +func (m *StoreAndInstantiateContractProposal) XXX_DiscardUnknown() { + xxx_messageInfo_StoreAndInstantiateContractProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_StoreAndInstantiateContractProposal proto.InternalMessageInfo + func init() { proto.RegisterType((*StoreCodeProposal)(nil), "cosmwasm.wasm.v1.StoreCodeProposal") proto.RegisterType((*InstantiateContractProposal)(nil), "cosmwasm.wasm.v1.InstantiateContractProposal") @@ -595,65 +657,68 @@ func init() { proto.RegisterType((*UnpinCodesProposal)(nil), "cosmwasm.wasm.v1.UnpinCodesProposal") proto.RegisterType((*AccessConfigUpdate)(nil), "cosmwasm.wasm.v1.AccessConfigUpdate") proto.RegisterType((*UpdateInstantiateConfigProposal)(nil), "cosmwasm.wasm.v1.UpdateInstantiateConfigProposal") + proto.RegisterType((*StoreAndInstantiateContractProposal)(nil), "cosmwasm.wasm.v1.StoreAndInstantiateContractProposal") } func init() { proto.RegisterFile("cosmwasm/wasm/v1/proposal.proto", fileDescriptor_be6422d717c730cb) } var fileDescriptor_be6422d717c730cb = []byte{ - // 834 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x8f, 0xdb, 0x44, - 0x14, 0xcf, 0xe4, 0x8f, 0x93, 0x9d, 0x8d, 0x20, 0xb8, 0xd9, 0x6d, 0x58, 0xc0, 0x8e, 0x0c, 0xaa, - 0x7c, 0xc1, 0x26, 0x8b, 0x84, 0x80, 0xdb, 0x3a, 0x70, 0xd8, 0x8a, 0x95, 0x56, 0x5e, 0xad, 0x2a, - 0x81, 0x84, 0x35, 0xb1, 0x67, 0x5d, 0x8b, 0xd8, 0x63, 0x79, 0xc6, 0x9b, 0xe6, 0x5b, 0x80, 0x84, - 0x38, 0xf5, 0x03, 0x20, 0x2e, 0x88, 0x3b, 0x1f, 0x60, 0xc5, 0xa9, 0xc7, 0x9e, 0x0c, 0x4d, 0xbe, - 0x41, 0x8e, 0x9c, 0xd0, 0xcc, 0x38, 0x21, 0xdb, 0xb2, 0x69, 0x11, 0x0d, 0x52, 0x2f, 0x4e, 0x66, - 0xde, 0x7b, 0xf3, 0x7e, 0xf3, 0xd3, 0xef, 0xbd, 0x37, 0x50, 0xf7, 0x09, 0x8d, 0x27, 0x88, 0xc6, - 0xb6, 0xf8, 0x5c, 0x0e, 0xec, 0x34, 0x23, 0x29, 0xa1, 0x68, 0x6c, 0xa5, 0x19, 0x61, 0x44, 0xed, - 0x2c, 0x1d, 0x2c, 0xf1, 0xb9, 0x1c, 0x1c, 0x74, 0x43, 0x12, 0x12, 0x61, 0xb4, 0xf9, 0x3f, 0xe9, - 0x77, 0xa0, 0x71, 0x3f, 0x42, 0xed, 0x11, 0xa2, 0xd8, 0xbe, 0x1c, 0x8c, 0x30, 0x43, 0x03, 0xdb, - 0x27, 0x51, 0x52, 0xda, 0xdf, 0x7e, 0x26, 0x11, 0x9b, 0xa6, 0x98, 0x4a, 0xab, 0xf1, 0xb0, 0x0a, - 0xdf, 0x38, 0x63, 0x24, 0xc3, 0x43, 0x12, 0xe0, 0xd3, 0x12, 0x81, 0xda, 0x85, 0x0d, 0x16, 0xb1, - 0x31, 0xee, 0x81, 0x3e, 0x30, 0x77, 0x5c, 0xb9, 0x50, 0xfb, 0x70, 0x37, 0xc0, 0xd4, 0xcf, 0xa2, - 0x94, 0x45, 0x24, 0xe9, 0x55, 0x85, 0x6d, 0x7d, 0x4b, 0xdd, 0x83, 0x4a, 0x96, 0x27, 0x1e, 0xa2, - 0xbd, 0x9a, 0x0c, 0xcc, 0xf2, 0xe4, 0x88, 0xaa, 0x1f, 0xc1, 0xd7, 0x78, 0x6e, 0x6f, 0x34, 0x65, - 0xd8, 0xf3, 0x49, 0x80, 0x7b, 0xf5, 0x3e, 0x30, 0xdb, 0x4e, 0x67, 0x56, 0xe8, 0xed, 0x7b, 0x47, - 0x67, 0x27, 0xce, 0x94, 0x09, 0x00, 0x6e, 0x9b, 0xfb, 0x2d, 0x57, 0xea, 0x39, 0xdc, 0x8f, 0x12, - 0xca, 0x50, 0xc2, 0x22, 0xc4, 0xb0, 0x97, 0xe2, 0x2c, 0x8e, 0x28, 0xe5, 0xb9, 0x9b, 0x7d, 0x60, - 0xee, 0x1e, 0x6a, 0xd6, 0xd3, 0x1c, 0x59, 0x47, 0xbe, 0x8f, 0x29, 0x1d, 0x92, 0xe4, 0x22, 0x0a, - 0xdd, 0xbd, 0xb5, 0xe8, 0xd3, 0x55, 0xb0, 0xfa, 0x0e, 0x84, 0x79, 0x92, 0x46, 0x89, 0x84, 0xd2, - 0xea, 0x03, 0xb3, 0xe5, 0xee, 0x88, 0x1d, 0x9e, 0xf5, 0x6e, 0xbd, 0xd5, 0xe8, 0x28, 0x77, 0xeb, - 0x2d, 0xa5, 0xd3, 0x34, 0x7e, 0xab, 0xc2, 0xb7, 0x8e, 0xff, 0x3e, 0x64, 0x48, 0x12, 0x96, 0x21, - 0x9f, 0x6d, 0x8b, 0xa8, 0x2e, 0x6c, 0xa0, 0x20, 0x8e, 0x12, 0xc1, 0xcf, 0x8e, 0x2b, 0x17, 0xea, - 0xbb, 0xb0, 0xc9, 0x91, 0x7a, 0x51, 0xd0, 0x6b, 0xf4, 0x81, 0x59, 0x77, 0xe0, 0xac, 0xd0, 0x15, - 0x8e, 0xf5, 0xf8, 0x33, 0x57, 0xe1, 0xa6, 0xe3, 0x80, 0x87, 0x8e, 0xd1, 0x08, 0x8f, 0x7b, 0x8a, - 0x0c, 0x15, 0x0b, 0xd5, 0x84, 0xb5, 0x98, 0x86, 0x82, 0xae, 0xb6, 0xb3, 0xff, 0x67, 0xa1, 0xab, - 0x2e, 0x9a, 0x2c, 0x6f, 0x71, 0x82, 0x29, 0x45, 0x21, 0x76, 0xb9, 0x8b, 0x8a, 0x60, 0xe3, 0x22, - 0x4f, 0x02, 0xda, 0x6b, 0xf5, 0x6b, 0xe6, 0xee, 0xe1, 0x9b, 0x96, 0x94, 0x95, 0xc5, 0x65, 0x65, - 0x95, 0xb2, 0xb2, 0x86, 0x24, 0x4a, 0x9c, 0x0f, 0xae, 0x0a, 0xbd, 0xf2, 0xd3, 0xef, 0xba, 0x19, - 0x46, 0xec, 0x7e, 0x3e, 0xb2, 0x7c, 0x12, 0xdb, 0xa5, 0x06, 0xe5, 0xcf, 0xfb, 0x34, 0xf8, 0xa6, - 0x14, 0x19, 0x0f, 0xa0, 0xae, 0x3c, 0xd9, 0xf8, 0x15, 0xc0, 0xdb, 0x27, 0x51, 0x98, 0xbd, 0x4c, - 0x22, 0x0f, 0x60, 0xcb, 0x2f, 0xcf, 0x2a, 0x49, 0x5b, 0xad, 0x5f, 0x8c, 0xb7, 0x92, 0x21, 0xe5, - 0xb9, 0x0c, 0x19, 0xdf, 0x03, 0xd8, 0x3d, 0xcb, 0x03, 0xb2, 0x15, 0xec, 0xb5, 0xa7, 0xb0, 0x97, - 0xb0, 0xea, 0xcf, 0x87, 0xf5, 0x5d, 0x15, 0xde, 0xfe, 0xfc, 0x01, 0xf6, 0xf3, 0xed, 0xcb, 0x73, - 0x13, 0xd9, 0x25, 0xe0, 0xc6, 0xbf, 0x50, 0x9a, 0xb2, 0x35, 0xa5, 0x3d, 0x04, 0xf0, 0xd6, 0x79, - 0x1a, 0x20, 0x86, 0x8f, 0x78, 0x05, 0xfd, 0x67, 0x3e, 0x06, 0x70, 0x27, 0xc1, 0x13, 0x4f, 0xd6, - 0xa6, 0xa0, 0xc4, 0xe9, 0x2e, 0x0a, 0xbd, 0x33, 0x45, 0xf1, 0xf8, 0x53, 0x63, 0x65, 0x32, 0xdc, - 0x56, 0x82, 0x27, 0x22, 0xe5, 0x26, 0xae, 0x8c, 0xfb, 0x50, 0x1d, 0x8e, 0x31, 0xca, 0x5e, 0x0e, - 0xb8, 0x0d, 0x32, 0x32, 0x7e, 0x06, 0xb0, 0x73, 0x2a, 0xfb, 0x1a, 0x5d, 0x25, 0xba, 0x73, 0x2d, - 0x91, 0xd3, 0x59, 0x14, 0x7a, 0x5b, 0xde, 0x44, 0x6c, 0x1b, 0xcb, 0xd4, 0x1f, 0xff, 0x43, 0x6a, - 0x67, 0x7f, 0x51, 0xe8, 0xaa, 0xf4, 0x5e, 0x33, 0x1a, 0xd7, 0x21, 0x7d, 0xc2, 0x21, 0x89, 0xca, - 0xe3, 0x0a, 0xaa, 0x99, 0x75, 0x47, 0x9b, 0x15, 0x7a, 0x53, 0x96, 0x1e, 0x5d, 0x14, 0xfa, 0xeb, - 0xf2, 0x84, 0xa5, 0x93, 0xe1, 0x36, 0x65, 0x39, 0x52, 0xe3, 0x17, 0x00, 0xd5, 0xf3, 0x65, 0x2f, - 0x7e, 0x45, 0x30, 0xff, 0x00, 0xa0, 0xba, 0x3e, 0x78, 0xa4, 0xf4, 0xd6, 0xfb, 0x0f, 0xb8, 0xb1, - 0xff, 0x7c, 0x75, 0xe3, 0x8c, 0xab, 0xbe, 0xc8, 0x8c, 0x73, 0xea, 0xbc, 0x46, 0x6e, 0x98, 0x74, - 0xc6, 0x1c, 0x40, 0x5d, 0x82, 0xb9, 0x3e, 0xc4, 0x2e, 0xa2, 0xf0, 0x7f, 0x64, 0xf6, 0x6b, 0xb8, - 0x87, 0x04, 0x64, 0xcf, 0x17, 0xa9, 0xbd, 0x5c, 0x40, 0x92, 0x34, 0xef, 0x1e, 0xbe, 0xb7, 0xf9, - 0x86, 0x12, 0x7f, 0x79, 0xcf, 0x5b, 0xe8, 0x19, 0x0b, 0x75, 0xbe, 0xb8, 0x7a, 0xa2, 0x55, 0x1e, - 0x3f, 0xd1, 0x2a, 0x3f, 0xce, 0x34, 0x70, 0x35, 0xd3, 0xc0, 0xa3, 0x99, 0x06, 0xfe, 0x98, 0x69, - 0xe0, 0xdb, 0xb9, 0x56, 0x79, 0x34, 0xd7, 0x2a, 0x8f, 0xe7, 0x5a, 0xe5, 0xcb, 0x3b, 0x6b, 0x4d, - 0x64, 0x48, 0x68, 0x7c, 0x6f, 0xf9, 0x24, 0x0a, 0xec, 0x07, 0xf2, 0x69, 0x24, 0x1a, 0xc9, 0x48, - 0x11, 0x0f, 0xa3, 0x0f, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x4f, 0xac, 0x4a, 0xb0, 0xa1, 0x09, - 0x00, 0x00, + // 877 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0xe3, 0x44, + 0x1c, 0xcf, 0xe4, 0xc3, 0x49, 0xa6, 0x11, 0x04, 0x6f, 0xda, 0x0d, 0x05, 0xec, 0xc8, 0x8b, 0x56, + 0xbe, 0xe0, 0x90, 0x22, 0x21, 0xe0, 0x16, 0x07, 0x0e, 0x5d, 0x51, 0xa9, 0x72, 0x55, 0xad, 0x04, + 0x12, 0xd1, 0xc4, 0x9e, 0x7a, 0x2d, 0xe2, 0x19, 0xcb, 0x33, 0x6e, 0xb7, 0x6f, 0x01, 0x12, 0xe2, + 0xb4, 0x0f, 0x80, 0xb8, 0x20, 0xee, 0x3c, 0x40, 0xc5, 0x69, 0x8f, 0x2b, 0x21, 0x19, 0x36, 0x7d, + 0x83, 0x1e, 0x39, 0xa1, 0x99, 0x71, 0xb2, 0x69, 0x77, 0xdb, 0xdd, 0x15, 0x4d, 0xa5, 0xbd, 0x38, + 0x99, 0xf9, 0x7f, 0xfd, 0xe6, 0xa7, 0xff, 0x17, 0x34, 0x7d, 0xca, 0xe2, 0x23, 0xc4, 0xe2, 0xbe, + 0xfc, 0x1c, 0x0e, 0xfa, 0x49, 0x4a, 0x13, 0xca, 0xd0, 0xd4, 0x49, 0x52, 0xca, 0xa9, 0xde, 0x9e, + 0x2b, 0x38, 0xf2, 0x73, 0x38, 0xd8, 0xec, 0x84, 0x34, 0xa4, 0x52, 0xd8, 0x17, 0xff, 0x94, 0xde, + 0xa6, 0x21, 0xf4, 0x28, 0xeb, 0x4f, 0x10, 0xc3, 0xfd, 0xc3, 0xc1, 0x04, 0x73, 0x34, 0xe8, 0xfb, + 0x34, 0x22, 0x85, 0xfc, 0xfd, 0xe7, 0x02, 0xf1, 0xe3, 0x04, 0x33, 0x25, 0xb5, 0x1e, 0x95, 0xe1, + 0x3b, 0x7b, 0x9c, 0xa6, 0x78, 0x44, 0x03, 0xbc, 0x5b, 0x20, 0xd0, 0x3b, 0xb0, 0xc6, 0x23, 0x3e, + 0xc5, 0x5d, 0xd0, 0x03, 0x76, 0xd3, 0x53, 0x07, 0xbd, 0x07, 0xd7, 0x02, 0xcc, 0xfc, 0x34, 0x4a, + 0x78, 0x44, 0x49, 0xb7, 0x2c, 0x65, 0xcb, 0x57, 0xfa, 0x3a, 0xd4, 0xd2, 0x8c, 0x8c, 0x11, 0xeb, + 0x56, 0x94, 0x61, 0x9a, 0x91, 0x21, 0xd3, 0x3f, 0x85, 0x6f, 0x89, 0xd8, 0xe3, 0xc9, 0x31, 0xc7, + 0x63, 0x9f, 0x06, 0xb8, 0x5b, 0xed, 0x01, 0xbb, 0xe5, 0xb6, 0x67, 0xb9, 0xd9, 0xba, 0x3f, 0xdc, + 0xdb, 0x71, 0x8f, 0xb9, 0x04, 0xe0, 0xb5, 0x84, 0xde, 0xfc, 0xa4, 0xef, 0xc3, 0x8d, 0x88, 0x30, + 0x8e, 0x08, 0x8f, 0x10, 0xc7, 0xe3, 0x04, 0xa7, 0x71, 0xc4, 0x98, 0x88, 0x5d, 0xef, 0x01, 0x7b, + 0x6d, 0xcb, 0x70, 0x2e, 0x72, 0xe4, 0x0c, 0x7d, 0x1f, 0x33, 0x36, 0xa2, 0xe4, 0x20, 0x0a, 0xbd, + 0xf5, 0x25, 0xeb, 0xdd, 0x85, 0xb1, 0xfe, 0x01, 0x84, 0x19, 0x49, 0x22, 0xa2, 0xa0, 0x34, 0x7a, + 0xc0, 0x6e, 0x78, 0x4d, 0x79, 0x23, 0xa2, 0xde, 0xab, 0x36, 0x6a, 0x6d, 0xed, 0x5e, 0xb5, 0xa1, + 0xb5, 0xeb, 0xd6, 0x9f, 0x65, 0xf8, 0xde, 0xf6, 0x33, 0x27, 0x23, 0x4a, 0x78, 0x8a, 0x7c, 0xbe, + 0x2a, 0xa2, 0x3a, 0xb0, 0x86, 0x82, 0x38, 0x22, 0x92, 0x9f, 0xa6, 0xa7, 0x0e, 0xfa, 0x1d, 0x58, + 0x17, 0x48, 0xc7, 0x51, 0xd0, 0xad, 0xf5, 0x80, 0x5d, 0x75, 0xe1, 0x2c, 0x37, 0x35, 0x81, 0x75, + 0xfb, 0x4b, 0x4f, 0x13, 0xa2, 0xed, 0x40, 0x98, 0x4e, 0xd1, 0x04, 0x4f, 0xbb, 0x9a, 0x32, 0x95, + 0x07, 0xdd, 0x86, 0x95, 0x98, 0x85, 0x92, 0xae, 0x96, 0xbb, 0xf1, 0x6f, 0x6e, 0xea, 0x1e, 0x3a, + 0x9a, 0xbf, 0x62, 0x07, 0x33, 0x86, 0x42, 0xec, 0x09, 0x15, 0x1d, 0xc1, 0xda, 0x41, 0x46, 0x02, + 0xd6, 0x6d, 0xf4, 0x2a, 0xf6, 0xda, 0xd6, 0xbb, 0x8e, 0x4a, 0x2b, 0x47, 0xa4, 0x95, 0x53, 0xa4, + 0x95, 0x33, 0xa2, 0x11, 0x71, 0x3f, 0x3e, 0xc9, 0xcd, 0xd2, 0xaf, 0x7f, 0x9b, 0x76, 0x18, 0xf1, + 0x07, 0xd9, 0xc4, 0xf1, 0x69, 0xdc, 0x2f, 0x72, 0x50, 0xfd, 0x7c, 0xc4, 0x82, 0xef, 0x8b, 0x24, + 0x13, 0x06, 0xcc, 0x53, 0x9e, 0xad, 0x3f, 0x00, 0xbc, 0xbd, 0x13, 0x85, 0xe9, 0x75, 0x12, 0xb9, + 0x09, 0x1b, 0x7e, 0xe1, 0xab, 0x20, 0x6d, 0x71, 0x7e, 0x35, 0xde, 0x0a, 0x86, 0xb4, 0x97, 0x32, + 0x64, 0xfd, 0x04, 0x60, 0x67, 0x2f, 0x0b, 0xe8, 0x4a, 0xb0, 0x57, 0x2e, 0x60, 0x2f, 0x60, 0x55, + 0x5f, 0x0e, 0xeb, 0xc7, 0x32, 0xbc, 0xfd, 0xd5, 0x43, 0xec, 0x67, 0xab, 0x4f, 0xcf, 0xab, 0xc8, + 0x2e, 0x00, 0xd7, 0x5e, 0x23, 0xd3, 0xb4, 0x95, 0x65, 0xda, 0x23, 0x00, 0x6f, 0xed, 0x27, 0x01, + 0xe2, 0x78, 0x28, 0x2a, 0xe8, 0x7f, 0xf3, 0x31, 0x80, 0x4d, 0x82, 0x8f, 0xc6, 0xaa, 0x36, 0x25, + 0x25, 0x6e, 0xe7, 0x2c, 0x37, 0xdb, 0xc7, 0x28, 0x9e, 0x7e, 0x61, 0x2d, 0x44, 0x96, 0xd7, 0x20, + 0xf8, 0x48, 0x86, 0xbc, 0x8a, 0x2b, 0xeb, 0x01, 0xd4, 0x47, 0x53, 0x8c, 0xd2, 0xeb, 0x01, 0x77, + 0x45, 0x1a, 0x59, 0xbf, 0x01, 0xd8, 0xde, 0x55, 0x7d, 0x8d, 0x2d, 0x02, 0xdd, 0x3d, 0x17, 0xc8, + 0x6d, 0x9f, 0xe5, 0x66, 0x4b, 0xbd, 0x44, 0x5e, 0x5b, 0xf3, 0xd0, 0x9f, 0xbd, 0x20, 0xb4, 0xbb, + 0x71, 0x96, 0x9b, 0xba, 0xd2, 0x5e, 0x12, 0x5a, 0xe7, 0x21, 0x7d, 0x2e, 0x20, 0xc9, 0xca, 0x13, + 0x19, 0x54, 0xb1, 0xab, 0xae, 0x31, 0xcb, 0xcd, 0xba, 0x2a, 0x3d, 0x76, 0x96, 0x9b, 0x6f, 0x2b, + 0x0f, 0x73, 0x25, 0xcb, 0xab, 0xab, 0x72, 0x64, 0xd6, 0xef, 0x00, 0xea, 0xfb, 0xf3, 0x5e, 0xfc, + 0x86, 0x60, 0xfe, 0x19, 0x40, 0x7d, 0x79, 0xf0, 0xa8, 0xd4, 0x5b, 0xee, 0x3f, 0xe0, 0xd2, 0xfe, + 0xf3, 0xed, 0xa5, 0x33, 0xae, 0xfc, 0x2a, 0x33, 0xce, 0xad, 0x8a, 0x1a, 0xb9, 0x64, 0xd2, 0x59, + 0xa7, 0x00, 0x9a, 0x0a, 0xcc, 0xf9, 0x21, 0x76, 0x10, 0x85, 0x37, 0xc8, 0xec, 0x77, 0x70, 0x1d, + 0x49, 0xc8, 0x63, 0x5f, 0x86, 0x1e, 0x67, 0x12, 0x92, 0xa2, 0x79, 0x6d, 0xeb, 0xc3, 0xab, 0x5f, + 0xa8, 0xf0, 0x17, 0xef, 0xbc, 0x85, 0x9e, 0x93, 0x30, 0xeb, 0xaf, 0x0a, 0xbc, 0x23, 0x77, 0x98, + 0x21, 0x09, 0x6e, 0x70, 0x58, 0x5f, 0xff, 0x56, 0x53, 0xbb, 0xbe, 0xad, 0x46, 0xbb, 0xb0, 0xd5, + 0x3c, 0x5b, 0x2d, 0xea, 0xcb, 0xab, 0xc5, 0x62, 0x6b, 0x68, 0xbc, 0x60, 0x6b, 0x68, 0xbe, 0x46, + 0x2f, 0x87, 0xab, 0xea, 0xe5, 0xee, 0xd7, 0x27, 0x4f, 0x8d, 0xd2, 0x93, 0xa7, 0x46, 0xe9, 0x97, + 0x99, 0x01, 0x4e, 0x66, 0x06, 0x78, 0x3c, 0x33, 0xc0, 0x3f, 0x33, 0x03, 0xfc, 0x70, 0x6a, 0x94, + 0x1e, 0x9f, 0x1a, 0xa5, 0x27, 0xa7, 0x46, 0xe9, 0x9b, 0xbb, 0x4b, 0x6e, 0x47, 0x94, 0xc5, 0xf7, + 0xe7, 0x0b, 0x6f, 0xd0, 0x7f, 0xa8, 0x16, 0x5f, 0xe9, 0x7a, 0xa2, 0xc9, 0xb5, 0xf7, 0x93, 0xff, + 0x02, 0x00, 0x00, 0xff, 0xff, 0x50, 0x71, 0x76, 0x67, 0x7f, 0x0b, 0x00, 0x00, } func (this *StoreCodeProposal) Equal(that interface{}) bool { @@ -1064,6 +1129,63 @@ func (this *UpdateInstantiateConfigProposal) Equal(that interface{}) bool { return true } +func (this *StoreAndInstantiateContractProposal) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*StoreAndInstantiateContractProposal) + if !ok { + that2, ok := that.(StoreAndInstantiateContractProposal) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Title != that1.Title { + return false + } + if this.Description != that1.Description { + return false + } + if this.RunAs != that1.RunAs { + return false + } + if !bytes.Equal(this.WASMByteCode, that1.WASMByteCode) { + return false + } + if !this.InstantiatePermission.Equal(that1.InstantiatePermission) { + return false + } + if this.UnpinCode != that1.UnpinCode { + return false + } + if this.Admin != that1.Admin { + return false + } + if this.Label != that1.Label { + return false + } + if !bytes.Equal(this.Msg, that1.Msg) { + return false + } + if len(this.Funds) != len(that1.Funds) { + return false + } + for i := range this.Funds { + if !this.Funds[i].Equal(&that1.Funds[i]) { + return false + } + } + return true +} + func (m *StoreCodeProposal) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1694,6 +1816,114 @@ func (m *UpdateInstantiateConfigProposal) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *StoreAndInstantiateContractProposal) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StoreAndInstantiateContractProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreAndInstantiateContractProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Funds) > 0 { + for iNdEx := len(m.Funds) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Funds[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProposal(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } + } + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x4a + } + if len(m.Label) > 0 { + i -= len(m.Label) + copy(dAtA[i:], m.Label) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Label))) + i-- + dAtA[i] = 0x42 + } + if len(m.Admin) > 0 { + i -= len(m.Admin) + copy(dAtA[i:], m.Admin) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Admin))) + i-- + dAtA[i] = 0x3a + } + if m.UnpinCode { + i-- + if m.UnpinCode { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if m.InstantiatePermission != nil { + { + size, err := m.InstantiatePermission.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProposal(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.WASMByteCode) > 0 { + i -= len(m.WASMByteCode) + copy(dAtA[i:], m.WASMByteCode) + i = encodeVarintProposal(dAtA, i, uint64(len(m.WASMByteCode))) + i-- + dAtA[i] = 0x22 + } + if len(m.RunAs) > 0 { + i -= len(m.RunAs) + copy(dAtA[i:], m.RunAs) + i = encodeVarintProposal(dAtA, i, uint64(len(m.RunAs))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintProposal(dAtA []byte, offset int, v uint64) int { offset -= sovProposal(v) base := offset @@ -1999,6 +2229,56 @@ func (m *UpdateInstantiateConfigProposal) Size() (n int) { return n } +func (m *StoreAndInstantiateContractProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.RunAs) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.WASMByteCode) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if m.InstantiatePermission != nil { + l = m.InstantiatePermission.Size() + n += 1 + l + sovProposal(uint64(l)) + } + if m.UnpinCode { + n += 2 + } + l = len(m.Admin) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Label) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if len(m.Funds) > 0 { + for _, e := range m.Funds { + l = e.Size() + n += 1 + l + sovProposal(uint64(l)) + } + } + return n +} + func sovProposal(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -4130,6 +4410,375 @@ func (m *UpdateInstantiateConfigProposal) Unmarshal(dAtA []byte) error { return nil } +func (m *StoreAndInstantiateContractProposal) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StoreAndInstantiateContractProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoreAndInstantiateContractProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunAs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RunAs = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WASMByteCode", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WASMByteCode = append(m.WASMByteCode[:0], dAtA[iNdEx:postIndex]...) + if m.WASMByteCode == nil { + m.WASMByteCode = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstantiatePermission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InstantiatePermission == nil { + m.InstantiatePermission = &AccessConfig{} + } + if err := m.InstantiatePermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UnpinCode", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.UnpinCode = bool(v != 0) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Admin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Label", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Label = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Funds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Funds = append(m.Funds, types.Coin{}) + if err := m.Funds[len(m.Funds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProposal(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProposal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + func skipProposal(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/wasm/types/proposal_test.go b/x/wasm/types/proposal_test.go index fcc378d390..6657d11412 100644 --- a/x/wasm/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -254,6 +254,120 @@ func TestValidateInstantiateContractProposal(t *testing.T) { } } +func TestValidateStoreAndInstantiateContractProposal(t *testing.T) { + var ( + anyAddress sdk.AccAddress = bytes.Repeat([]byte{0x0}, ContractAddrLen) + invalidAddress = "invalid address" + ) + + specs := map[string]struct { + src *StoreAndInstantiateContractProposal + expErr bool + }{ + "all good": { + src: StoreAndInstantiateContractProposalFixture(), + }, + "with instantiate permission": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + accessConfig := AccessTypeOnlyAddress.With(anyAddress) + p.InstantiatePermission = &accessConfig + }), + }, + "base data missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Title = "" + }), + expErr: true, + }, + "run_as missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.RunAs = "" + }), + expErr: true, + }, + "run_as invalid": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.RunAs = invalidAddress + }), + expErr: true, + }, + "wasm code missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.WASMByteCode = nil + }), + expErr: true, + }, + "wasm code invalid": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.WASMByteCode = bytes.Repeat([]byte{0x0}, MaxWasmSize+1) + }), + expErr: true, + }, + "with invalid instantiate permission": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.InstantiatePermission = &AccessConfig{} + }), + expErr: true, + }, + "without admin": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Admin = "" + }), + }, + "without init msg": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Msg = nil + }), + expErr: true, + }, + "with invalid init msg": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Msg = []byte("not a json string") + }), + expErr: true, + }, + "without init funds": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Funds = nil + }), + }, + "admin invalid": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Admin = invalidAddress + }), + expErr: true, + }, + "label empty": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Label = "" + }), + expErr: true, + }, + "init funds negative": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Funds = sdk.Coins{{Denom: "foo", Amount: sdk.NewInt(-1)}} + }), + expErr: true, + }, + "init funds with duplicates": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Funds = sdk.Coins{{Denom: "foo", Amount: sdk.NewInt(1)}, {Denom: "foo", Amount: sdk.NewInt(2)}} + }), + expErr: true, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + err := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + func TestValidateMigrateContractProposal(t *testing.T) { invalidAddress := "invalid address2" diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index 22da3520d6..c37b6d9ddf 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -247,6 +247,41 @@ func InstantiateContractProposalFixture(mutators ...func(p *InstantiateContractP return p } +func StoreAndInstantiateContractProposalFixture(mutators ...func(p *StoreAndInstantiateContractProposal)) *StoreAndInstantiateContractProposal { + var ( + anyValidAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, ContractAddrLen) + + initMsg = struct { + Verifier sdk.AccAddress `json:"verifier"` + Beneficiary sdk.AccAddress `json:"beneficiary"` + }{ + Verifier: anyValidAddress, + Beneficiary: anyValidAddress, + } + ) + const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" + + initMsgBz, err := json.Marshal(initMsg) + if err != nil { + panic(err) + } + p := &StoreAndInstantiateContractProposal{ + Title: "Foo", + Description: "Bar", + RunAs: anyAddress, + WASMByteCode: []byte{0x0}, + Admin: anyAddress, + Label: "testing", + Msg: initMsgBz, + Funds: nil, + } + + for _, m := range mutators { + m(p) + } + return p +} + func MigrateContractProposalFixture(mutators ...func(p *MigrateContractProposal)) *MigrateContractProposal { var ( anyValidAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, ContractAddrLen) From f532c8f8164bdac93367371aa23a78fa7de20f92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:05:10 +0000 Subject: [PATCH 022/294] Bump github.com/spf13/viper from 1.13.0 to 1.14.0 Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 18 +++++++++--------- go.sum | 36 +++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 8222d96353..8f8e9be538 100644 --- a/go.mod +++ b/go.mod @@ -23,13 +23,13 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.5.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.13.0 - github.com/stretchr/testify v1.8.0 + github.com/spf13/viper v1.14.0 + github.com/stretchr/testify v1.8.1 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca github.com/tendermint/tendermint v0.34.22 github.com/tendermint/tm-db v0.6.7 - google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b - google.golang.org/grpc v1.50.0 + google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e + google.golang.org/grpc v1.50.1 gopkg.in/yaml.v2 v2.4.0 ) @@ -61,7 +61,7 @@ require ( github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -107,7 +107,7 @@ require ( github.com/rs/cors v1.8.2 // indirect github.com/rs/zerolog v1.27.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/afero v1.9.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/tendermint/btcd v0.1.1 // indirect @@ -117,10 +117,10 @@ require ( go.etcd.io/bbolt v1.3.6 // indirect golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect - golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect + golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect + golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/text v0.4.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 4eace7260b..d4e73f726b 100644 --- a/go.sum +++ b/go.sum @@ -245,8 +245,8 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -714,8 +714,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -731,8 +731,8 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= -github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= +github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= +github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= @@ -741,8 +741,9 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -750,8 +751,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= @@ -922,8 +924,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= -golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1015,10 +1017,9 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U= -golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= @@ -1031,8 +1032,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1095,7 +1097,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1165,8 +1167,8 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b h1:SfSkJugek6xm7lWywqth4r2iTrYLpD8lOj1nMIIhMNM= -google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From c0a482ef364476002167cdc8525bef1c998d8397 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:05:58 +0100 Subject: [PATCH 023/294] Authz redesign: CLI implementation (#1079) * Add contract authz proto * Implement contract autorization * Register contract authz * Add contract-authz tests * Consume gas for contract authz * Add contract authz cli * Update cli usage * Model spike * Add max funds limit * Redesign authz model * Start e2e test * Full e2e test * Add cli implementation for signle grant case * Restore file to avoid merge conflicts * Test filter and limits * Add allow-al-messages flag * Add cli implementation for signle grant case * Add allow-al-messages flag * Implement comments fixes * Test accept * Fix description * No linter warning * Fix flags and add example command * Fix lint error * Fix limits cli * Add cli implementation for signle grant case * Add allow-al-messages flag * Implement comments fixes * Fix flags and add example command * Fix lint error * Fix limits cli * Add cli implementation for signle grant case * Add allow-al-messages flag * Implement comments fixes * Fix flags and add example command * Fix lint error * Fix limits cli * Fix comments Co-authored-by: Giancarlos Salas Co-authored-by: Alex Peters --- x/wasm/client/cli/tx.go | 120 +++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index d8227f7cd3..13a7005770 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strconv" + "time" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -13,6 +14,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/authz" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -32,9 +34,13 @@ const ( flagInstantiateByAddress = "instantiate-only-address" flagInstantiateByAnyOfAddress = "instantiate-anyof-addresses" flagUnpinCode = "unpin-code" - flagAllowedMsgs = "allow-msgs" - flagRunOnce = "run-once" + flagAllowedMsgKeys = "allow-msg-keys" + flagAllowedRawMsgs = "allow-raw-msgs" flagExpiration = "expiration" + flagMaxCalls = "max-calls" + flagMaxFunds = "max-funds" + flagAllowAllMsgs = "allow-all-messages" + flagNoTokenTransfer = "no-token-transfer" //nolint:gosec ) // GetTxCmd returns the transaction commands for this module @@ -384,9 +390,17 @@ func parseExecuteArgs(contractAddr string, execMsg string, sender sdk.AccAddress func GrantAuthorizationCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "grant [grantee] [contract_addr_bech32] --allow-msgs [msg1,msg2,...]", + Use: "grant [grantee] [message_type=\"execution\"|\"migration\"] [contract_addr_bech32] --allow-raw-msgs [msg1,msg2,...] --allow-msg-keys [key1,key2,...] --allow-all-messages", Short: "Grant authorization to an address", - Args: cobra.ExactArgs(2), + Long: fmt.Sprintf(`Grant authorization to an address. +Examples: +$ %s tx grant execution --allow-all-messages --maxCalls 1 --no-token-transfer --expiration 1667979596 + +$ %s tx grant execution --allow-all-messages --maxFunds 100000uwasm --expiration 1667979596 + +$ %s tx grant execution --allow-all-messages --maxCalls 5 --maxFunds 100000uwasm --expiration 1667979596 +`, version.AppName, version.AppName, version.AppName), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -398,17 +412,27 @@ func GrantAuthorizationCmd() *cobra.Command { return err } - contract, err := sdk.AccAddressFromBech32(args[1]) + contract, err := sdk.AccAddressFromBech32(args[2]) + if err != nil { + return err + } + + msgKeys, err := cmd.Flags().GetStringSlice(flagAllowedMsgKeys) if err != nil { return err } - msgs, err := cmd.Flags().GetStringSlice(flagAllowedMsgs) + rawMsgs, err := cmd.Flags().GetStringSlice(flagAllowedRawMsgs) if err != nil { return err } - once, err := cmd.Flags().GetBool(flagRunOnce) + maxFundsStr, err := cmd.Flags().GetString(flagMaxFunds) + if err != nil { + return fmt.Errorf("max funds: %s", err) + } + + maxCalls, err := cmd.Flags().GetUint64(flagMaxCalls) if err != nil { return err } @@ -420,18 +444,84 @@ func GrantAuthorizationCmd() *cobra.Command { if exp == 0 { return errors.New("expiration must be set") } - _ = clientCtx - _ = grantee - _ = msgs - _ = once - _ = contract - return errors.New("not implemented") + allowAllMsgs, err := cmd.Flags().GetBool(flagAllowAllMsgs) + if err != nil { + return err + } + + noTokenTransfer, err := cmd.Flags().GetBool(flagNoTokenTransfer) + if err != nil { + return err + } + + var limit types.ContractAuthzLimitX + switch { + case maxFundsStr != "" && maxCalls != 0 && !noTokenTransfer: + maxFunds, err := sdk.ParseCoinsNormalized(maxFundsStr) + if err != nil { + return fmt.Errorf("max funds: %s", err) + } + limit = types.NewCombinedLimit(maxCalls, maxFunds...) + case maxFundsStr != "" && maxCalls == 0 && !noTokenTransfer: + maxFunds, err := sdk.ParseCoinsNormalized(maxFundsStr) + if err != nil { + return fmt.Errorf("max funds: %s", err) + } + limit = types.NewMaxFundsLimit(maxFunds...) + case maxCalls != 0 && noTokenTransfer && maxFundsStr == "": + limit = types.NewMaxCallsLimit(maxCalls) + default: + return errors.New("invalid limit setup") + } + + var filter types.ContractAuthzFilterX + switch { + case allowAllMsgs && len(msgKeys) != 0 || allowAllMsgs && len(rawMsgs) != 0 || len(msgKeys) != 0 && len(rawMsgs) != 0: + return errors.New("cannot set more than one filter within one grant") + case allowAllMsgs: + filter = types.NewAllowAllMessagesFilter() + case len(msgKeys) != 0: + filter = types.NewAcceptedMessageKeysFilter(msgKeys...) + case len(rawMsgs) != 0: + msgs := make([]types.RawContractMessage, len(rawMsgs)) + for i, msg := range rawMsgs { + msgs[i] = types.RawContractMessage(msg) + } + filter = types.NewAcceptedMessagesFilter(msgs...) + default: + return errors.New("invalid filter setup") + } + + grant, err := types.NewContractGrant(contract, limit, filter) + if err != nil { + return err + } + + var authorization authz.Authorization + switch args[1] { + case "execution": + authorization = types.NewContractExecutionAuthorization(*grant) + case "migration": + authorization = types.NewContractMigrationAuthorization(*grant) + default: + return fmt.Errorf("%s authorization type not supported", args[1]) + } + + grantMsg, err := authz.NewMsgGrant(clientCtx.GetFromAddress(), grantee, authorization, time.Unix(0, exp)) + if err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), grantMsg) }, } flags.AddTxFlagsToCmd(cmd) - cmd.Flags().StringSlice(flagAllowedMsgs, []string{}, "Allowed msgs") - cmd.Flags().Bool(flagRunOnce, false, "Allow to execute only once") + cmd.Flags().StringSlice(flagAllowedMsgKeys, []string{}, "Allowed msg keys") + cmd.Flags().StringSlice(flagAllowedRawMsgs, []string{}, "Allowed raw msgs") + cmd.Flags().Uint64(flagMaxCalls, 0, "Maximal number of calls to the contract") + cmd.Flags().String(flagMaxFunds, "", "Maximal amount of tokens transferable to the contract.") cmd.Flags().Int64(flagExpiration, 0, "The Unix timestamp.") + cmd.Flags().Bool(flagAllowAllMsgs, false, "Allow all messages") + cmd.Flags().Bool(flagNoTokenTransfer, false, "Don't allow token transfer") return cmd } From f1f36c760828521b848ce840bb574a45a09f0c93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 08:02:50 +0000 Subject: [PATCH 024/294] Bump github.com/cosmos/gogoproto from 1.4.2 to 1.4.3 Bumps [github.com/cosmos/gogoproto](https://github.com/cosmos/gogoproto) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/cosmos/gogoproto/releases) - [Changelog](https://github.com/cosmos/gogoproto/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/gogoproto/compare/v1.4.2...v1.4.3) --- updated-dependencies: - dependency-name: github.com/cosmos/gogoproto dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8f8e9be538..7232deb0cd 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/CosmWasm/wasmvm v1.1.1 github.com/cosmos/cosmos-proto v1.0.0-alpha8 github.com/cosmos/cosmos-sdk v0.45.10 - github.com/cosmos/gogoproto v1.4.2 + github.com/cosmos/gogoproto v1.4.3 github.com/cosmos/iavl v0.19.4 github.com/cosmos/ibc-go/v3 v3.3.1 github.com/cosmos/interchain-accounts v0.1.0 diff --git a/go.sum b/go.sum index d4e73f726b..af0efbc65a 100644 --- a/go.sum +++ b/go.sum @@ -169,8 +169,8 @@ github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpF github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/gogoproto v1.4.2 h1:UeGRcmFW41l0G0MiefWhkPEVEwvu78SZsHBvI78dAYw= -github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.3 h1:RP3yyVREh9snv/lsOvmsAPQt8f44LgL281X0IOIhhcI= +github.com/cosmos/gogoproto v1.4.3/go.mod h1:0hLIG5TR7IvV1fme1HCFKjfzW9X2x0Mo+RooWXCnOWU= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= From df4fa9c8bd624bd05f783e31b1e8cd59eb3306db Mon Sep 17 00:00:00 2001 From: Giancarlos Salas Date: Tue, 15 Nov 2022 16:06:07 -0600 Subject: [PATCH 025/294] Update authz grant examples --- x/wasm/client/cli/tx.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 13a7005770..35ccd7c1c7 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -394,11 +394,11 @@ func GrantAuthorizationCmd() *cobra.Command { Short: "Grant authorization to an address", Long: fmt.Sprintf(`Grant authorization to an address. Examples: -$ %s tx grant execution --allow-all-messages --maxCalls 1 --no-token-transfer --expiration 1667979596 +$ %s tx grant execution --allow-all-messages --max-calls 1 --no-token-transfer --expiration 1667979596 -$ %s tx grant execution --allow-all-messages --maxFunds 100000uwasm --expiration 1667979596 +$ %s tx grant execution --allow-all-messages --max-funds 100000uwasm --expiration 1667979596 -$ %s tx grant execution --allow-all-messages --maxCalls 5 --maxFunds 100000uwasm --expiration 1667979596 +$ %s tx grant execution --allow-all-messages --max-calls 5 --max-funds 100000uwasm --expiration 1667979596 `, version.AppName, version.AppName, version.AppName), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { From ab4ffa51e651a9a21095dbb102a032d62b11729c Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:19:57 +0100 Subject: [PATCH 026/294] Enable larger wasm bytecode upload for gov proposals (#1095) * Enable larger wasm bytecode upload for gov proposals * Set max proposal wasm code size to 3MB --- README.md | 1 + x/wasm/types/genesis.go | 2 +- x/wasm/types/genesis_test.go | 2 +- x/wasm/types/proposal.go | 4 ++-- x/wasm/types/proposal_test.go | 4 ++-- x/wasm/types/tx.go | 2 +- x/wasm/types/validation.go | 9 ++++++--- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c8fc9549f5..fe0f6e3e2d 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,7 @@ file of your custom chain. * `wasmtypes.MaxLabelSize = 64` to set the maximum label size on instantiation (default 128) * `wasmtypes.MaxWasmSize=777000` to set the max size of compiled wasm to be accepted (default 819200) +* `wasmtypes.MaxProposalWasmSize=888000` to set the max size of gov proposal compiled wasm to be accepted (default 3145728) ## Genesis Configuration We strongly suggest **to limit the max block gas in the genesis** and not use the default value (`-1` for infinite). diff --git a/x/wasm/types/genesis.go b/x/wasm/types/genesis.go index a82893bd90..4d6775d02e 100644 --- a/x/wasm/types/genesis.go +++ b/x/wasm/types/genesis.go @@ -47,7 +47,7 @@ func (c Code) ValidateBasic() error { if err := c.CodeInfo.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "code info") } - if err := validateWasmCode(c.CodeBytes); err != nil { + if err := validateWasmCode(c.CodeBytes, MaxProposalWasmSize); err != nil { return sdkerrors.Wrap(err, "code bytes") } return nil diff --git a/x/wasm/types/genesis_test.go b/x/wasm/types/genesis_test.go index 5ddcb20885..f45d3f07f0 100644 --- a/x/wasm/types/genesis_test.go +++ b/x/wasm/types/genesis_test.go @@ -117,7 +117,7 @@ func TestCodeValidateBasic(t *testing.T) { }, "codeBytes greater limit": { srcMutator: func(c *Code) { - c.CodeBytes = bytes.Repeat([]byte{0x1}, MaxWasmSize+1) + c.CodeBytes = bytes.Repeat([]byte{0x1}, MaxProposalWasmSize+1) }, expError: true, }, diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index 0b8f943264..e56300a911 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -119,7 +119,7 @@ func (p StoreCodeProposal) ValidateBasic() error { return sdkerrors.Wrap(err, "run as") } - if err := validateWasmCode(p.WASMByteCode); err != nil { + if err := validateWasmCode(p.WASMByteCode, MaxProposalWasmSize); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "code bytes %s", err.Error()) } @@ -303,7 +303,7 @@ func (p StoreAndInstantiateContractProposal) ValidateBasic() error { return sdkerrors.Wrap(err, "run as") } - if err := validateWasmCode(p.WASMByteCode); err != nil { + if err := validateWasmCode(p.WASMByteCode, MaxProposalWasmSize); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "code bytes %s", err.Error()) } diff --git a/x/wasm/types/proposal_test.go b/x/wasm/types/proposal_test.go index 6657d11412..245184752b 100644 --- a/x/wasm/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -138,7 +138,7 @@ func TestValidateStoreCodeProposal(t *testing.T) { }, "wasm code invalid": { src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { - p.WASMByteCode = bytes.Repeat([]byte{0x0}, MaxWasmSize+1) + p.WASMByteCode = bytes.Repeat([]byte{0x0}, MaxProposalWasmSize+1) }), expErr: true, }, @@ -299,7 +299,7 @@ func TestValidateStoreAndInstantiateContractProposal(t *testing.T) { }, "wasm code invalid": { src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { - p.WASMByteCode = bytes.Repeat([]byte{0x0}, MaxWasmSize+1) + p.WASMByteCode = bytes.Repeat([]byte{0x0}, MaxProposalWasmSize+1) }), expErr: true, }, diff --git a/x/wasm/types/tx.go b/x/wasm/types/tx.go index dd6f6284cd..6742224df7 100644 --- a/x/wasm/types/tx.go +++ b/x/wasm/types/tx.go @@ -60,7 +60,7 @@ func (msg MsgStoreCode) ValidateBasic() error { return err } - if err := validateWasmCode(msg.WASMByteCode); err != nil { + if err := validateWasmCode(msg.WASMByteCode, MaxWasmSize); err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "code bytes %s", err.Error()) } diff --git a/x/wasm/types/validation.go b/x/wasm/types/validation.go index 908c525524..cf6b1511b2 100644 --- a/x/wasm/types/validation.go +++ b/x/wasm/types/validation.go @@ -13,14 +13,17 @@ var ( // MaxWasmSize is the largest a compiled contract code can be when storing code on chain MaxWasmSize = 800 * 1024 // extension point for chains to customize via compile flag. + + // MaxProposalWasmSize is the largest a gov proposal compiled contract code can be when storing code on chain + MaxProposalWasmSize = 3 * 1024 * 1024 // extension point for chains to customize via compile flag. ) -func validateWasmCode(s []byte) error { +func validateWasmCode(s []byte, maxSize int) error { if len(s) == 0 { return sdkerrors.Wrap(ErrEmpty, "is required") } - if len(s) > MaxWasmSize { - return sdkerrors.Wrapf(ErrLimit, "cannot be longer than %d bytes", MaxWasmSize) + if len(s) > maxSize { + return sdkerrors.Wrapf(ErrLimit, "cannot be longer than %d bytes", maxSize) } return nil } From b063af76529b3ca2713567ab436966b0cbd7fe09 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 17 Nov 2022 14:30:13 +0100 Subject: [PATCH 027/294] Bump SDK to v0.45.11 --- go.mod | 20 ++++++++++---------- go.sum | 46 +++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 7232deb0cd..8c764de454 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/CosmWasm/wasmvm v1.1.1 github.com/cosmos/cosmos-proto v1.0.0-alpha8 - github.com/cosmos/cosmos-sdk v0.45.10 + github.com/cosmos/cosmos-sdk v0.45.11 github.com/cosmos/gogoproto v1.4.3 github.com/cosmos/iavl v0.19.4 github.com/cosmos/ibc-go/v3 v3.3.1 @@ -21,12 +21,12 @@ require ( github.com/rakyll/statik v0.1.7 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cast v1.5.0 - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.6.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.14.0 github.com/stretchr/testify v1.8.1 - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca - github.com/tendermint/tendermint v0.34.22 + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/tendermint/tendermint v0.34.23 github.com/tendermint/tm-db v0.6.7 google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e google.golang.org/grpc v1.50.1 @@ -84,7 +84,7 @@ require ( github.com/improbable-eng/grpc-web v0.14.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.15.9 // indirect + github.com/klauspost/compress v1.15.11 // indirect github.com/lib/pq v1.10.6 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -115,13 +115,13 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/zondax/hid v0.9.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect + golang.org/x/crypto v0.1.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect - golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect - golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect + golang.org/x/net v0.1.0 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/term v0.1.0 // indirect golang.org/x/text v0.4.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect diff --git a/go.sum b/go.sum index af0efbc65a..ae438b7c41 100644 --- a/go.sum +++ b/go.sum @@ -65,7 +65,7 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -162,8 +162,8 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= -github.com/cosmos/cosmos-sdk v0.45.10 h1:YRf1N6C7OFCc8FJ5wuhcnDDySJNDn5DxSscVgbeXgz4= -github.com/cosmos/cosmos-sdk v0.45.10/go.mod h1:CbfWNs4PuxxsvRD/snQuSBDwIhtsD7rIDTVQyYMKTa0= +github.com/cosmos/cosmos-sdk v0.45.11 h1:Pc44fFEkai0KXFND5Ys/2ZJkfVdstMIBzKBN8MY7Ll0= +github.com/cosmos/cosmos-sdk v0.45.11/go.mod h1:45z8Q1Ah4iypFycu2Kl4kBPIsQKUiND8G2CUX+HTtPM= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -214,7 +214,7 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= @@ -479,8 +479,8 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -587,7 +587,7 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -721,8 +721,8 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -756,16 +756,17 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjclr41o+2Q= -github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= +github.com/tendermint/tendermint v0.34.23 h1:JZYsdc59aOiT5efou+BHILJv8x6FlRyvlor84Xq9Tb0= +github.com/tendermint/tendermint v0.34.23/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= @@ -836,8 +837,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -876,6 +877,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -924,8 +926,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1018,12 +1020,13 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1093,6 +1096,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1183,8 +1187,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 632cd30d8d256030f92587ab2e907698d98e3bb7 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 17 Nov 2022 19:02:22 +0100 Subject: [PATCH 028/294] Fix license head --- LICENSE | 1 - 1 file changed, 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4e31b6cf9f..9c558055d5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,3 @@ -Cosmos-SDK License: Apache2.0 Apache License From c7a3d23e254e3d20accb021959fdd2dd54f3a94a Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 17 Nov 2022 19:07:17 +0100 Subject: [PATCH 029/294] Fix README header --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fe0f6e3e2d..2ed57987b4 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Wasm Zone -[![CircleCI](https://circleci.com/gh/CosmWasm/wasmd/tree/master.svg?style=shield)](https://circleci.com/gh/CosmWasm/wasmd/tree/master) -[![codecov](https://codecov.io/gh/cosmwasm/wasmd/branch/master/graph/badge.svg)](https://codecov.io/gh/cosmwasm/wasmd) +[![CircleCI](https://circleci.com/gh/CosmWasm/wasmd/tree/main.svg?style=shield)](https://circleci.com/gh/CosmWasm/wasmd/tree/main) +[![codecov](https://codecov.io/gh/cosmwasm/wasmd/branch/main/graph/badge.svg)](https://codecov.io/gh/cosmwasm/wasmd) [![Go Report Card](https://goreportcard.com/badge/github.com/CosmWasm/wasmd)](https://goreportcard.com/report/github.com/CosmWasm/wasmd) -[![license](https://img.shields.io/github/license/CosmWasm/wasmd.svg)](https://github.com/CosmWasm/wasmd/blob/master/LICENSE) +[![license](https://img.shields.io/github/license/CosmWasm/wasmd.svg)](https://github.com/CosmWasm/wasmd/blob/main/LICENSE) [![LoC](https://tokei.rs/b1/github/CosmWasm/wasmd)](https://github.com/CosmWasm/wasmd) From fc476aa886cc1df488c3dda3c543f23e57bac19d Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Fri, 18 Nov 2022 18:31:05 +0700 Subject: [PATCH 030/294] Bump version go to 1.19 (#1044) * bump go 1.19 * add change log * correct change log --- .circleci/config.yml | 2 +- CHANGELOG.md | 3 ++- Dockerfile | 2 +- README.md | 2 +- contrib/prototools-docker/Dockerfile | 2 +- go.mod | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9b226efb97..3003f55f72 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 executors: golang: docker: - - image: cimg/go:1.18 + - image: cimg/go:1.19 commands: make: diff --git a/CHANGELOG.md b/CHANGELOG.md index aa8937acb3..d347becf5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ - Allow AccessConfig to use a list of addresses instead of just a single address [\#945](https://github.com/CosmWasm/wasmd/issues/945) - Make contract addresses predictable \("deterministic"\) [\#942](https://github.com/CosmWasm/wasmd/issues/942) - Add query for the total supply of a coin [\#903](https://github.com/CosmWasm/wasmd/pull/903) ([larry0x](https://github.com/larry0x)) -- Upgrade go to v1.18 [\#866](https://github.com/CosmWasm/wasmd/pull/866/) ([faddat](https://github.com/faddat)) +- Upgrade go to v1.19 [\#1044](https://github.com/CosmWasm/wasmd/pull/1044) +- Upgrade go to v1.18 [\#866]https://github.com/CosmWasm/wasmd/pull/866/) ([faddat](https://github.com/faddat)) - Upgrade to ibc-go v3.3.0 REQUIRES [MIGRATION](https://github.com/cosmos/ibc-go/blob/v3.2.3/docs/migrations/support-denoms-with-slashes.md) [\#1016](https://github.com/CosmWasm/wasmd/pull/1016) - Upgrade to cosmos-sdk v0.45.8 [\#964](https://github.com/CosmWasm/wasmd/pull/964/) ([faddat](https://github.com/faddat)) - Upgrade wasmvm to v1.1.1 [\#1012](https://github.com/CosmWasm/wasmd/pull/1012), see [wasmvm v1.1.1](https://github.com/CosmWasm/wasmvm/releases/tag/v1.1.1) diff --git a/Dockerfile b/Dockerfile index 42494493c7..649cf7eb5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # docker build . -t cosmwasm/wasmd:latest # docker run --rm -it cosmwasm/wasmd:latest /bin/sh -FROM golang:1.18-alpine3.15 AS go-builder +FROM golang:1.19-alpine3.15 AS go-builder ARG arch=x86_64 # this comes from standard alpine nightly file diff --git a/README.md b/README.md index 2ed57987b4..ebdc070de3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This code was forked from the `cosmos/gaia` repository as a basis and then we ad many gaia-specific files. However, the `wasmd` binary should function just like `gaiad` except for the addition of the `x/wasm` module. -**Note**: Requires [Go 1.18+](https://golang.org/dl/) +**Note**: Requires [Go 1.19+](https://golang.org/dl/) For critical security issues & disclosure, see [SECURITY.md](SECURITY.md). ## Compatibility with CosmWasm contracts diff --git a/contrib/prototools-docker/Dockerfile b/contrib/prototools-docker/Dockerfile index 3ed6974c24..45cd04b87e 100644 --- a/contrib/prototools-docker/Dockerfile +++ b/contrib/prototools-docker/Dockerfile @@ -39,7 +39,7 @@ RUN GO111MODULE=on go get \ RUN upx --lzma /usr/local/bin/* -FROM golang:1.18-alpine +FROM golang:1.19-alpine ENV LD_LIBRARY_PATH=/lib64:/lib WORKDIR /work diff --git a/go.mod b/go.mod index 8c764de454..9f51efe1eb 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/CosmWasm/wasmd -go 1.18 +go 1.19 require ( github.com/CosmWasm/wasmvm v1.1.1 From e6f51498b66591d55c5e5073dad9cadaa1f9608a Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Tue, 22 Nov 2022 10:54:30 +0100 Subject: [PATCH 031/294] Upgrade to IBC v4.2.0 with interchain-accounts v0.2.4 (#1088) * Upgrade to IBC v4.2.0 with interchain-accounts v0.2.4 * Fix linter issues * Test version handshake * Add more ibc e2e scenarios * Add fee middleware to wasm * Get ibc app version from middleware --- app/ante.go | 4 +- app/app.go | 125 ++++++---- app/sim_test.go | 4 +- app/test_access.go | 4 +- app/test_helpers.go | 48 ++-- go.mod | 4 +- go.sum | 8 +- tests/e2e/ibc_fees_test.go | 214 ++++++++++++++++ tests/e2e/ica_test.go | 91 +++++++ tests/e2e/testdata/cw20_base.wasm.gz | Bin 0 -> 105532 bytes tests/e2e/testdata/cw20_ics20.wasm.gz | Bin 0 -> 119250 bytes x/wasm/ibc.go | 84 +++++-- x/wasm/ibc_integration_test.go | 126 ++++++++++ x/wasm/ibc_reflect_test.go | 4 +- x/wasm/ibc_test.go | 4 +- x/wasm/ibctesting/chain.go | 232 +++++++++++------- x/wasm/ibctesting/coordinator.go | 48 +--- x/wasm/ibctesting/endpoint.go | 94 +++++-- x/wasm/ibctesting/event_utils.go | 79 ++++-- x/wasm/ibctesting/path.go | 22 +- x/wasm/ibctesting/wasm.go | 2 +- x/wasm/keeper/handler_plugin.go | 4 +- x/wasm/keeper/handler_plugin_encoders.go | 6 +- x/wasm/keeper/handler_plugin_encoders_test.go | 6 +- x/wasm/keeper/handler_plugin_test.go | 6 +- x/wasm/keeper/ibc.go | 2 +- x/wasm/keeper/query_plugins.go | 2 +- x/wasm/keeper/query_plugins_test.go | 2 +- x/wasm/keeper/relay.go | 8 +- x/wasm/keeper/snapshotter_integration_test.go | 2 +- x/wasm/keeper/test_common.go | 60 ++--- x/wasm/keeper/wasmtesting/mock_engine.go | 53 ++++ x/wasm/keeper/wasmtesting/mock_keepers.go | 4 +- x/wasm/relay_pingpong_test.go | 13 +- x/wasm/relay_test.go | 8 +- x/wasm/types/expected_keepers.go | 6 +- 36 files changed, 1021 insertions(+), 358 deletions(-) create mode 100644 tests/e2e/ibc_fees_test.go create mode 100644 tests/e2e/ica_test.go create mode 100644 tests/e2e/testdata/cw20_base.wasm.gz create mode 100644 tests/e2e/testdata/cw20_ics20.wasm.gz create mode 100644 x/wasm/ibc_integration_test.go diff --git a/app/ante.go b/app/ante.go index 937f87fb9a..e5dd75a938 100644 --- a/app/ante.go +++ b/app/ante.go @@ -4,8 +4,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" - ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" - "github.com/cosmos/ibc-go/v3/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v4/modules/core/ante" + "github.com/cosmos/ibc-go/v4/modules/core/keeper" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types" diff --git a/app/app.go b/app/app.go index c81550fd22..569f22e490 100644 --- a/app/app.go +++ b/app/app.go @@ -74,24 +74,27 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" - icacontroller "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller" - icacontrollerkeeper "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/keeper" - icacontrollertypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/types" - icahost "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host" - icahostkeeper "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/keeper" - icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - transfer "github.com/cosmos/ibc-go/v3/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v3/modules/core" - ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client" - ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client" - ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" - ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + ica "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts" + icacontroller "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller" + icacontrollerkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" + ibcfee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee" + ibcfeekeeper "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/keeper" + ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + transfer "github.com/cosmos/ibc-go/v4/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v4/modules/core" + ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v4/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" // Note: please do your research before using this in production app, this is a demo and not an officially // supported IBC team implementation. It has no known issues, but do your own research before using it. @@ -207,6 +210,7 @@ var ( wasm.AppModuleBasic{}, ica.AppModuleBasic{}, intertx.AppModuleBasic{}, + ibcfee.AppModuleBasic{}, ) // module account permissions @@ -218,6 +222,7 @@ var ( stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + ibcfeetypes.ModuleName: nil, icatypes.ModuleName: nil, wasm.ModuleName: {authtypes.Burner}, } @@ -256,6 +261,7 @@ type WasmApp struct { ParamsKeeper paramskeeper.Keeper EvidenceKeeper evidencekeeper.Keeper IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + IBCFeeKeeper ibcfeekeeper.Keeper ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper InterTxKeeper intertxkeeper.Keeper @@ -269,6 +275,7 @@ type WasmApp struct { ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper ScopedInterTxKeeper capabilitykeeper.ScopedKeeper ScopedTransferKeeper capabilitykeeper.ScopedKeeper + ScopedIBCFeeKeeper capabilitykeeper.ScopedKeeper ScopedWasmKeeper capabilitykeeper.ScopedKeeper // the module manager @@ -308,7 +315,8 @@ func NewWasmApp( minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, - feegrant.StoreKey, authzkeeper.StoreKey, wasm.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, intertxtypes.StoreKey, + feegrant.StoreKey, authzkeeper.StoreKey, wasm.StoreKey, icahosttypes.StoreKey, + icacontrollertypes.StoreKey, intertxtypes.StoreKey, ibcfeetypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -443,20 +451,26 @@ func NewWasmApp( AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) + // IBC Fee Module keeper + app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( + appCodec, keys[ibcfeetypes.StoreKey], app.getSubspace(ibcfeetypes.ModuleName), + app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, + ) + // Create Transfer Keepers app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, keys[ibctransfertypes.StoreKey], app.getSubspace(ibctransfertypes.ModuleName), - app.IBCKeeper.ChannelKeeper, + app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, ) - transferModule := transfer.NewAppModule(app.TransferKeeper) - transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) app.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, @@ -472,23 +486,15 @@ func NewWasmApp( appCodec, keys[icacontrollertypes.StoreKey], app.getSubspace(icacontrollertypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee + app.IBCFeeKeeper, // use ics29 fee as ics4Wrapper in middleware stack app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, scopedICAControllerKeeper, app.MsgServiceRouter(), ) - icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) - icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) // For wasmd we use the demo controller from https://github.com/cosmos/interchain-accounts but see notes below app.InterTxKeeper = intertxkeeper.NewKeeper(appCodec, keys[intertxtypes.StoreKey], app.ICAControllerKeeper, scopedInterTxKeeper) - // Note: please do your research before using this in production app, this is a demo and not an officially - // supported IBC team implementation. Do your own research before using it. - interTxModule := intertx.NewAppModule(appCodec, app.InterTxKeeper) - interTxIBCModule := intertx.NewIBCModule(app.InterTxKeeper) - // You will likely want to swap out the second argument with your own reviewed and maintained ica auth module - icaControllerIBCModule := icacontroller.NewIBCModule(app.ICAControllerKeeper, interTxIBCModule) // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( @@ -528,19 +534,46 @@ func NewWasmApp( wasmOpts..., ) - // Create static IBC router, add app routes, then set and seal it - ibcRouter := porttypes.NewRouter() - // The gov proposal types can be individually enabled if len(enabledProposals) != 0 { govRouter.AddRoute(wasm.RouterKey, wasm.NewWasmProposalHandler(app.WasmKeeper, enabledProposals)) } - ibcRouter. - AddRoute(wasm.ModuleName, wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper)). - AddRoute(ibctransfertypes.ModuleName, transferIBCModule). - AddRoute(icacontrollertypes.SubModuleName, icaControllerIBCModule). - AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). - AddRoute(intertxtypes.ModuleName, icaControllerIBCModule) + + // Create Transfer Stack + var transferStack porttypes.IBCModule + transferStack = transfer.NewIBCModule(app.TransferKeeper) + transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) + + // Create Interchain Accounts Stack + // SendPacket, since it is originating from the application to core IBC: + // icaAuthModuleKeeper.SendTx -> icaController.SendPacket -> fee.SendPacket -> channel.SendPacket + + // Note: please do your research before using this in production app, this is a demo and not an officially + // supported IBC team implementation. Do your own research before using it. + var icaControllerStack porttypes.IBCModule + // You will likely want to use your own reviewed and maintained ica auth module + icaControllerStack = intertx.NewIBCModule(app.InterTxKeeper) + icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, app.ICAControllerKeeper) + icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) + + // RecvPacket, message that originates from core IBC and goes down to app, the flow is: + // channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket + var icaHostStack porttypes.IBCModule + icaHostStack = icahost.NewIBCModule(app.ICAHostKeeper) + icaHostStack = ibcfee.NewIBCMiddleware(icaHostStack, app.IBCFeeKeeper) + + // Create fee enabled wasm ibc Stack + var wasmStack porttypes.IBCModule + wasmStack = wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCFeeKeeper) + wasmStack = ibcfee.NewIBCMiddleware(wasmStack, app.IBCFeeKeeper) + + // Create static IBC router, add app routes, then set and seal it + ibcRouter := porttypes.NewRouter(). + AddRoute(ibctransfertypes.ModuleName, transferStack). + AddRoute(wasm.ModuleName, wasmStack). + AddRoute(intertxtypes.ModuleName, icaControllerStack). + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). + AddRoute(icahosttypes.SubModuleName, icaHostStack) app.IBCKeeper.SetRouter(ibcRouter) app.GovKeeper = govkeeper.NewKeeper( @@ -583,9 +616,10 @@ func NewWasmApp( authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), params.NewAppModule(app.ParamsKeeper), - transferModule, - icaModule, - interTxModule, + transfer.NewAppModule(app.TransferKeeper), + ibcfee.NewAppModule(app.IBCFeeKeeper), + ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + intertx.NewAppModule(appCodec, app.InterTxKeeper), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), // always be last to make sure that it checks for all invariants and not only part of them ) @@ -614,6 +648,7 @@ func NewWasmApp( ibctransfertypes.ModuleName, ibchost.ModuleName, icatypes.ModuleName, + ibcfeetypes.ModuleName, intertxtypes.ModuleName, wasm.ModuleName, ) @@ -639,6 +674,7 @@ func NewWasmApp( ibctransfertypes.ModuleName, ibchost.ModuleName, icatypes.ModuleName, + ibcfeetypes.ModuleName, intertxtypes.ModuleName, wasm.ModuleName, ) @@ -671,6 +707,7 @@ func NewWasmApp( ibctransfertypes.ModuleName, ibchost.ModuleName, icatypes.ModuleName, + ibcfeetypes.ModuleName, intertxtypes.ModuleName, // wasm after ibc transfer wasm.ModuleName, @@ -704,7 +741,7 @@ func NewWasmApp( evidence.NewAppModule(app.EvidenceKeeper), wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), ibc.NewAppModule(app.IBCKeeper), - transferModule, + transfer.NewAppModule(app.TransferKeeper), ) app.sm.RegisterStoreDecoders() diff --git a/app/sim_test.go b/app/sim_test.go index e80c6fcae7..5e206064e6 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -28,8 +28,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/simulation" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" diff --git a/app/test_access.go b/app/test_access.go index d992a89602..51b8bb9939 100644 --- a/app/test_access.go +++ b/app/test_access.go @@ -12,8 +12,8 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper" - ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" + ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" "github.com/CosmWasm/wasmd/x/wasm" ) diff --git a/app/test_helpers.go b/app/test_helpers.go index d15e155560..8c3e8c11e5 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -97,7 +97,7 @@ func Setup(isCheckTx bool, opts ...wasm.Option) *WasmApp { // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit (10^6) in the default token of the WasmApp from first genesis // account. A Nop logger is set in WasmApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, opts []wasm.Option, balances ...banktypes.Balance) *WasmApp { +func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasm.Option, balances ...banktypes.Balance) *WasmApp { app, genesisState := setup(t, true, 5, opts...) // set genesis accounts authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) @@ -106,7 +106,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) - bondAmt := sdk.NewInt(1000000) + bondAmt := sdk.TokensFromConsensusPower(1, sdk.DefaultPowerReduction) for _, val := range valSet.Validators { pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) @@ -126,30 +126,30 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), MinSelfDelegation: sdk.ZeroInt(), } + validators = append(validators, validator) delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec())) - } // set validators and delegations - stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) - genesisState[stakingtypes.ModuleName] = app.appCodec.MustMarshalJSON(stakingGenesis) + var stakingGenesis stakingtypes.GenesisState + app.AppCodec().MustUnmarshalJSON(genesisState[stakingtypes.ModuleName], &stakingGenesis) - totalSupply := sdk.NewCoins() - for _, b := range balances { - // add genesis acc tokens and delegated tokens to total supply - totalSupply = totalSupply.Add(b.Coins.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt))...) - } + bondDenom := stakingGenesis.Params.BondDenom // add bonded amount to bonded pool module account balances = append(balances, banktypes.Balance{ Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, + Coins: sdk.Coins{sdk.NewCoin(bondDenom, bondAmt.Mul(sdk.NewInt(int64(len(valSet.Validators)))))}, }) + // set validators and delegations + stakingGenesis = *stakingtypes.NewGenesisState(stakingGenesis.Params, validators, delegations) + genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(&stakingGenesis) + // update total supply - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}) - genesisState[banktypes.ModuleName] = app.appCodec.MustMarshalJSON(bankGenesis) + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, sdk.NewCoins(), []banktypes.Metadata{}) + genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) @@ -157,6 +157,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs // init chain will set the validator set and initialize the genesis accounts app.InitChain( abci.RequestInitChain{ + ChainId: chainID, Validators: []abci.ValidatorUpdate{}, ConsensusParams: DefaultConsensusParams, AppStateBytes: stateBytes, @@ -165,12 +166,17 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs // commit genesis changes app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ - Height: app.LastBlockHeight() + 1, - AppHash: app.LastCommitID().Hash, - ValidatorsHash: valSet.Hash(), - NextValidatorsHash: valSet.Hash(), - }}) + app.BeginBlock( + abci.RequestBeginBlock{ + Header: tmproto.Header{ + ChainID: chainID, + Height: app.LastBlockHeight() + 1, + AppHash: app.LastCommitID().Hash, + ValidatorsHash: valSet.Hash(), + NextValidatorsHash: valSet.Hash(), + }, + }, + ) return app } @@ -380,10 +386,6 @@ func SignAndDeliver( // Simulate a sending a transaction and committing a block app.BeginBlock(abci.RequestBeginBlock{Header: header}) gInfo, res, err := app.Deliver(txCfg.TxEncoder(), tx) - - app.EndBlock(abci.RequestEndBlock{}) - app.Commit() - return gInfo, res, err } diff --git a/go.mod b/go.mod index 9f51efe1eb..f7d483c3b7 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/cosmos/cosmos-sdk v0.45.11 github.com/cosmos/gogoproto v1.4.3 github.com/cosmos/iavl v0.19.4 - github.com/cosmos/ibc-go/v3 v3.3.1 - github.com/cosmos/interchain-accounts v0.1.0 + github.com/cosmos/ibc-go/v4 v4.2.0 + github.com/cosmos/interchain-accounts v0.2.4 github.com/dvsekhvalnov/jose2go v1.5.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 diff --git a/go.sum b/go.sum index ae438b7c41..a2fe53b4a0 100644 --- a/go.sum +++ b/go.sum @@ -175,10 +175,10 @@ github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4 github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v3 v3.3.1 h1:i8o3iPSPN8fr7AjCPQnHEKz/VfeMrxc8mjvgAw6txWk= -github.com/cosmos/ibc-go/v3 v3.3.1/go.mod h1:V1nliDk/5q5KWr0mup7M76oN4SY0IOU371SKbCV2wN0= -github.com/cosmos/interchain-accounts v0.1.0 h1:QmuwNsf1Hxl3P5GSGt7Z+JeuHPiZw4Z34R/038P5T6s= -github.com/cosmos/interchain-accounts v0.1.0/go.mod h1:Fv6LXDs+0ng4mIDVWwEJMXbAIMxY4kiq+A7Bw1Fb9AY= +github.com/cosmos/ibc-go/v4 v4.2.0 h1:Fx/kKq/uvawrAxk6ZrQ6sEIgffLRU5Cs/AUnvpPBrHI= +github.com/cosmos/ibc-go/v4 v4.2.0/go.mod h1:57qWScDtfCx3FOMLYmBIKPbOLE6xiVhrgxHAQmbWYXM= +github.com/cosmos/interchain-accounts v0.2.4 h1:7UrroFQsCRSp17980mk6anx4YteveIJVkU+a0wlsHQI= +github.com/cosmos/interchain-accounts v0.2.4/go.mod h1:jeiJEb0zg609G0oCrCG0r6Guhb7YbA1uFiwww/1YgZE= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= diff --git a/tests/e2e/ibc_fees_test.go b/tests/e2e/ibc_fees_test.go new file mode 100644 index 0000000000..fa315ffe60 --- /dev/null +++ b/tests/e2e/ibc_fees_test.go @@ -0,0 +1,214 @@ +package e2e + +import ( + "bytes" + "encoding/base64" + "fmt" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + ibcfee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/CosmWasm/wasmd/app" + wasmibctesting "github.com/CosmWasm/wasmd/x/wasm/ibctesting" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func TestIBCFeesTransfer(t *testing.T) { + // scenario: + // given 2 chains + // with an ics-20 channel established + // when an ics-29 fee is attached to an ibc package + // then the relayer's payee is receiving the fee(s) on success + marshaler := app.MakeEncodingConfig().Marshaler + coord := wasmibctesting.NewCoordinator(t, 2) + chainA := coord.GetChain(ibctesting.GetChainID(0)) + chainB := coord.GetChain(ibctesting.GetChainID(1)) + + actorChainA := sdk.AccAddress(chainA.SenderPrivKey.PubKey().Address()) + actorChainB := sdk.AccAddress(chainB.SenderPrivKey.PubKey().Address()) + receiver := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) + payee := sdk.AccAddress(bytes.Repeat([]byte{2}, address.Len)) + oneToken := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))) + + path := wasmibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: ibctransfertypes.PortID, + Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.Version})), + Order: channeltypes.UNORDERED, + } + path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: ibctransfertypes.PortID, + Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.Version})), + Order: channeltypes.UNORDERED, + } + // with an ics-20 transfer channel setup between both chains + coord.Setup(path) + require.True(t, chainA.App.IBCFeeKeeper.IsFeeEnabled(chainA.GetContext(), ibctransfertypes.PortID, path.EndpointA.ChannelID)) + // and with a payee registered on both chains + _, err := chainA.SendMsgs(ibcfee.NewMsgRegisterPayee(ibctransfertypes.PortID, path.EndpointA.ChannelID, actorChainA.String(), payee.String())) + require.NoError(t, err) + _, err = chainB.SendMsgs(ibcfee.NewMsgRegisterCounterpartyPayee(ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), payee.String())) + require.NoError(t, err) + + // when a transfer package is sent + transferCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)) + ibcPayloadMsg := ibctransfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, transferCoin, actorChainA.String(), receiver.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano())) + ibcPackageFee := ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) + feeMsg := ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointA.ChannelID, actorChainA.String(), nil) + _, err = chainA.SendMsgs(feeMsg, ibcPayloadMsg) + require.NoError(t, err) + pendingIncentivisedPackages := chainA.App.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainA.GetContext(), ibctransfertypes.PortID, path.EndpointA.ChannelID) + assert.Len(t, pendingIncentivisedPackages, 1) + + // and packages relayed + require.NoError(t, coord.RelayAndAckPendingPackets(path)) + + // then + expBalance := ibctransfertypes.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, transferCoin.Denom, transferCoin.Amount) + gotBalance := chainB.Balance(receiver, expBalance.Denom) + assert.Equal(t, expBalance.String(), gotBalance.String()) + payeeBalance := chainA.AllBalances(payee) + assert.Equal(t, oneToken.Add(oneToken...).String(), payeeBalance.String()) + + // and with a payee registered for chain B to A + _, err = chainA.SendMsgs(ibcfee.NewMsgRegisterCounterpartyPayee(ibctransfertypes.PortID, path.EndpointA.ChannelID, actorChainA.String(), payee.String())) + require.NoError(t, err) + _, err = chainB.SendMsgs(ibcfee.NewMsgRegisterPayee(ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), payee.String())) + require.NoError(t, err) + + // and transfer from B to A + ibcPayloadMsg = ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, transferCoin, actorChainB.String(), receiver.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano())) + ibcPackageFee = ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) + feeMsg = ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), nil) + _, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) + require.NoError(t, err) + pendingIncentivisedPackages = chainB.App.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID) + assert.Len(t, pendingIncentivisedPackages, 1) + + // when packages relayed + require.NoError(t, coord.RelayAndAckPendingPackets(path)) + + // then + expBalance = ibctransfertypes.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, transferCoin.Denom, transferCoin.Amount) + gotBalance = chainA.Balance(receiver, expBalance.Denom) + assert.Equal(t, expBalance.String(), gotBalance.String()) + payeeBalance = chainB.AllBalances(payee) + assert.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2)).String(), payeeBalance.String()) +} + +func TestIBCFeesWasm(t *testing.T) { + // scenario: + // given 2 chains with cw20-ibc on chain A and native ics20 module on B + // and an ibc channel established + // when an ics-29 fee is attached to an ibc package + // then the relayer's payee is receiving the fee(s) on success + marshaler := app.MakeEncodingConfig().Marshaler + coord := wasmibctesting.NewCoordinator(t, 2) + chainA := coord.GetChain(ibctesting.GetChainID(0)) + chainB := coord.GetChain(ibctesting.GetChainID(1)) + actorChainA := sdk.AccAddress(chainA.SenderPrivKey.PubKey().Address()) + actorChainB := sdk.AccAddress(chainB.SenderPrivKey.PubKey().Address()) + + // setup chain A + codeID := chainA.StoreCodeFile("./testdata/cw20_base.wasm.gz").CodeID + + initMsg := []byte(fmt.Sprintf(`{"decimals": 6, "name": "test", "symbol":"ALX", "initial_balances": [{"address": %q,"amount":"100000000"}] }`, actorChainA.String())) + cw20ContractAddr := chainA.InstantiateContract(codeID, initMsg) + + initMsg = []byte(fmt.Sprintf(`{"default_timeout": 360, "gov_contract": %q, "allowlist":[{"contract":%q}]}`, actorChainA.String(), cw20ContractAddr.String())) + codeID = chainA.StoreCodeFile("./testdata/cw20_ics20.wasm.gz").CodeID + ibcContractAddr := chainA.InstantiateContract(codeID, initMsg) + ibcContractPortID := chainA.ContractInfo(ibcContractAddr).IBCPortID + + payee := sdk.AccAddress(bytes.Repeat([]byte{2}, address.Len)) + oneToken := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))) + + path := wasmibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: ibcContractPortID, + Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.Version})), + Order: channeltypes.UNORDERED, + } + path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: ibctransfertypes.PortID, + Version: string(marshaler.MustMarshalJSON(&ibcfee.Metadata{FeeVersion: ibcfee.Version, AppVersion: ibctransfertypes.Version})), + Order: channeltypes.UNORDERED, + } + // with an ics-29 fee enabled channel setup between both chains + coord.Setup(path) + require.True(t, chainA.App.IBCFeeKeeper.IsFeeEnabled(chainA.GetContext(), ibcContractPortID, path.EndpointA.ChannelID)) + require.True(t, chainB.App.IBCFeeKeeper.IsFeeEnabled(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID)) + // and with a payee registered for A -> B + _, err := chainA.SendMsgs(ibcfee.NewMsgRegisterPayee(ibcContractPortID, path.EndpointA.ChannelID, actorChainA.String(), payee.String())) + require.NoError(t, err) + _, err = chainB.SendMsgs(ibcfee.NewMsgRegisterCounterpartyPayee(ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), payee.String())) + require.NoError(t, err) + + // when a transfer package is sent from ics20 contract on A to B + transfer := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf(`{"channel": %q, "remote_address": %q}`, path.EndpointA.ChannelID, actorChainB.String()))) + exec := []byte(fmt.Sprintf(`{"send":{"contract": %q, "amount": "100", "msg": %q}}`, ibcContractAddr.String(), transfer)) + execMsg := wasmtypes.MsgExecuteContract{ + Sender: actorChainA.String(), + Contract: cw20ContractAddr.String(), + Msg: exec, + } + ibcPackageFee := ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) + feeMsg := ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibcContractPortID, path.EndpointA.ChannelID, actorChainA.String(), nil) + _, err = chainA.SendMsgs(feeMsg, &execMsg) + require.NoError(t, err) + pendingIncentivisedPackages := chainA.App.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainA.GetContext(), ibcContractPortID, path.EndpointA.ChannelID) + assert.Len(t, pendingIncentivisedPackages, 1) + + // and packages relayed + require.NoError(t, coord.RelayAndAckPendingPackets(path)) + + // then + // on chain A + gotCW20Balance, err := chainA.App.WasmKeeper.QuerySmart(chainA.GetContext(), cw20ContractAddr, []byte(fmt.Sprintf(`{"balance":{"address": %q}}`, actorChainA.String()))) + require.NoError(t, err) + assert.JSONEq(t, `{"balance":"99999900"}`, string(gotCW20Balance)) + payeeBalance := chainA.AllBalances(payee) + assert.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2)).String(), payeeBalance.String()) + // and on chain B + pendingIncentivisedPackages = chainA.App.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainA.GetContext(), ibcContractPortID, path.EndpointA.ChannelID) + assert.Len(t, pendingIncentivisedPackages, 0) + expBalance := ibctransfertypes.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, "cw20:"+cw20ContractAddr.String(), sdk.NewInt(100)) + gotBalance := chainB.Balance(actorChainB, expBalance.Denom) + assert.Equal(t, expBalance.String(), gotBalance.String(), chainB.AllBalances(actorChainB)) + + // and with a payee registered for chain B to A + _, err = chainA.SendMsgs(ibcfee.NewMsgRegisterCounterpartyPayee(ibcContractPortID, path.EndpointA.ChannelID, actorChainA.String(), payee.String())) + require.NoError(t, err) + _, err = chainB.SendMsgs(ibcfee.NewMsgRegisterPayee(ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), payee.String())) + require.NoError(t, err) + + // and when sent back from chain B to A + ibcPayloadMsg := ibctransfertypes.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, gotBalance, actorChainB.String(), actorChainA.String(), clienttypes.Height{}, uint64(time.Now().Add(time.Minute).UnixNano())) + ibcPackageFee = ibcfee.NewFee(oneToken, oneToken, sdk.Coins{}) + feeMsg = ibcfee.NewMsgPayPacketFee(ibcPackageFee, ibctransfertypes.PortID, path.EndpointB.ChannelID, actorChainB.String(), nil) + _, err = chainB.SendMsgs(feeMsg, ibcPayloadMsg) + require.NoError(t, err) + pendingIncentivisedPackages = chainB.App.IBCFeeKeeper.GetIdentifiedPacketFeesForChannel(chainB.GetContext(), ibctransfertypes.PortID, path.EndpointB.ChannelID) + assert.Len(t, pendingIncentivisedPackages, 1) + + // when packages relayed + require.NoError(t, coord.RelayAndAckPendingPackets(path)) + + // then + // on chain A + gotCW20Balance, err = chainA.App.WasmKeeper.QuerySmart(chainA.GetContext(), cw20ContractAddr, []byte(fmt.Sprintf(`{"balance":{"address": %q}}`, actorChainA.String()))) + require.NoError(t, err) + assert.JSONEq(t, `{"balance":"100000000"}`, string(gotCW20Balance)) + // and on chain B + payeeBalance = chainB.AllBalances(payee) + assert.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(2)).String(), payeeBalance.String()) +} diff --git a/tests/e2e/ica_test.go b/tests/e2e/ica_test.go new file mode 100644 index 0000000000..24c0623611 --- /dev/null +++ b/tests/e2e/ica_test.go @@ -0,0 +1,91 @@ +package e2e + +import ( + "bytes" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + hosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + wasmibctesting "github.com/CosmWasm/wasmd/x/wasm/ibctesting" +) + +func TestICA(t *testing.T) { + // scenario: + // given a host and controller chain + // when an ica is registered on the controller chain + // and the channel is established to the host chain + // then the ICA owner can submit a message via IBC + // to control their account on the host chain + coord := wasmibctesting.NewCoordinator(t, 2) + hostChain := coord.GetChain(ibctesting.GetChainID(0)) + hostParams := hosttypes.NewParams(true, []string{sdk.MsgTypeURL(&banktypes.MsgSend{})}) + hostChain.App.ICAHostKeeper.SetParams(hostChain.GetContext(), hostParams) + + controllerChain := coord.GetChain(ibctesting.GetChainID(1)) + + path := wasmibctesting.NewPath(controllerChain, hostChain) + coord.SetupConnections(path) + + ownerAddr := sdk.AccAddress(controllerChain.SenderPrivKey.PubKey().Address()) + msg := intertxtypes.NewMsgRegisterAccount(ownerAddr.String(), path.EndpointA.ConnectionID, "") + res, err := controllerChain.SendMsgs(msg) + chanID, portID, version := parseIBCChannelEvents(t, res) + + // next open channels on both sides + path.EndpointA.ChannelID = chanID + path.EndpointA.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: portID, + Version: version, + Order: channeltypes.ORDERED, + } + path.EndpointB.ChannelConfig = &ibctesting.ChannelConfig{ + PortID: icatypes.PortID, + Version: icatypes.Version, + Order: channeltypes.ORDERED, + } + coord.CreateChannels(path) + + // assert ICA exists on controller + icaRsp, err := controllerChain.App.InterTxKeeper.InterchainAccount(sdk.WrapSDKContext(controllerChain.GetContext()), &intertxtypes.QueryInterchainAccountRequest{ + Owner: ownerAddr.String(), + ConnectionId: path.EndpointA.ConnectionID, + }) + require.NoError(t, err) + icaAddr := sdk.MustAccAddressFromBech32(icaRsp.InterchainAccountAddress) + hostChain.Fund(icaAddr, sdk.NewInt(1_000)) + + // submit a tx + targetAddr := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) + sendCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + payloadMsg := banktypes.NewMsgSend(icaAddr, targetAddr, sdk.NewCoins(sendCoin)) + msg2, err := intertxtypes.NewMsgSubmitTx(payloadMsg, path.EndpointA.ConnectionID, ownerAddr.String()) + require.NoError(t, err) + res, err = controllerChain.SendMsgs(msg2) + require.NoError(t, err) + + assert.Equal(t, 1, len(controllerChain.PendingSendPackets)) + require.NoError(t, coord.RelayAndAckPendingPackets(path)) + + gotBalance := hostChain.Balance(targetAddr, sdk.DefaultBondDenom) + assert.Equal(t, sendCoin.String(), gotBalance.String()) +} + +func parseIBCChannelEvents(t *testing.T, res *sdk.Result) (string, string, string) { + t.Helper() + chanID, err := ibctesting.ParseChannelIDFromEvents(res.GetEvents()) + require.NoError(t, err) + portID, err := wasmibctesting.ParsePortIDFromEvents(res.GetEvents()) + require.NoError(t, err) + version, err := wasmibctesting.ParseChannelVersionFromEvents(res.GetEvents()) + require.NoError(t, err) + return chanID, portID, version +} diff --git a/tests/e2e/testdata/cw20_base.wasm.gz b/tests/e2e/testdata/cw20_base.wasm.gz new file mode 100644 index 0000000000000000000000000000000000000000..7745e80f6db3d5420a9fac311cf3b9de314fac34 GIT binary patch literal 105532 zcmV(@K-Rw>iwFq)6HQ|P17mkGFkfO}b7d}fVRLN&?7e@yUe#GAy4Tu2-*><7Ir}7s z3ypqNbJ^ zm??2mtrfi0No%gAEo$swOKo*hMU6@|TJDIJUgr5e&suA*{hl8=3AFmhgb(N4zt*p3 zJ?mM|dVU5syzMP22myO`d;|;e5p}o8P=DT)D z(e4d5-L&)iJ8!t{)|+mi^89RspHYFg-hS(i^ybHJ4pjZ^EpLCz4Y#{z#oKPa@s96% z)rRR;UVrD!J8%8rACpGL>c=~8zL9#e^ZGm9{^seMe=Hcm>!F)(`o34a>XolGP;cDDv0T0e4hqUl(t(@8bw@02U*t5vP>(b;`$%n(UUNYPzd#fTB}eg z`a4Ybct`&QDy3rdqv%N#MJkE$3CadR-U+CEs;Y&m@T8zWTA6=Rh@YbY^eok_4)v?u zYPYHH=ATBLxENAHMMCA{#Sx8@hNWZs4eCJGxLNvKB{bmCIOs4OR3iVlHf8Rl=?;pb zR~R6VSmlxKO2^VLN-j`c#p71PA(f26B%wRCWGOyKhQd%ssk%e`2K^TkJVugb;civ! z*>fz&cL&v@PkfqxkK#9dOm&jC5QgsjF&*T$-u|{-H{8DKR^Z?No!)%c%{RWCuHLC) zp6K9RDt*hXKe7{V?@^0yy?xisJAe3w8*c`FyzSPv-hTb2;2D+OaNBKfy%C@My=vcd zv%7m<6+3U<@%CGH-u$-fsgdbhZ~qbcdc-}WB|{azbtgS+Uw=KVfE%vA`SzP=y6t_sXtL)Q-7@fRQ;Lyb9Gw% zh5AeNSL#{yb@k?@W4FEK#<$&Z{m!@Ucp&^)wfv;I@ql{2dav64KDA#xfV&T$JO@#qJCL@LXCY={feSCKBczr z{5AFK>Wk`4+rOaxAN5=6^E3hfsD58PsXj*^{I=TuS@oOhg!)zW-_$>-�%=PpIwB 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ˈgGFs=P!zw{CJ+ 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 M0N}#7cTmU#05(?*h5!Hn literal 0 HcmV?d00001 diff --git a/tests/e2e/testdata/cw20_ics20.wasm.gz b/tests/e2e/testdata/cw20_ics20.wasm.gz new file mode 100644 index 0000000000000000000000000000000000000000..07517a2fb5d8f3adf35b32173f2b25763beeeb1b GIT binary patch literal 119250 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

T_oD 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

Top

-## cosmwasm/wasm/v1/tx.proto +## cosmwasm/wasm/v1/genesis.proto - + -### MsgClearAdmin -MsgClearAdmin removes any admin stored for a smart contract +### Code +Code struct encompasses CodeInfo and CodeBytes | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `code_id` | [uint64](#uint64) | | | +| `code_info` | [CodeInfo](#cosmwasm.wasm.v1.CodeInfo) | | | +| `code_bytes` | [bytes](#bytes) | | | +| `pinned` | [bool](#bool) | | Pinned to wasmvm cache | - + -### MsgClearAdminResponse -MsgClearAdminResponse returns empty data +### Contract +Contract struct encompasses ContractAddress, ContractInfo, and ContractState + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `contract_address` | [string](#string) | | | +| `contract_info` | [ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | +| `contract_state` | [Model](#cosmwasm.wasm.v1.Model) | repeated | | +| `contract_code_history` | [ContractCodeHistoryEntry](#cosmwasm.wasm.v1.ContractCodeHistoryEntry) | repeated | | - + -### MsgExecuteContract -MsgExecuteContract submits the given message data to a smart contract +### GenesisState +GenesisState - genesis state of x/wasm | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on execution | +| `params` | [Params](#cosmwasm.wasm.v1.Params) | | | +| `codes` | [Code](#cosmwasm.wasm.v1.Code) | repeated | | +| `contracts` | [Contract](#cosmwasm.wasm.v1.Contract) | repeated | | +| `sequences` | [Sequence](#cosmwasm.wasm.v1.Sequence) | repeated | | - + -### MsgExecuteContractResponse -MsgExecuteContractResponse returns execution result data. +### Sequence +Sequence key and value of an id generation counter | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | +| `id_key` | [bytes](#bytes) | | | +| `value` | [uint64](#uint64) | | | + - + -### MsgInstantiateContract -MsgInstantiateContract create a new smart contract instance for the given -code id. + + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | -| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | -| `label` | [string](#string) | | Label is optional metadata to be stored with a contract instance. | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | + +

Top

+## cosmwasm/wasm/v1/ibc.proto - + -### MsgInstantiateContract2 -MsgInstantiateContract2 create a new smart contract instance for the given -code id with a predicable address. +### MsgIBCCloseChannel +MsgIBCCloseChannel port and channel need to be owned by the contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | -| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | -| `label` | [string](#string) | | Label is optional metadata to be stored with a contract instance. | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | -| `salt` | [bytes](#bytes) | | Salt is an arbitrary value provided by the sender. Size can be 1 to 64. | -| `fix_msg` | [bool](#bool) | | FixMsg include the msg value into the hash for the predictable address. Default is false | +| `channel` | [string](#string) | | | - + -### MsgInstantiateContract2Response -MsgInstantiateContract2Response return instantiation result data +### MsgIBCSend +MsgIBCSend | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | Address is the bech32 address of the new contract instance. | -| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | +| `channel` | [string](#string) | | the channel by which the packet will be sent | +| `timeout_height` | [uint64](#uint64) | | Timeout height relative to the current block height. The timeout is disabled when set to 0. | +| `timeout_timestamp` | [uint64](#uint64) | | Timeout timestamp (in nanoseconds) relative to the current block timestamp. The timeout is disabled when set to 0. | +| `data` | [bytes](#bytes) | | Data is the payload to transfer. We must not make assumption what format or content is in here. | + - + -### MsgInstantiateContractResponse -MsgInstantiateContractResponse return instantiation result data + + + + + + + +

Top

+ +## cosmwasm/wasm/v1/proposal.proto + + + + + +### AccessConfigUpdate +AccessConfigUpdate contains the code id and the access config to be +applied. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | Address is the bech32 address of the new contract instance. | -| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code to be updated | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply to the set of code ids | - + -### MsgMigrateContract -MsgMigrateContract runs a code upgrade/ downgrade for a smart contract +### ClearAdminProposal +ClearAdminProposal gov proposal content type to clear the admin of a +contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | | `contract` | [string](#string) | | Contract is the address of the smart contract | -| `code_id` | [uint64](#uint64) | | CodeID references the new WASM code | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on migration | - + -### MsgMigrateContractResponse -MsgMigrateContractResponse returns contract migration result data. +### ExecuteContractProposal +ExecuteContractProposal gov proposal content type to call execute on a +contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `data` | [bytes](#bytes) | | Data contains same raw bytes returned as data from the wasm contract. (May be empty) | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as execute | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | - + -### MsgStoreCode -MsgStoreCode submit Wasm code to the system +### InstantiateContract2Proposal +InstantiateContract2Proposal gov proposal content type to instantiate +contract 2 | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | -| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission access control to apply on contract creation, optional | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's enviroment as sender | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | +| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | +| `msg` | [bytes](#bytes) | | Msg json encode message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `salt` | [bytes](#bytes) | | Salt is an arbitrary value provided by the sender. Size can be 1 to 64. | +| `fix_msg` | [bool](#bool) | | FixMsg include the msg value into the hash for the predictable address. Default is false | - + -### MsgStoreCodeResponse -MsgStoreCodeResponse returns store result data. +### InstantiateContractProposal +InstantiateContractProposal gov proposal content type to instantiate a +contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | | `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | -| `checksum` | [bytes](#bytes) | | Checksum is the sha256 hash of the stored code | +| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | - + -### MsgUpdateAdmin -MsgUpdateAdmin sets a new admin for a smart contract +### MigrateContractProposal +MigrateContractProposal gov proposal content type to migrate a contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | -| `new_admin` | [string](#string) | | NewAdmin address to be set | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text + +Note: skipping 3 as this was previously used for unneeded run_as | | `contract` | [string](#string) | | Contract is the address of the smart contract | +| `code_id` | [uint64](#uint64) | | CodeID references the new WASM code | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on migration | - + -### MsgUpdateAdminResponse -MsgUpdateAdminResponse returns empty data +### PinCodesProposal +PinCodesProposal gov proposal content type to pin a set of code ids in the +wasmvm cache. +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `code_ids` | [uint64](#uint64) | repeated | CodeIDs references the new WASM codes | - - - + - +### StoreAndInstantiateContractProposal +StoreAndInstantiateContractProposal gov proposal content type to store +and instantiate the contract. -### Msg -Msg defines the wasm Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `StoreCode` | [MsgStoreCode](#cosmwasm.wasm.v1.MsgStoreCode) | [MsgStoreCodeResponse](#cosmwasm.wasm.v1.MsgStoreCodeResponse) | StoreCode to submit Wasm code to the system | | -| `InstantiateContract` | [MsgInstantiateContract](#cosmwasm.wasm.v1.MsgInstantiateContract) | [MsgInstantiateContractResponse](#cosmwasm.wasm.v1.MsgInstantiateContractResponse) | InstantiateContract creates a new smart contract instance for the given code id. | | -| `InstantiateContract2` | [MsgInstantiateContract2](#cosmwasm.wasm.v1.MsgInstantiateContract2) | [MsgInstantiateContract2Response](#cosmwasm.wasm.v1.MsgInstantiateContract2Response) | InstantiateContract2 creates a new smart contract instance for the given code id with a predictable address | | -| `ExecuteContract` | [MsgExecuteContract](#cosmwasm.wasm.v1.MsgExecuteContract) | [MsgExecuteContractResponse](#cosmwasm.wasm.v1.MsgExecuteContractResponse) | Execute submits the given message data to a smart contract | | -| `MigrateContract` | [MsgMigrateContract](#cosmwasm.wasm.v1.MsgMigrateContract) | [MsgMigrateContractResponse](#cosmwasm.wasm.v1.MsgMigrateContractResponse) | Migrate runs a code upgrade/ downgrade for a smart contract | | -| `UpdateAdmin` | [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) | [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) | UpdateAdmin sets a new admin for a smart contract | | -| `ClearAdmin` | [MsgClearAdmin](#cosmwasm.wasm.v1.MsgClearAdmin) | [MsgClearAdminResponse](#cosmwasm.wasm.v1.MsgClearAdminResponse) | ClearAdmin removes any admin stored for a smart contract | | - - +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | +| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | +| `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `source` | [string](#string) | | Source is the URL where the code is hosted | +| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | +| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | - -

Top

-## cosmwasm/wasm/v1/genesis.proto - + -### Code -Code struct encompasses CodeInfo and CodeBytes +### StoreCodeProposal +StoreCodeProposal gov proposal content type to submit WASM code to the system | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_id` | [uint64](#uint64) | | | -| `code_info` | [CodeInfo](#cosmwasm.wasm.v1.CodeInfo) | | | -| `code_bytes` | [bytes](#bytes) | | | -| `pinned` | [bool](#bool) | | Pinned to wasmvm cache | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | +| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | +| `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | +| `source` | [string](#string) | | Source is the URL where the code is hosted | +| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | +| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | - + -### Contract -Contract struct encompasses ContractAddress, ContractInfo, and ContractState +### SudoContractProposal +SudoContractProposal gov proposal content type to call sudo on a contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `contract_address` | [string](#string) | | | -| `contract_info` | [ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | -| `contract_state` | [Model](#cosmwasm.wasm.v1.Model) | repeated | | -| `contract_code_history` | [ContractCodeHistoryEntry](#cosmwasm.wasm.v1.ContractCodeHistoryEntry) | repeated | | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as sudo | - + -### GenesisState -GenesisState - genesis state of x/wasm +### UnpinCodesProposal +UnpinCodesProposal gov proposal content type to unpin a set of code ids in +the wasmvm cache. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `params` | [Params](#cosmwasm.wasm.v1.Params) | | | -| `codes` | [Code](#cosmwasm.wasm.v1.Code) | repeated | | -| `contracts` | [Contract](#cosmwasm.wasm.v1.Contract) | repeated | | -| `sequences` | [Sequence](#cosmwasm.wasm.v1.Sequence) | repeated | | -| `gen_msgs` | [GenesisState.GenMsgs](#cosmwasm.wasm.v1.GenesisState.GenMsgs) | repeated | | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `code_ids` | [uint64](#uint64) | repeated | CodeIDs references the WASM codes | - + -### GenesisState.GenMsgs -GenMsgs define the messages that can be executed during genesis phase in -order. The intention is to have more human readable data that is auditable. +### UpdateAdminProposal +UpdateAdminProposal gov proposal content type to set an admin for a contract. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `store_code` | [MsgStoreCode](#cosmwasm.wasm.v1.MsgStoreCode) | | | -| `instantiate_contract` | [MsgInstantiateContract](#cosmwasm.wasm.v1.MsgInstantiateContract) | | | -| `execute_contract` | [MsgExecuteContract](#cosmwasm.wasm.v1.MsgExecuteContract) | | MsgInstantiateContract2 intentionally not supported see https://github.com/CosmWasm/wasmd/issues/987 | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `new_admin` | [string](#string) | | NewAdmin address to be set | +| `contract` | [string](#string) | | Contract is the address of the smart contract | - + -### Sequence -Sequence key and value of an id generation counter +### UpdateInstantiateConfigProposal +UpdateInstantiateConfigProposal gov proposal content type to update +instantiate config to a set of code ids. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `id_key` | [bytes](#bytes) | | | -| `value` | [uint64](#uint64) | | | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `access_config_updates` | [AccessConfigUpdate](#cosmwasm.wasm.v1.AccessConfigUpdate) | repeated | AccessConfigUpdate contains the list of code ids and the access config to be applied. | @@ -812,371 +863,296 @@ Sequence key and value of an id generation counter - +

Top

-## cosmwasm/wasm/v1/ibc.proto +## cosmwasm/wasm/v1/query.proto - + -### MsgIBCCloseChannel -MsgIBCCloseChannel port and channel need to be owned by the contract +### CodeInfoResponse +CodeInfoResponse contains code meta data from CodeInfo | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `channel` | [string](#string) | | | +| `code_id` | [uint64](#uint64) | | id for legacy support | +| `creator` | [string](#string) | | | +| `data_hash` | [bytes](#bytes) | | | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | | - + -### MsgIBCSend -MsgIBCSend +### QueryAllContractStateRequest +QueryAllContractStateRequest is the request type for the +Query/AllContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `channel` | [string](#string) | | the channel by which the packet will be sent | -| `timeout_height` | [uint64](#uint64) | | Timeout height relative to the current block height. The timeout is disabled when set to 0. | -| `timeout_timestamp` | [uint64](#uint64) | | Timeout timestamp (in nanoseconds) relative to the current block timestamp. The timeout is disabled when set to 0. | -| `data` | [bytes](#bytes) | | Data is the payload to transfer. We must not make assumption what format or content is in here. | - - - - - - - - - - - - +| `address` | [string](#string) | | address is the address of the contract | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | - -

Top

-## cosmwasm/wasm/v1/proposal.proto + - - -### AccessConfigUpdate -AccessConfigUpdate contains the code id and the access config to be -applied. +### QueryAllContractStateResponse +QueryAllContractStateResponse is the response type for the +Query/AllContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code to be updated | -| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply to the set of code ids | +| `models` | [Model](#cosmwasm.wasm.v1.Model) | repeated | | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | - + -### ClearAdminProposal -ClearAdminProposal gov proposal content type to clear the admin of a -contract. +### QueryCodeRequest +QueryCodeRequest is the request type for the Query/Code RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID | - + -### ExecuteContractProposal -ExecuteContractProposal gov proposal content type to call execute on a -contract. +### QueryCodeResponse +QueryCodeResponse is the response type for the Query/Code RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as execute | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `code_info` | [CodeInfoResponse](#cosmwasm.wasm.v1.CodeInfoResponse) | | | +| `data` | [bytes](#bytes) | | | - + -### InstantiateContract2Proposal -InstantiateContract2Proposal gov proposal content type to instantiate contract 2 +### QueryCodesRequest +QueryCodesRequest is the request type for the Query/Codes RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's enviroment as sender | -| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | -| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | -| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | -| `msg` | [bytes](#bytes) | | Msg json encode message to be passed to the contract on instantiation | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | -| `salt` | [bytes](#bytes) | | Salt is an arbitrary value provided by the sender. Size can be 1 to 64. | -| `fix_msg` | [bool](#bool) | | FixMsg include the msg value into the hash for the predictable address. Default is false | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | - + -### InstantiateContractProposal -InstantiateContractProposal gov proposal content type to instantiate a -contract. +### QueryCodesResponse +QueryCodesResponse is the response type for the Query/Codes RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | -| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | -| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | -| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `code_infos` | [CodeInfoResponse](#cosmwasm.wasm.v1.CodeInfoResponse) | repeated | | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | - + -### MigrateContractProposal -MigrateContractProposal gov proposal content type to migrate a contract. +### QueryContractHistoryRequest +QueryContractHistoryRequest is the request type for the Query/ContractHistory +RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text - -Note: skipping 3 as this was previously used for unneeded run_as | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `code_id` | [uint64](#uint64) | | CodeID references the new WASM code | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on migration | +| `address` | [string](#string) | | address is the address of the contract to query | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | - + -### PinCodesProposal -PinCodesProposal gov proposal content type to pin a set of code ids in the -wasmvm cache. +### QueryContractHistoryResponse +QueryContractHistoryResponse is the response type for the +Query/ContractHistory RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `code_ids` | [uint64](#uint64) | repeated | CodeIDs references the new WASM codes | +| `entries` | [ContractCodeHistoryEntry](#cosmwasm.wasm.v1.ContractCodeHistoryEntry) | repeated | | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | - + -### StoreAndInstantiateContractProposal -StoreAndInstantiateContractProposal gov proposal content type to store -and instantiate the contract. +### QueryContractInfoRequest +QueryContractInfoRequest is the request type for the Query/ContractInfo RPC +method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | -| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | -| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | -| `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | -| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | -| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | -| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | -| `source` | [string](#string) | | Source is the URL where the code is hosted | -| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | -| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | +| `address` | [string](#string) | | address is the address of the contract to query | - + -### StoreCodeProposal -StoreCodeProposal gov proposal content type to submit WASM code to the system +### QueryContractInfoResponse +QueryContractInfoResponse is the response type for the Query/ContractInfo RPC +method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's environment as sender | -| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | -| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | -| `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | -| `source` | [string](#string) | | Source is the URL where the code is hosted | -| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | -| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | +| `address` | [string](#string) | | address is the address of the contract | +| `contract_info` | [ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | - + -### SudoContractProposal -SudoContractProposal gov proposal content type to call sudo on a contract. +### QueryContractsByCodeRequest +QueryContractsByCodeRequest is the request type for the Query/ContractsByCode +RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `contract` | [string](#string) | | Contract is the address of the smart contract | -| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract as sudo | +| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | - + -### UnpinCodesProposal -UnpinCodesProposal gov proposal content type to unpin a set of code ids in -the wasmvm cache. +### QueryContractsByCodeResponse +QueryContractsByCodeResponse is the response type for the +Query/ContractsByCode RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `code_ids` | [uint64](#uint64) | repeated | CodeIDs references the WASM codes | +| `contracts` | [string](#string) | repeated | contracts are a set of contract addresses | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | - + -### UpdateAdminProposal -UpdateAdminProposal gov proposal content type to set an admin for a contract. +### QueryContractsByCreatorRequest +QueryContractsByCreatorRequest is the request type for the +Query/ContractsByCreator RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `new_admin` | [string](#string) | | NewAdmin address to be set | -| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `creator_address` | [string](#string) | | CreatorAddress is the address of contract creator | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | Pagination defines an optional pagination for the request. | - + -### UpdateInstantiateConfigProposal -UpdateInstantiateConfigProposal gov proposal content type to update -instantiate config to a set of code ids. +### QueryContractsByCreatorResponse +QueryContractsByCreatorResponse is the response type for the +Query/ContractsByCreator RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | Title is a short summary | -| `description` | [string](#string) | | Description is a human readable text | -| `access_config_updates` | [AccessConfigUpdate](#cosmwasm.wasm.v1.AccessConfigUpdate) | repeated | AccessConfigUpdate contains the list of code ids and the access config to be applied. | +| `contract_addresses` | [string](#string) | repeated | ContractAddresses result set | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | Pagination defines the pagination in the response. | - - - - + - +### QueryParamsRequest +QueryParamsRequest is the request type for the Query/Params RPC method. - -

Top

-## cosmwasm/wasm/v1/query.proto + - - -### CodeInfoResponse -CodeInfoResponse contains code meta data from CodeInfo +### QueryParamsResponse +QueryParamsResponse is the response type for the Query/Params RPC method. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_id` | [uint64](#uint64) | | id for legacy support | -| `creator` | [string](#string) | | | -| `data_hash` | [bytes](#bytes) | | | -| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | | +| `params` | [Params](#cosmwasm.wasm.v1.Params) | | params defines the parameters of the module. | - + -### QueryAllContractStateRequest -QueryAllContractStateRequest is the request type for the -Query/AllContractState RPC method +### QueryPinnedCodesRequest +QueryPinnedCodesRequest is the request type for the Query/PinnedCodes +RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract | | `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | @@ -1184,16 +1160,16 @@ Query/AllContractState RPC method - + -### QueryAllContractStateResponse -QueryAllContractStateResponse is the response type for the -Query/AllContractState RPC method +### QueryPinnedCodesResponse +QueryPinnedCodesResponse is the response type for the +Query/PinnedCodes RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `models` | [Model](#cosmwasm.wasm.v1.Model) | repeated | | +| `code_ids` | [uint64](#uint64) | repeated | | | `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | @@ -1201,321 +1177,330 @@ Query/AllContractState RPC method - - -### QueryCodeRequest -QueryCodeRequest is the request type for the Query/Code RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID | - - - - - - - + -### QueryCodeResponse -QueryCodeResponse is the response type for the Query/Code RPC method +### QueryRawContractStateRequest +QueryRawContractStateRequest is the request type for the +Query/RawContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_info` | [CodeInfoResponse](#cosmwasm.wasm.v1.CodeInfoResponse) | | | -| `data` | [bytes](#bytes) | | | - +| `address` | [string](#string) | | address is the address of the contract | +| `query_data` | [bytes](#bytes) | | | - -### QueryCodesRequest -QueryCodesRequest is the request type for the Query/Codes RPC method + + +### QueryRawContractStateResponse +QueryRawContractStateResponse is the response type for the +Query/RawContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `data` | [bytes](#bytes) | | Data contains the raw store data | - + -### QueryCodesResponse -QueryCodesResponse is the response type for the Query/Codes RPC method +### QuerySmartContractStateRequest +QuerySmartContractStateRequest is the request type for the +Query/SmartContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_infos` | [CodeInfoResponse](#cosmwasm.wasm.v1.CodeInfoResponse) | repeated | | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | +| `address` | [string](#string) | | address is the address of the contract | +| `query_data` | [bytes](#bytes) | | QueryData contains the query data passed to the contract | - + -### QueryContractHistoryRequest -QueryContractHistoryRequest is the request type for the Query/ContractHistory -RPC method +### QuerySmartContractStateResponse +QuerySmartContractStateResponse is the response type for the +Query/SmartContractState RPC method | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract to query | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `data` | [bytes](#bytes) | | Data contains the json data returned from the smart contract | + - + -### QueryContractHistoryResponse -QueryContractHistoryResponse is the response type for the -Query/ContractHistory RPC method + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `entries` | [ContractCodeHistoryEntry](#cosmwasm.wasm.v1.ContractCodeHistoryEntry) | repeated | | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | + +### Query +Query provides defines the gRPC querier service +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `ContractInfo` | [QueryContractInfoRequest](#cosmwasm.wasm.v1.QueryContractInfoRequest) | [QueryContractInfoResponse](#cosmwasm.wasm.v1.QueryContractInfoResponse) | ContractInfo gets the contract meta data | GET|/cosmwasm/wasm/v1/contract/{address}| +| `ContractHistory` | [QueryContractHistoryRequest](#cosmwasm.wasm.v1.QueryContractHistoryRequest) | [QueryContractHistoryResponse](#cosmwasm.wasm.v1.QueryContractHistoryResponse) | ContractHistory gets the contract code history | GET|/cosmwasm/wasm/v1/contract/{address}/history| +| `ContractsByCode` | [QueryContractsByCodeRequest](#cosmwasm.wasm.v1.QueryContractsByCodeRequest) | [QueryContractsByCodeResponse](#cosmwasm.wasm.v1.QueryContractsByCodeResponse) | ContractsByCode lists all smart contracts for a code id | GET|/cosmwasm/wasm/v1/code/{code_id}/contracts| +| `AllContractState` | [QueryAllContractStateRequest](#cosmwasm.wasm.v1.QueryAllContractStateRequest) | [QueryAllContractStateResponse](#cosmwasm.wasm.v1.QueryAllContractStateResponse) | AllContractState gets all raw store data for a single contract | GET|/cosmwasm/wasm/v1/contract/{address}/state| +| `RawContractState` | [QueryRawContractStateRequest](#cosmwasm.wasm.v1.QueryRawContractStateRequest) | [QueryRawContractStateResponse](#cosmwasm.wasm.v1.QueryRawContractStateResponse) | RawContractState gets single key from the raw store data of a contract | GET|/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}| +| `SmartContractState` | [QuerySmartContractStateRequest](#cosmwasm.wasm.v1.QuerySmartContractStateRequest) | [QuerySmartContractStateResponse](#cosmwasm.wasm.v1.QuerySmartContractStateResponse) | SmartContractState get smart query result from the contract | GET|/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}| +| `Code` | [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest) | [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse) | Code gets the binary code and metadata for a singe wasm code | GET|/cosmwasm/wasm/v1/code/{code_id}| +| `Codes` | [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest) | [QueryCodesResponse](#cosmwasm.wasm.v1.QueryCodesResponse) | Codes gets the metadata for all stored wasm codes | GET|/cosmwasm/wasm/v1/code| +| `PinnedCodes` | [QueryPinnedCodesRequest](#cosmwasm.wasm.v1.QueryPinnedCodesRequest) | [QueryPinnedCodesResponse](#cosmwasm.wasm.v1.QueryPinnedCodesResponse) | PinnedCodes gets the pinned code ids | GET|/cosmwasm/wasm/v1/codes/pinned| +| `Params` | [QueryParamsRequest](#cosmwasm.wasm.v1.QueryParamsRequest) | [QueryParamsResponse](#cosmwasm.wasm.v1.QueryParamsResponse) | Params gets the module params | GET|/cosmwasm/wasm/v1/codes/params| +| `ContractsByCreator` | [QueryContractsByCreatorRequest](#cosmwasm.wasm.v1.QueryContractsByCreatorRequest) | [QueryContractsByCreatorResponse](#cosmwasm.wasm.v1.QueryContractsByCreatorResponse) | ContractsByCreator gets the contracts by creator | GET|/cosmwasm/wasm/v1/contracts/creator/{creator_address}| + - + +

Top

-### QueryContractInfoRequest -QueryContractInfoRequest is the request type for the Query/ContractInfo RPC -method +## cosmwasm/wasm/v1/tx.proto -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract to query | + +### MsgClearAdmin +MsgClearAdmin removes any admin stored for a smart contract +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `contract` | [string](#string) | | Contract is the address of the smart contract | - -### QueryContractInfoResponse -QueryContractInfoResponse is the response type for the Query/ContractInfo RPC -method -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract | -| `contract_info` | [ContractInfo](#cosmwasm.wasm.v1.ContractInfo) | | | + +### MsgClearAdminResponse +MsgClearAdminResponse returns empty data - -### QueryContractsByCodeRequest -QueryContractsByCodeRequest is the request type for the Query/ContractsByCode -RPC method + + + +### MsgExecuteContract +MsgExecuteContract submits the given message data to a smart contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_id` | [uint64](#uint64) | | grpc-gateway_out does not support Go style CodID | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on execution | - + -### QueryContractsByCodeResponse -QueryContractsByCodeResponse is the response type for the -Query/ContractsByCode RPC method +### MsgExecuteContractResponse +MsgExecuteContractResponse returns execution result data. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `contracts` | [string](#string) | repeated | contracts are a set of contract addresses | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | +| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | - + -### QueryContractsByCreatorRequest -QueryContractsByCreatorRequest is the request type for the -Query/ContractsByCreator RPC method. +### MsgInstantiateContract +MsgInstantiateContract create a new smart contract instance for the given +code id. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `creator_address` | [string](#string) | | CreatorAddress is the address of contract creator | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | Pagination defines an optional pagination for the request. | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | +| `label` | [string](#string) | | Label is optional metadata to be stored with a contract instance. | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | - + -### QueryContractsByCreatorResponse -QueryContractsByCreatorResponse is the response type for the -Query/ContractsByCreator RPC method. +### MsgInstantiateContract2 +MsgInstantiateContract2 create a new smart contract instance for the given +code id with a predicable address. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `contract_addresses` | [string](#string) | repeated | ContractAddresses result set | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | Pagination defines the pagination in the response. | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | +| `label` | [string](#string) | | Label is optional metadata to be stored with a contract instance. | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `salt` | [bytes](#bytes) | | Salt is an arbitrary value provided by the sender. Size can be 1 to 64. | +| `fix_msg` | [bool](#bool) | | FixMsg include the msg value into the hash for the predictable address. Default is false | - + -### QueryParamsRequest -QueryParamsRequest is the request type for the Query/Params RPC method. +### MsgInstantiateContract2Response +MsgInstantiateContract2Response return instantiation result data + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `address` | [string](#string) | | Address is the bech32 address of the new contract instance. | +| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | - + -### QueryParamsResponse -QueryParamsResponse is the response type for the Query/Params RPC method. +### MsgInstantiateContractResponse +MsgInstantiateContractResponse return instantiation result data | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `params` | [Params](#cosmwasm.wasm.v1.Params) | | params defines the parameters of the module. | +| `address` | [string](#string) | | Address is the bech32 address of the new contract instance. | +| `data` | [bytes](#bytes) | | Data contains bytes to returned from the contract | - + -### QueryPinnedCodesRequest -QueryPinnedCodesRequest is the request type for the Query/PinnedCodes -RPC method +### MsgMigrateContract +MsgMigrateContract runs a code upgrade/ downgrade for a smart contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `contract` | [string](#string) | | Contract is the address of the smart contract | +| `code_id` | [uint64](#uint64) | | CodeID references the new WASM code | +| `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on migration | - + -### QueryPinnedCodesResponse -QueryPinnedCodesResponse is the response type for the -Query/PinnedCodes RPC method +### MsgMigrateContractResponse +MsgMigrateContractResponse returns contract migration result data. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `code_ids` | [uint64](#uint64) | repeated | | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | +| `data` | [bytes](#bytes) | | Data contains same raw bytes returned as data from the wasm contract. (May be empty) | - + -### QueryRawContractStateRequest -QueryRawContractStateRequest is the request type for the -Query/RawContractState RPC method +### MsgStoreCode +MsgStoreCode submit Wasm code to the system | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract | -| `query_data` | [bytes](#bytes) | | | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | +| `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission access control to apply on contract creation, optional | - + -### QueryRawContractStateResponse -QueryRawContractStateResponse is the response type for the -Query/RawContractState RPC method +### MsgStoreCodeResponse +MsgStoreCodeResponse returns store result data. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `data` | [bytes](#bytes) | | Data contains the raw store data | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | +| `checksum` | [bytes](#bytes) | | Checksum is the sha256 hash of the stored code | - + -### QuerySmartContractStateRequest -QuerySmartContractStateRequest is the request type for the -Query/SmartContractState RPC method +### MsgUpdateAdmin +MsgUpdateAdmin sets a new admin for a smart contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | address is the address of the contract | -| `query_data` | [bytes](#bytes) | | QueryData contains the query data passed to the contract | - - +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `new_admin` | [string](#string) | | NewAdmin address to be set | +| `contract` | [string](#string) | | Contract is the address of the smart contract | - -### QuerySmartContractStateResponse -QuerySmartContractStateResponse is the response type for the -Query/SmartContractState RPC method + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `data` | [bytes](#bytes) | | Data contains the json data returned from the smart contract | +### MsgUpdateAdminResponse +MsgUpdateAdminResponse returns empty data @@ -1528,24 +1513,20 @@ Query/SmartContractState RPC method - + -### Query -Query provides defines the gRPC querier service +### Msg +Msg defines the wasm Msg service. | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `ContractInfo` | [QueryContractInfoRequest](#cosmwasm.wasm.v1.QueryContractInfoRequest) | [QueryContractInfoResponse](#cosmwasm.wasm.v1.QueryContractInfoResponse) | ContractInfo gets the contract meta data | GET|/cosmwasm/wasm/v1/contract/{address}| -| `ContractHistory` | [QueryContractHistoryRequest](#cosmwasm.wasm.v1.QueryContractHistoryRequest) | [QueryContractHistoryResponse](#cosmwasm.wasm.v1.QueryContractHistoryResponse) | ContractHistory gets the contract code history | GET|/cosmwasm/wasm/v1/contract/{address}/history| -| `ContractsByCode` | [QueryContractsByCodeRequest](#cosmwasm.wasm.v1.QueryContractsByCodeRequest) | [QueryContractsByCodeResponse](#cosmwasm.wasm.v1.QueryContractsByCodeResponse) | ContractsByCode lists all smart contracts for a code id | GET|/cosmwasm/wasm/v1/code/{code_id}/contracts| -| `AllContractState` | [QueryAllContractStateRequest](#cosmwasm.wasm.v1.QueryAllContractStateRequest) | [QueryAllContractStateResponse](#cosmwasm.wasm.v1.QueryAllContractStateResponse) | AllContractState gets all raw store data for a single contract | GET|/cosmwasm/wasm/v1/contract/{address}/state| -| `RawContractState` | [QueryRawContractStateRequest](#cosmwasm.wasm.v1.QueryRawContractStateRequest) | [QueryRawContractStateResponse](#cosmwasm.wasm.v1.QueryRawContractStateResponse) | RawContractState gets single key from the raw store data of a contract | GET|/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}| -| `SmartContractState` | [QuerySmartContractStateRequest](#cosmwasm.wasm.v1.QuerySmartContractStateRequest) | [QuerySmartContractStateResponse](#cosmwasm.wasm.v1.QuerySmartContractStateResponse) | SmartContractState get smart query result from the contract | GET|/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}| -| `Code` | [QueryCodeRequest](#cosmwasm.wasm.v1.QueryCodeRequest) | [QueryCodeResponse](#cosmwasm.wasm.v1.QueryCodeResponse) | Code gets the binary code and metadata for a singe wasm code | GET|/cosmwasm/wasm/v1/code/{code_id}| -| `Codes` | [QueryCodesRequest](#cosmwasm.wasm.v1.QueryCodesRequest) | [QueryCodesResponse](#cosmwasm.wasm.v1.QueryCodesResponse) | Codes gets the metadata for all stored wasm codes | GET|/cosmwasm/wasm/v1/code| -| `PinnedCodes` | [QueryPinnedCodesRequest](#cosmwasm.wasm.v1.QueryPinnedCodesRequest) | [QueryPinnedCodesResponse](#cosmwasm.wasm.v1.QueryPinnedCodesResponse) | PinnedCodes gets the pinned code ids | GET|/cosmwasm/wasm/v1/codes/pinned| -| `Params` | [QueryParamsRequest](#cosmwasm.wasm.v1.QueryParamsRequest) | [QueryParamsResponse](#cosmwasm.wasm.v1.QueryParamsResponse) | Params gets the module params | GET|/cosmwasm/wasm/v1/codes/params| -| `ContractsByCreator` | [QueryContractsByCreatorRequest](#cosmwasm.wasm.v1.QueryContractsByCreatorRequest) | [QueryContractsByCreatorResponse](#cosmwasm.wasm.v1.QueryContractsByCreatorResponse) | ContractsByCreator gets the contracts by creator | GET|/cosmwasm/wasm/v1/contracts/creator/{creator_address}| +| `StoreCode` | [MsgStoreCode](#cosmwasm.wasm.v1.MsgStoreCode) | [MsgStoreCodeResponse](#cosmwasm.wasm.v1.MsgStoreCodeResponse) | StoreCode to submit Wasm code to the system | | +| `InstantiateContract` | [MsgInstantiateContract](#cosmwasm.wasm.v1.MsgInstantiateContract) | [MsgInstantiateContractResponse](#cosmwasm.wasm.v1.MsgInstantiateContractResponse) | InstantiateContract creates a new smart contract instance for the given code id. | | +| `InstantiateContract2` | [MsgInstantiateContract2](#cosmwasm.wasm.v1.MsgInstantiateContract2) | [MsgInstantiateContract2Response](#cosmwasm.wasm.v1.MsgInstantiateContract2Response) | InstantiateContract2 creates a new smart contract instance for the given code id with a predictable address | | +| `ExecuteContract` | [MsgExecuteContract](#cosmwasm.wasm.v1.MsgExecuteContract) | [MsgExecuteContractResponse](#cosmwasm.wasm.v1.MsgExecuteContractResponse) | Execute submits the given message data to a smart contract | | +| `MigrateContract` | [MsgMigrateContract](#cosmwasm.wasm.v1.MsgMigrateContract) | [MsgMigrateContractResponse](#cosmwasm.wasm.v1.MsgMigrateContractResponse) | Migrate runs a code upgrade/ downgrade for a smart contract | | +| `UpdateAdmin` | [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) | [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) | UpdateAdmin sets a new admin for a smart contract | | +| `ClearAdmin` | [MsgClearAdmin](#cosmwasm.wasm.v1.MsgClearAdmin) | [MsgClearAdminResponse](#cosmwasm.wasm.v1.MsgClearAdminResponse) | ClearAdmin removes any admin stored for a smart contract | | diff --git a/proto/cosmwasm/wasm/v1/genesis.proto b/proto/cosmwasm/wasm/v1/genesis.proto index b7622c206a..4e728ff4ba 100644 --- a/proto/cosmwasm/wasm/v1/genesis.proto +++ b/proto/cosmwasm/wasm/v1/genesis.proto @@ -3,7 +3,6 @@ package cosmwasm.wasm.v1; import "gogoproto/gogo.proto"; import "cosmwasm/wasm/v1/types.proto"; -import "cosmwasm/wasm/v1/tx.proto"; option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; @@ -20,23 +19,6 @@ message GenesisState { (gogoproto.nullable) = false, (gogoproto.jsontag) = "sequences,omitempty" ]; - repeated GenMsgs gen_msgs = 5 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "gen_msgs,omitempty" - ]; - - // GenMsgs define the messages that can be executed during genesis phase in - // order. The intention is to have more human readable data that is auditable. - message GenMsgs { - // sum is a single message - oneof sum { - MsgStoreCode store_code = 1; - MsgInstantiateContract instantiate_contract = 2; - MsgExecuteContract execute_contract = 3; - // MsgInstantiateContract2 intentionally not supported - // see https://github.com/CosmWasm/wasmd/issues/987 - } - } } // Code struct encompasses CodeInfo and CodeBytes diff --git a/proto/cosmwasm/wasm/v1/proposal.proto b/proto/cosmwasm/wasm/v1/proposal.proto index a419fea7cc..1b8fffaa00 100644 --- a/proto/cosmwasm/wasm/v1/proposal.proto +++ b/proto/cosmwasm/wasm/v1/proposal.proto @@ -60,14 +60,15 @@ message InstantiateContractProposal { ]; } -// InstantiateContract2Proposal gov proposal content type to instantiate contract 2 +// InstantiateContract2Proposal gov proposal content type to instantiate +// contract 2 message InstantiateContract2Proposal { // Title is a short summary string title = 1; // Description is a human readable text string description = 2; // RunAs is the address that is passed to the contract's enviroment as sender - string run_as = 3; + string run_as = 3; // Admin is an optional address that can execute migrations string admin = 4; // CodeID is the reference to the stored WASM code diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index b33d0a49fd..8a630868ca 100755 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -28,5 +28,3 @@ cd .. # move proto files to the right places cp -r github.com/CosmWasm/wasmd/* ./ rm -rf github.com - -go mod tidy diff --git a/x/wasm/client/cli/genesis_msg.go b/x/wasm/client/cli/genesis_msg.go deleted file mode 100644 index 674a54d1c6..0000000000 --- a/x/wasm/client/cli/genesis_msg.go +++ /dev/null @@ -1,531 +0,0 @@ -package cli - -import ( - "bufio" - "bytes" - "crypto/sha256" - "encoding/json" - "errors" - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/spf13/cobra" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/CosmWasm/wasmd/x/wasm/ioutils" - "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmWasm/wasmd/x/wasm/types" -) - -// GenesisReader reads genesis data. Extension point for custom genesis state readers. -type GenesisReader interface { - ReadWasmGenesis(cmd *cobra.Command) (*GenesisData, error) -} - -// GenesisMutator extension point to modify the wasm module genesis state. -// This gives flexibility to customize the data structure in the genesis file a bit. -type GenesisMutator interface { - // AlterWasmModuleState loads the genesis from the default or set home dir, - // unmarshalls the wasm module section into the object representation - // calls the callback function to modify it - // and marshals the modified state back into the genesis file - AlterWasmModuleState(cmd *cobra.Command, callback func(state *types.GenesisState, appState map[string]json.RawMessage) error) error -} - -// GenesisStoreCodeCmd cli command to add a `MsgStoreCode` to the wasm section of the genesis -// that is executed on block 0. -func GenesisStoreCodeCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { - cmd := &cobra.Command{ - Use: "store [wasm file] --run-as [owner_address_or_key_name]\",", - Short: "Upload a wasm binary", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - senderAddr, err := getActorAddress(cmd) - if err != nil { - return err - } - - msg, err := parseStoreCodeArgs(args[0], senderAddr, cmd.Flags()) - if err != nil { - return err - } - if err = msg.ValidateBasic(); err != nil { - return err - } - - return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, _ map[string]json.RawMessage) error { - state.GenMsgs = append(state.GenMsgs, types.GenesisState_GenMsgs{ - Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: &msg}, - }) - return nil - }) - }, - SilenceUsage: true, - } - cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator") - cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional") - cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional") - cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional") - cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") - - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// GenesisInstantiateContractCmd cli command to add a `MsgInstantiateContract` to the wasm section of the genesis -// that is executed on block 0. -func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { - cmd := &cobra.Command{ - Use: "instantiate-contract [code_id_int64] [json_encoded_init_args] --label [text] --run-as [address] --admin [address,optional] --amount [coins,optional]", - Short: "Instantiate a wasm contract", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - senderAddr, err := getActorAddress(cmd) - if err != nil { - return err - } - - msg, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, senderAddr, cmd.Flags()) - if err != nil { - return err - } - if err = msg.ValidateBasic(); err != nil { - return err - } - - return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { - // simple sanity check that sender has some balance, although it may be consumed by appState previous message already - switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); { - case err != nil: - return err - case !ok: - return errors.New("sender has not enough account balance") - } - - // does code id exists? - codeInfos := GetAllCodes(state) - if err != nil { - return err - } - var codeInfo *CodeMeta - for i := range codeInfos { - if codeInfos[i].CodeID == msg.CodeID { - codeInfo = &codeInfos[i] - break - } - } - if codeInfo == nil { - return fmt.Errorf("unknown code id: %d", msg.CodeID) - } - // permissions correct? - if !codeInfo.Info.InstantiateConfig.Allowed(senderAddr) { - return fmt.Errorf("permissions were not granted for %s", senderAddr) - } - state.GenMsgs = append(state.GenMsgs, types.GenesisState_GenMsgs{ - Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: msg}, - }) - return nil - }) - }, - SilenceUsage: true, - } - cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") - cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") - cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") - cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract.") - - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// GenesisExecuteContractCmd cli command to add a `MsgExecuteContract` to the wasm section of the genesis -// that is executed on block 0. -func GenesisExecuteContractCmd(defaultNodeHome string, genesisMutator GenesisMutator) *cobra.Command { - cmd := &cobra.Command{ - Use: "execute [contract_addr_bech32] [json_encoded_send_args] --run-as [address] --amount [coins,optional]", - Short: "Execute a command on a wasm contract", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - senderAddr, err := getActorAddress(cmd) - if err != nil { - return err - } - - msg, err := parseExecuteArgs(args[0], args[1], senderAddr, cmd.Flags()) - if err != nil { - return err - } - if err = msg.ValidateBasic(); err != nil { - return err - } - - return genesisMutator.AlterWasmModuleState(cmd, func(state *types.GenesisState, appState map[string]json.RawMessage) error { - // simple sanity check that sender has some balance, although it may be consumed by appState previous message already - switch ok, err := hasAccountBalance(cmd, appState, senderAddr, msg.Funds); { - case err != nil: - return err - case !ok: - return errors.New("sender has not enough account balance") - } - - // - does contract address exists? - if !hasContract(state, msg.Contract) { - return fmt.Errorf("unknown contract: %s", msg.Contract) - } - state.GenMsgs = append(state.GenMsgs, types.GenesisState_GenMsgs{ - Sum: &types.GenesisState_GenMsgs_ExecuteContract{ExecuteContract: &msg}, - }) - return nil - }) - }, - SilenceUsage: true, - } - cmd.Flags().String(flagAmount, "", "Coins to send to the contract along with command") - cmd.Flags().String(flagRunAs, "", "The address that pays the funds.") - - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// GenesisListCodesCmd cli command to list all codes stored in the genesis wasm.code section -// as well as from messages that are queued in the wasm.genMsgs section. -func GenesisListCodesCmd(defaultNodeHome string, genReader GenesisReader) *cobra.Command { - cmd := &cobra.Command{ - Use: "list-codes ", - Short: "Lists all codes from genesis code dump and queued messages", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - g, err := genReader.ReadWasmGenesis(cmd) - if err != nil { - return err - } - all := GetAllCodes(g.WasmModuleState) - if err != nil { - return err - } - return printJSONOutput(cmd, all) - }, - SilenceUsage: true, - } - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// GenesisListContractsCmd cli command to list all contracts stored in the genesis wasm.contract section -// as well as from messages that are queued in the wasm.genMsgs section. -func GenesisListContractsCmd(defaultNodeHome string, genReader GenesisReader) *cobra.Command { - cmd := &cobra.Command{ - Use: "list-contracts ", - Short: "Lists all contracts from genesis contract dump and queued messages", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - g, err := genReader.ReadWasmGenesis(cmd) - if err != nil { - return err - } - state := g.WasmModuleState - all := GetAllContracts(state) - return printJSONOutput(cmd, all) - }, - SilenceUsage: true, - } - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - flags.AddQueryFlagsToCmd(cmd) - return cmd -} - -// clientCtx marshaller works only with proto or bytes, so we marshal the output ourselves -func printJSONOutput(cmd *cobra.Command, obj interface{}) error { - clientCtx := client.GetClientContextFromCmd(cmd) - bz, err := json.MarshalIndent(obj, "", " ") - if err != nil { - return err - } - return clientCtx.PrintString(string(bz)) -} - -type CodeMeta struct { - CodeID uint64 `json:"code_id"` - Info types.CodeInfo `json:"info"` -} - -func GetAllCodes(state *types.GenesisState) []CodeMeta { - all := make([]CodeMeta, len(state.Codes)) - for i, c := range state.Codes { - all[i] = CodeMeta{ - CodeID: c.CodeID, - Info: c.CodeInfo, - } - } - // add inflight - seq := codeSeqValue(state) - for _, m := range state.GenMsgs { - if msg := m.GetStoreCode(); msg != nil { - var accessConfig types.AccessConfig - if msg.InstantiatePermission != nil { - accessConfig = *msg.InstantiatePermission - } else { - // default - creator := sdk.MustAccAddressFromBech32(msg.Sender) - accessConfig = state.Params.InstantiateDefaultPermission.With(creator) - } - bz := msg.WASMByteCode - if ioutils.IsGzip(msg.WASMByteCode) { - var err error - bz, err = ioutils.Uncompress(msg.WASMByteCode, uint64(types.MaxWasmSize)) - if err != nil { - panic(fmt.Sprintf("failed to unzip wasm binary: %s", err)) - } - } - hash := sha256.Sum256(bz) - all = append(all, CodeMeta{ - CodeID: seq, - Info: types.CodeInfo{ - CodeHash: hash[:], - Creator: msg.Sender, - InstantiateConfig: accessConfig, - }, - }) - seq++ - } - } - return all -} - -type ContractMeta struct { - ContractAddress string `json:"contract_address"` - Info types.ContractInfo `json:"info"` -} - -func GetAllContracts(state *types.GenesisState) []ContractMeta { - all := make([]ContractMeta, len(state.Contracts)) - for i, c := range state.Contracts { - all[i] = ContractMeta{ - ContractAddress: c.ContractAddress, - Info: c.ContractInfo, - } - } - // add inflight - seq := contractSeqValue(state) - for _, m := range state.GenMsgs { - if msg := m.GetInstantiateContract(); msg != nil { - all = append(all, ContractMeta{ - ContractAddress: keeper.BuildContractAddressClassic(msg.CodeID, seq).String(), - Info: types.ContractInfo{ - CodeID: msg.CodeID, - Creator: msg.Sender, - Admin: msg.Admin, - Label: msg.Label, - }, - }) - seq++ - } - } - return all -} - -func hasAccountBalance(cmd *cobra.Command, appState map[string]json.RawMessage, sender sdk.AccAddress, coins sdk.Coins) (bool, error) { - // no coins needed, no account needed - if coins.IsZero() { - return true, nil - } - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return false, err - } - cdc := clientCtx.Codec - var genBalIterator banktypes.GenesisBalancesIterator - err = genutil.ValidateAccountInGenesis(appState, genBalIterator, sender, coins, cdc) - if err != nil { - return false, err - } - return true, nil -} - -func hasContract(state *types.GenesisState, contractAddr string) bool { - for _, c := range state.Contracts { - if c.ContractAddress == contractAddr { - return true - } - } - seq := contractSeqValue(state) - for _, m := range state.GenMsgs { - if msg := m.GetInstantiateContract(); msg != nil { - if keeper.BuildContractAddressClassic(msg.CodeID, seq).String() == contractAddr { - return true - } - seq++ - } - } - return false -} - -// GenesisData contains raw and unmarshalled data from the genesis file -type GenesisData struct { - GenesisFile string - GenDoc *tmtypes.GenesisDoc - AppState map[string]json.RawMessage - WasmModuleState *types.GenesisState -} - -func NewGenesisData(genesisFile string, genDoc *tmtypes.GenesisDoc, appState map[string]json.RawMessage, wasmModuleState *types.GenesisState) *GenesisData { - return &GenesisData{GenesisFile: genesisFile, GenDoc: genDoc, AppState: appState, WasmModuleState: wasmModuleState} -} - -type DefaultGenesisReader struct{} - -func (d DefaultGenesisReader) ReadWasmGenesis(cmd *cobra.Command) (*GenesisData, error) { - clientCtx := client.GetClientContextFromCmd(cmd) - serverCtx := server.GetServerContextFromCmd(cmd) - config := serverCtx.Config - config.SetRoot(clientCtx.HomeDir) - - genFile := config.GenesisFile() - appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal genesis state: %w", err) - } - var wasmGenesisState types.GenesisState - if appState[types.ModuleName] != nil { - clientCtx := client.GetClientContextFromCmd(cmd) - clientCtx.Codec.MustUnmarshalJSON(appState[types.ModuleName], &wasmGenesisState) - } - - return NewGenesisData( - genFile, - genDoc, - appState, - &wasmGenesisState, - ), nil -} - -var ( - _ GenesisReader = DefaultGenesisIO{} - _ GenesisMutator = DefaultGenesisIO{} -) - -// DefaultGenesisIO implements both interfaces to read and modify the genesis state for this module. -// This implementation uses the default data structure that is used by the module.go genesis import/ export. -type DefaultGenesisIO struct { - DefaultGenesisReader -} - -// NewDefaultGenesisIO constructor to create a new instance -func NewDefaultGenesisIO() *DefaultGenesisIO { - return &DefaultGenesisIO{DefaultGenesisReader: DefaultGenesisReader{}} -} - -// AlterWasmModuleState loads the genesis from the default or set home dir, -// unmarshalls the wasm module section into the object representation -// calls the callback function to modify it -// and marshals the modified state back into the genesis file -func (x DefaultGenesisIO) AlterWasmModuleState(cmd *cobra.Command, callback func(state *types.GenesisState, appState map[string]json.RawMessage) error) error { - g, err := x.ReadWasmGenesis(cmd) - if err != nil { - return err - } - if err := callback(g.WasmModuleState, g.AppState); err != nil { - return err - } - // and store update - if err := g.WasmModuleState.ValidateBasic(); err != nil { - return err - } - clientCtx := client.GetClientContextFromCmd(cmd) - wasmGenStateBz, err := clientCtx.Codec.MarshalJSON(g.WasmModuleState) - if err != nil { - return sdkerrors.Wrap(err, "marshal wasm genesis state") - } - - g.AppState[types.ModuleName] = wasmGenStateBz - appStateJSON, err := json.Marshal(g.AppState) - if err != nil { - return sdkerrors.Wrap(err, "marshal application genesis state") - } - - g.GenDoc.AppState = appStateJSON - return genutil.ExportGenesisFile(g.GenDoc, g.GenesisFile) -} - -// contractSeqValue reads the contract sequence from the genesis or -// returns default start value used in the keeper -func contractSeqValue(state *types.GenesisState) uint64 { - var seq uint64 = 1 - for _, s := range state.Sequences { - if bytes.Equal(s.IDKey, types.KeyLastInstanceID) { - seq = s.Value - break - } - } - return seq -} - -// codeSeqValue reads the code sequence from the genesis or -// returns default start value used in the keeper -func codeSeqValue(state *types.GenesisState) uint64 { - var seq uint64 = 1 - for _, s := range state.Sequences { - if bytes.Equal(s.IDKey, types.KeyLastCodeID) { - seq = s.Value - break - } - } - return seq -} - -// getActorAddress returns the account address for the `--run-as` flag. -// The flag value can either be an address already or a key name where the -// address is read from the keyring instead. -func getActorAddress(cmd *cobra.Command) (sdk.AccAddress, error) { - actorArg, err := cmd.Flags().GetString(flagRunAs) - if err != nil { - return nil, fmt.Errorf("run-as: %s", err.Error()) - } - if len(actorArg) == 0 { - return nil, errors.New("run-as address is required") - } - - actorAddr, err := sdk.AccAddressFromBech32(actorArg) - if err == nil { - return actorAddr, nil - } - inBuf := bufio.NewReader(cmd.InOrStdin()) - keyringBackend, err := cmd.Flags().GetString(flags.FlagKeyringBackend) - if err != nil { - return nil, err - } - - homeDir := client.GetClientContextFromCmd(cmd).HomeDir - // attempt to lookup address from Keybase if no address was provided - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, homeDir, inBuf) - if err != nil { - return nil, err - } - - info, err := kb.Key(actorArg) - if err != nil { - return nil, fmt.Errorf("failed to get address from Keybase: %w", err) - } - return info.GetAddress(), nil -} diff --git a/x/wasm/client/cli/genesis_msg_test.go b/x/wasm/client/cli/genesis_msg_test.go deleted file mode 100644 index 335c30a246..0000000000 --- a/x/wasm/client/cli/genesis_msg_test.go +++ /dev/null @@ -1,748 +0,0 @@ -package cli - -import ( - "context" - "encoding/json" - "os" - "path" - "testing" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/CosmWasm/wasmd/x/wasm/keeper" - "github.com/CosmWasm/wasmd/x/wasm/types" -) - -var wasmIdent = []byte("\x00\x61\x73\x6D") - -var myWellFundedAccount = keeper.RandomBech32AccountAddress(nil) - -const defaultTestKeyName = "my-key-name" - -func TestGenesisStoreCodeCmd(t *testing.T) { - minimalWasmGenesis := types.GenesisState{ - Params: types.DefaultParams(), - } - anyValidWasmFile, err := os.CreateTemp(t.TempDir(), "wasm") - require.NoError(t, err) - anyValidWasmFile.Write(wasmIdent) - require.NoError(t, anyValidWasmFile.Close()) - - specs := map[string]struct { - srcGenesis types.GenesisState - mutator func(cmd *cobra.Command) - expError bool - }{ - "all good with actor address": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{anyValidWasmFile.Name()}) - flagSet := cmd.Flags() - flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t)) - }, - }, - "all good with key name": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{anyValidWasmFile.Name()}) - flagSet := cmd.Flags() - flagSet.Set("run-as", defaultTestKeyName) - }, - }, - "with unknown actor key name should fail": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{anyValidWasmFile.Name()}) - flagSet := cmd.Flags() - flagSet.Set("run-as", "unknown key") - }, - expError: true, - }, - "without actor should fail": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{anyValidWasmFile.Name()}) - }, - expError: true, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - homeDir := setupGenesis(t, spec.srcGenesis) - - // when - cmd := GenesisStoreCodeCmd(homeDir, NewDefaultGenesisIO()) - spec.mutator(cmd) - err := executeCmdWithContext(t, homeDir, cmd) - if spec.expError { - require.Error(t, err) - return - } - require.NoError(t, err) - // then - moduleState := loadModuleState(t, homeDir) - assert.Len(t, moduleState.GenMsgs, 1) - }) - } -} - -func TestInstantiateContractCmd(t *testing.T) { - minimalWasmGenesis := types.GenesisState{ - Params: types.DefaultParams(), - } - anyValidWasmFile, err := os.CreateTemp(t.TempDir(), "wasm") - require.NoError(t, err) - anyValidWasmFile.Write(wasmIdent) - require.NoError(t, anyValidWasmFile.Close()) - - specs := map[string]struct { - srcGenesis types.GenesisState - mutator func(cmd *cobra.Command) - expMsgCount int - expError bool - }{ - "all good with code id in genesis codes": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("no-admin", "true") - }, - expMsgCount: 1, - }, - "all good with code id from genesis store messages without initial sequence": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}}, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("admin", myWellFundedAccount) - }, - expMsgCount: 2, - }, - "all good with code id from genesis store messages without initial sequence and key name admin": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}}, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", defaultTestKeyName) - flagSet.Set("admin", defaultTestKeyName) - }, - expMsgCount: 2, - }, - "all good with code id from genesis store messages and sequence set": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}}, - }, - Sequences: []types.Sequence{ - {IDKey: types.KeyLastCodeID, Value: 100}, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"100", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("no-admin", "true") - }, - expMsgCount: 2, - }, - "fails with codeID not existing in codes": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"2", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("no-admin", "true") - }, - expError: true, - }, - "fails when instantiation permissions not granted": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture(func(code *types.MsgStoreCode) { - code.InstantiatePermission = &types.AllowNobody - })}}, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("no-admin", "true") - }, - expError: true, - }, - "fails if no explicit --no-admin passed": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - }, - expError: true, - }, - "fails if both --admin and --no-admin passed": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("no-admin", "true") - flagSet.Set("admin", myWellFundedAccount) - }, - expError: true, - }, - "succeeds with unknown account when no funds": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t)) - flagSet.Set("no-admin", "true") - }, - expMsgCount: 1, - }, - "succeeds with funds from well funded account": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("amount", "100stake") - flagSet.Set("no-admin", "true") - }, - expMsgCount: 1, - }, - "fails without enough sender balance": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfo{ - CodeHash: []byte("a-valid-code-hash"), - Creator: keeper.RandomBech32AccountAddress(t), - InstantiateConfig: types.AccessConfig{ - Permission: types.AccessTypeEverybody, - }, - }, - CodeBytes: wasmIdent, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{"1", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("label", "testing") - flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t)) - flagSet.Set("amount", "10stake") - flagSet.Set("no-admin", "true") - }, - expError: true, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - homeDir := setupGenesis(t, spec.srcGenesis) - - // when - cmd := GenesisInstantiateContractCmd(homeDir, NewDefaultGenesisIO()) - spec.mutator(cmd) - err := executeCmdWithContext(t, homeDir, cmd) - if spec.expError { - require.Error(t, err) - return - } - require.NoError(t, err) - // then - moduleState := loadModuleState(t, homeDir) - assert.Len(t, moduleState.GenMsgs, spec.expMsgCount) - }) - } -} - -func TestExecuteContractCmd(t *testing.T) { - const firstContractAddress = "cosmos14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4hmalr" - minimalWasmGenesis := types.GenesisState{ - Params: types.DefaultParams(), - } - anyValidWasmFile, err := os.CreateTemp(t.TempDir(), "wasm") - require.NoError(t, err) - anyValidWasmFile.Write(wasmIdent) - require.NoError(t, anyValidWasmFile.Close()) - - specs := map[string]struct { - srcGenesis types.GenesisState - mutator func(cmd *cobra.Command) - expMsgCount int - expError bool - }{ - "all good with contract in genesis contracts": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - Contracts: []types.Contract{ - { - ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(), - ContractState: []types.Model{}, - ContractCodeHistory: []types.ContractCodeHistoryEntry{ - types.ContractCodeHistoryEntryFixture(), - }, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{firstContractAddress, `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", myWellFundedAccount) - }, - expMsgCount: 1, - }, - "all good with contract from genesis store messages without initial sequence": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}}, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{firstContractAddress, `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", myWellFundedAccount) - }, - expMsgCount: 2, - }, - "all good with contract from genesis store messages and contract sequence set": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: types.MsgInstantiateContractFixture()}}, - }, - Sequences: []types.Sequence{ - {IDKey: types.KeyLastInstanceID, Value: 100}, - }, - }, - mutator: func(cmd *cobra.Command) { - // See TestBuildContractAddress in keeper_test.go - cmd.SetArgs([]string{"cosmos1mujpjkwhut9yjw4xueyugc02evfv46y0dtmnz4lh8xxkkdapym9stu5qm8", `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", myWellFundedAccount) - }, - expMsgCount: 2, - }, - "fails with unknown contract address": { - srcGenesis: minimalWasmGenesis, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{keeper.RandomBech32AccountAddress(t), `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", myWellFundedAccount) - }, - expError: true, - }, - "succeeds with unknown account when no funds": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - Contracts: []types.Contract{ - { - ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(), - ContractState: []types.Model{}, - ContractCodeHistory: []types.ContractCodeHistoryEntry{ - types.ContractCodeHistoryEntryFixture(), - }, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{firstContractAddress, `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t)) - }, - expMsgCount: 1, - }, - "succeeds with funds from well funded account": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - Contracts: []types.Contract{ - { - ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(), - ContractState: []types.Model{}, - ContractCodeHistory: []types.ContractCodeHistoryEntry{ - types.ContractCodeHistoryEntryFixture(), - }, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{firstContractAddress, `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", myWellFundedAccount) - flagSet.Set("amount", "100stake") - }, - expMsgCount: 1, - }, - "fails without enough sender balance": { - srcGenesis: types.GenesisState{ - Params: types.DefaultParams(), - Codes: []types.Code{ - { - CodeID: 1, - CodeInfo: types.CodeInfoFixture(), - CodeBytes: wasmIdent, - }, - }, - Contracts: []types.Contract{ - { - ContractAddress: firstContractAddress, - ContractInfo: types.ContractInfoFixture(), - ContractState: []types.Model{}, - ContractCodeHistory: []types.ContractCodeHistoryEntry{ - types.ContractCodeHistoryEntryFixture(), - }, - }, - }, - }, - mutator: func(cmd *cobra.Command) { - cmd.SetArgs([]string{firstContractAddress, `{}`}) - flagSet := cmd.Flags() - flagSet.Set("run-as", keeper.RandomBech32AccountAddress(t)) - flagSet.Set("amount", "10stake") - }, - expError: true, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - homeDir := setupGenesis(t, spec.srcGenesis) - cmd := GenesisExecuteContractCmd(homeDir, NewDefaultGenesisIO()) - spec.mutator(cmd) - - // when - err := executeCmdWithContext(t, homeDir, cmd) - if spec.expError { - require.Error(t, err) - return - } - require.NoError(t, err) - // then - moduleState := loadModuleState(t, homeDir) - assert.Len(t, moduleState.GenMsgs, spec.expMsgCount) - }) - } -} - -func TestGetAllContracts(t *testing.T) { - specs := map[string]struct { - src types.GenesisState - exp []ContractMeta - }{ - "read from contracts state": { - src: types.GenesisState{ - Contracts: []types.Contract{ - { - ContractAddress: "first-contract", - ContractInfo: types.ContractInfo{Label: "first"}, - }, - { - ContractAddress: "second-contract", - ContractInfo: types.ContractInfo{Label: "second"}, - }, - }, - }, - exp: []ContractMeta{ - { - ContractAddress: "first-contract", - Info: types.ContractInfo{Label: "first"}, - }, - { - ContractAddress: "second-contract", - Info: types.ContractInfo{Label: "second"}, - }, - }, - }, - "read from message state": { - src: types.GenesisState{ - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "first"}}}, - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "second"}}}, - }, - }, - exp: []ContractMeta{ - { - ContractAddress: keeper.BuildContractAddressClassic(0, 1).String(), - Info: types.ContractInfo{Label: "first"}, - }, - { - ContractAddress: keeper.BuildContractAddressClassic(0, 2).String(), - Info: types.ContractInfo{Label: "second"}, - }, - }, - }, - "read from message state with contract sequence": { - src: types.GenesisState{ - Sequences: []types.Sequence{ - {IDKey: types.KeyLastInstanceID, Value: 100}, - }, - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}}, - }, - }, - exp: []ContractMeta{ - { - ContractAddress: keeper.BuildContractAddressClassic(0, 100).String(), - Info: types.ContractInfo{Label: "hundred"}, - }, - }, - }, - "read from contract and message state with contract sequence": { - src: types.GenesisState{ - Contracts: []types.Contract{ - { - ContractAddress: "first-contract", - ContractInfo: types.ContractInfo{Label: "first"}, - }, - }, - Sequences: []types.Sequence{ - {IDKey: types.KeyLastInstanceID, Value: 100}, - }, - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_InstantiateContract{InstantiateContract: &types.MsgInstantiateContract{Label: "hundred"}}}, - }, - }, - exp: []ContractMeta{ - { - ContractAddress: "first-contract", - Info: types.ContractInfo{Label: "first"}, - }, - { - ContractAddress: keeper.BuildContractAddressClassic(0, 100).String(), - Info: types.ContractInfo{Label: "hundred"}, - }, - }, - }, - } - for msg, spec := range specs { - t.Run(msg, func(t *testing.T) { - got := GetAllContracts(&spec.src) - assert.Equal(t, spec.exp, got) - }) - } -} - -func setupGenesis(t *testing.T, wasmGenesis types.GenesisState) string { - appCodec := keeper.MakeEncodingConfig(t).Marshaler - homeDir := t.TempDir() - - require.NoError(t, os.Mkdir(path.Join(homeDir, "config"), 0o700)) - genFilename := path.Join(homeDir, "config", "genesis.json") - appState := make(map[string]json.RawMessage) - appState[types.ModuleName] = appCodec.MustMarshalJSON(&wasmGenesis) - - bankGenesis := banktypes.DefaultGenesisState() - bankGenesis.Balances = append(bankGenesis.Balances, banktypes.Balance{ - // add a balance for the default sender account - Address: myWellFundedAccount, - Coins: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10000000000))), - }) - appState[banktypes.ModuleName] = appCodec.MustMarshalJSON(bankGenesis) - appState[stakingtypes.ModuleName] = appCodec.MustMarshalJSON(stakingtypes.DefaultGenesisState()) - - appStateBz, err := json.Marshal(appState) - require.NoError(t, err) - genDoc := tmtypes.GenesisDoc{ - ChainID: "testing", - AppState: appStateBz, - } - err = genutil.ExportGenesisFile(&genDoc, genFilename) - require.NoError(t, err) - - return homeDir -} - -func executeCmdWithContext(t *testing.T, homeDir string, cmd *cobra.Command) error { - logger := log.NewNopLogger() - cfg, err := genutiltest.CreateDefaultTendermintConfig(homeDir) - require.NoError(t, err) - appCodec := keeper.MakeEncodingConfig(t).Marshaler - serverCtx := server.NewContext(viper.New(), cfg, logger) - clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(homeDir) - - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) - flagSet := cmd.Flags() - flagSet.Set("home", homeDir) - flagSet.Set(flags.FlagKeyringBackend, keyring.BackendTest) - - mockIn := testutil.ApplyMockIODiscardOutErr(cmd) - kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, homeDir, mockIn) - require.NoError(t, err) - _, err = kb.NewAccount(defaultTestKeyName, testdata.TestMnemonic, "", sdk.FullFundraiserPath, hd.Secp256k1) - require.NoError(t, err) - return cmd.ExecuteContext(ctx) -} - -func loadModuleState(t *testing.T, homeDir string) types.GenesisState { - genFilename := path.Join(homeDir, "config", "genesis.json") - appState, _, err := genutiltypes.GenesisStateFromGenFile(genFilename) - require.NoError(t, err) - require.Contains(t, appState, types.ModuleName) - - appCodec := keeper.MakeEncodingConfig(t).Marshaler - var moduleState types.GenesisState - require.NoError(t, appCodec.UnmarshalJSON(appState[types.ModuleName], &moduleState)) - return moduleState -} diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index c17f0f4086..4d1eb92870 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -212,7 +212,7 @@ func ProposalInstantiateContract2Cmd() *cobra.Command { return err } - src, err := parseInstantiateArgs(args[0], args[1], clientCtx.FromAddress, cmd.Flags()) + src, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, clientCtx.FromAddress, cmd.Flags()) if err != nil { return err } diff --git a/x/wasm/genesis_test.go b/x/wasm/genesis_test.go index d2bb8dc458..9d968f87a9 100644 --- a/x/wasm/genesis_test.go +++ b/x/wasm/genesis_test.go @@ -80,7 +80,7 @@ func TestInitGenesis(t *testing.T) { q2 := newData.module.LegacyQuerierHandler(nil) // initialize new app with genstate - InitGenesis(newData.ctx, &newData.keeper, *genState, newData.stakingKeeper, newData.module.Route().Handler()) + InitGenesis(newData.ctx, &newData.keeper, *genState) // run same checks again on newdata, to make sure it was reinitialized correctly assertCodeList(t, q2, newData.ctx, 1) diff --git a/x/wasm/keeper/genesis.go b/x/wasm/keeper/genesis.go index 2fb152a130..183c6f48ba 100644 --- a/x/wasm/keeper/genesis.go +++ b/x/wasm/keeper/genesis.go @@ -16,7 +16,7 @@ type ValidatorSetSource interface { // InitGenesis sets supply information for genesis. // // CONTRACT: all types of accounts must have been already initialized/created -func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, stakingKeeper ValidatorSetSource, msgHandler sdk.Handler) ([]abci.ValidatorUpdate, error) { +func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) ([]abci.ValidatorUpdate, error) { contractKeeper := NewGovPermissionKeeper(keeper) keeper.SetParams(ctx, data.Params) var maxCodeID uint64 @@ -64,21 +64,7 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState, staki if seqVal <= uint64(maxContractID) { return nil, sdkerrors.Wrapf(types.ErrInvalid, "seq %s with value: %d must be greater than: %d ", string(types.KeyLastInstanceID), seqVal, maxContractID) } - - if len(data.GenMsgs) == 0 { - return nil, nil - } - for _, genTx := range data.GenMsgs { - msg := genTx.AsMsg() - if msg == nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown message") - } - _, err := msgHandler(ctx, msg) - if err != nil { - return nil, sdkerrors.Wrap(err, "genesis") - } - } - return stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + return nil, nil } // ExportGenesis returns a GenesisState for a given context and keeper. diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index beba80fe7d..063b2adc50 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -1,10 +1,8 @@ package keeper import ( - "bytes" "crypto/sha256" "encoding/base64" - "errors" "fmt" "math/rand" "os" @@ -23,9 +21,7 @@ import ( fuzz "github.com/google/gofuzz" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/proto/tendermint/crypto" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" @@ -121,7 +117,7 @@ func TestGenesisExportImport(t *testing.T) { var importState wasmTypes.GenesisState err = dstKeeper.cdc.UnmarshalJSON(exportedGenesis, &importState) require.NoError(t, err) - InitGenesis(dstCtx, dstKeeper, importState, &StakingKeeperMock{}, TestHandler(contractKeeper)) + InitGenesis(dstCtx, dstKeeper, importState) // compare whole DB for j := range srcStoreKeys { @@ -149,10 +145,8 @@ func TestGenesisInit(t *testing.T) { myCodeInfo := wasmTypes.CodeInfoFixture(wasmTypes.WithSHA256CodeHash(wasmCode)) specs := map[string]struct { - src types.GenesisState - stakingMock StakingKeeperMock - msgHandlerMock MockMsgHandler - expSuccess bool + src types.GenesisState + expSuccess bool }{ "happy path: code info correct": { src: types.GenesisState{ @@ -457,53 +451,19 @@ func TestGenesisInit(t *testing.T) { Params: types.DefaultParams(), }, }, - "validator set update called for any genesis messages": { - src: wasmTypes.GenesisState{ - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{ - StoreCode: types.MsgStoreCodeFixture(), - }}, - }, - Params: types.DefaultParams(), - }, - stakingMock: StakingKeeperMock{expCalls: 1, validatorUpdate: []abci.ValidatorUpdate{ - { - PubKey: crypto.PublicKey{Sum: &crypto.PublicKey_Ed25519{ - Ed25519: []byte("a valid key"), - }}, - Power: 100, - }, - }}, - msgHandlerMock: MockMsgHandler{expCalls: 1, expMsg: types.MsgStoreCodeFixture()}, - expSuccess: true, - }, - "validator set update not called on genesis msg handler errors": { - src: wasmTypes.GenesisState{ - GenMsgs: []types.GenesisState_GenMsgs{ - {Sum: &types.GenesisState_GenMsgs_StoreCode{ - StoreCode: types.MsgStoreCodeFixture(), - }}, - }, - Params: types.DefaultParams(), - }, - msgHandlerMock: MockMsgHandler{expCalls: 1, err: errors.New("test error response")}, - stakingMock: StakingKeeperMock{expCalls: 0}, - }, } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { keeper, ctx, _ := setupKeeper(t) require.NoError(t, types.ValidateGenesis(spec.src)) - gotValidatorSet, gotErr := InitGenesis(ctx, keeper, spec.src, &spec.stakingMock, spec.msgHandlerMock.Handle) + _, gotErr := InitGenesis(ctx, keeper, spec.src) if !spec.expSuccess { require.Error(t, gotErr) return } require.NoError(t, gotErr) - spec.msgHandlerMock.verifyCalls(t) - spec.stakingMock.verifyCalls(t) - assert.Equal(t, spec.stakingMock.validatorUpdate, gotValidatorSet) + for _, c := range spec.src.Codes { assert.Equal(t, c.Pinned, keeper.IsPinnedCode(ctx, c.CodeID)) } @@ -575,7 +535,6 @@ func TestImportContractWithCodeHistoryPreserved(t *testing.T) { ] }` keeper, ctx, _ := setupKeeper(t) - contractKeeper := NewGovPermissionKeeper(keeper) wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) @@ -592,7 +551,7 @@ func TestImportContractWithCodeHistoryPreserved(t *testing.T) { ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter()) // when - _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(contractKeeper)) + _, err = InitGenesis(ctx, keeper, importState) require.NoError(t, err) // verify wasm code @@ -655,77 +614,6 @@ func TestImportContractWithCodeHistoryPreserved(t *testing.T) { assert.Equal(t, uint64(3), keeper.PeekAutoIncrementID(ctx, types.KeyLastInstanceID)) } -func TestSupportedGenMsgTypes(t *testing.T) { - wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") - require.NoError(t, err) - var ( - myAddress sdk.AccAddress = bytes.Repeat([]byte{1}, types.ContractAddrLen) - verifierAddress sdk.AccAddress = bytes.Repeat([]byte{2}, types.ContractAddrLen) - beneficiaryAddress sdk.AccAddress = bytes.Repeat([]byte{3}, types.ContractAddrLen) - ) - const denom = "stake" - importState := types.GenesisState{ - Params: types.DefaultParams(), - GenMsgs: []types.GenesisState_GenMsgs{ - { - Sum: &types.GenesisState_GenMsgs_StoreCode{ - StoreCode: &types.MsgStoreCode{ - Sender: myAddress.String(), - WASMByteCode: wasmCode, - }, - }, - }, - { - Sum: &types.GenesisState_GenMsgs_InstantiateContract{ - InstantiateContract: &types.MsgInstantiateContract{ - Sender: myAddress.String(), - CodeID: 1, - Label: "testing", - Msg: HackatomExampleInitMsg{ - Verifier: verifierAddress, - Beneficiary: beneficiaryAddress, - }.GetBytes(t), - Funds: sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))), - }, - }, - }, - { - Sum: &types.GenesisState_GenMsgs_ExecuteContract{ - ExecuteContract: &types.MsgExecuteContract{ - Sender: verifierAddress.String(), - Contract: BuildContractAddressClassic(1, 1).String(), - Msg: []byte(`{"release":{}}`), - }, - }, - }, - }, - } - require.NoError(t, importState.ValidateBasic()) - ctx, keepers := CreateDefaultTestInput(t) - keeper := keepers.WasmKeeper - ctx = ctx.WithBlockHeight(0).WithGasMeter(sdk.NewInfiniteGasMeter()) - keepers.Faucet.Fund(ctx, myAddress, sdk.NewCoin(denom, sdk.NewInt(100))) - - // when - _, err = InitGenesis(ctx, keeper, importState, &StakingKeeperMock{}, TestHandler(keepers.ContractKeeper)) - require.NoError(t, err) - - // verify code stored - gotWasmCode, err := keeper.GetByteCode(ctx, 1) - require.NoError(t, err) - assert.Equal(t, wasmCode, gotWasmCode) - codeInfo := keeper.GetCodeInfo(ctx, 1) - require.NotNil(t, codeInfo) - - // verify contract instantiated - cInfo := keeper.GetContractInfo(ctx, BuildContractAddressClassic(1, 1)) - require.NotNil(t, cInfo) - - // verify contract executed - gotBalance := keepers.BankKeeper.GetBalance(ctx, beneficiaryAddress, denom) - assert.Equal(t, sdk.NewCoin(denom, sdk.NewInt(10)), gotBalance) -} - func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) { t.Helper() tempDir, err := os.MkdirTemp("", "wasm") @@ -781,39 +669,3 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) { ) return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams} } - -type StakingKeeperMock struct { - err error - validatorUpdate []abci.ValidatorUpdate - expCalls int - gotCalls int -} - -func (s *StakingKeeperMock) ApplyAndReturnValidatorSetUpdates(_ sdk.Context) ([]abci.ValidatorUpdate, error) { - s.gotCalls++ - return s.validatorUpdate, s.err -} - -func (s *StakingKeeperMock) verifyCalls(t *testing.T) { - assert.Equal(t, s.expCalls, s.gotCalls, "number calls") -} - -type MockMsgHandler struct { - result *sdk.Result - err error - expCalls int - gotCalls int - expMsg sdk.Msg - gotMsg sdk.Msg -} - -func (m *MockMsgHandler) Handle(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { - m.gotCalls++ - m.gotMsg = msg - return m.result, m.err -} - -func (m *MockMsgHandler) verifyCalls(t *testing.T) { - assert.Equal(t, m.expMsg, m.gotMsg, "message param") - assert.Equal(t, m.expCalls, m.gotCalls, "number calls") -} diff --git a/x/wasm/module.go b/x/wasm/module.go index ea79b23768..cc83cf831f 100644 --- a/x/wasm/module.go +++ b/x/wasm/module.go @@ -168,7 +168,7 @@ func (AppModule) QuerierRoute() string { func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { var genesisState GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - validators, err := InitGenesis(ctx, am.keeper, genesisState, am.validatorSetSource, am.Route().Handler()) + validators, err := InitGenesis(ctx, am.keeper, genesisState) if err != nil { panic(err) } diff --git a/x/wasm/simulation/genesis.go b/x/wasm/simulation/genesis.go index 5271bd2365..eff45898ef 100644 --- a/x/wasm/simulation/genesis.go +++ b/x/wasm/simulation/genesis.go @@ -16,7 +16,6 @@ func RandomizedGenState(simstate *module.SimulationState) { Sequences: []types.Sequence{ {IDKey: types.KeyLastCodeID, Value: simstate.Rand.Uint64()}, }, - GenMsgs: nil, } _, err := simstate.Cdc.MarshalJSON(&wasmGenesis) diff --git a/x/wasm/types/genesis.go b/x/wasm/types/genesis.go index 4d6775d02e..f14dbc3d76 100644 --- a/x/wasm/types/genesis.go +++ b/x/wasm/types/genesis.go @@ -32,11 +32,7 @@ func (s GenesisState) ValidateBasic() error { return sdkerrors.Wrapf(err, "sequence: %d", i) } } - for i := range s.GenMsgs { - if err := s.GenMsgs[i].ValidateBasic(); err != nil { - return sdkerrors.Wrapf(err, "gen message: %d", i) - } - } + return nil } @@ -80,28 +76,6 @@ func (c Contract) ValidateBasic() error { return nil } -// AsMsg returns the underlying cosmos-sdk message instance. Null when can not be mapped to a known type. -func (m GenesisState_GenMsgs) AsMsg() sdk.Msg { - if msg := m.GetStoreCode(); msg != nil { - return msg - } - if msg := m.GetInstantiateContract(); msg != nil { - return msg - } - if msg := m.GetExecuteContract(); msg != nil { - return msg - } - return nil -} - -func (m GenesisState_GenMsgs) ValidateBasic() error { - msg := m.AsMsg() - if msg == nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "unknown message") - } - return msg.ValidateBasic() -} - // ValidateGenesis performs basic validation of supply genesis data returning an // error for any failed validation criteria. func ValidateGenesis(data GenesisState) error { diff --git a/x/wasm/types/genesis.pb.go b/x/wasm/types/genesis.pb.go index b080905ab4..b753dc1a83 100644 --- a/x/wasm/types/genesis.pb.go +++ b/x/wasm/types/genesis.pb.go @@ -28,11 +28,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState - genesis state of x/wasm type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - Codes []Code `protobuf:"bytes,2,rep,name=codes,proto3" json:"codes,omitempty"` - Contracts []Contract `protobuf:"bytes,3,rep,name=contracts,proto3" json:"contracts,omitempty"` - Sequences []Sequence `protobuf:"bytes,4,rep,name=sequences,proto3" json:"sequences,omitempty"` - GenMsgs []GenesisState_GenMsgs `protobuf:"bytes,5,rep,name=gen_msgs,json=genMsgs,proto3" json:"gen_msgs,omitempty"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Codes []Code `protobuf:"bytes,2,rep,name=codes,proto3" json:"codes,omitempty"` + Contracts []Contract `protobuf:"bytes,3,rep,name=contracts,proto3" json:"contracts,omitempty"` + Sequences []Sequence `protobuf:"bytes,4,rep,name=sequences,proto3" json:"sequences,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -101,120 +100,6 @@ func (m *GenesisState) GetSequences() []Sequence { return nil } -func (m *GenesisState) GetGenMsgs() []GenesisState_GenMsgs { - if m != nil { - return m.GenMsgs - } - return nil -} - -// GenMsgs define the messages that can be executed during genesis phase in -// order. The intention is to have more human readable data that is auditable. -type GenesisState_GenMsgs struct { - // sum is a single message - // - // Types that are valid to be assigned to Sum: - // *GenesisState_GenMsgs_StoreCode - // *GenesisState_GenMsgs_InstantiateContract - // *GenesisState_GenMsgs_ExecuteContract - Sum isGenesisState_GenMsgs_Sum `protobuf_oneof:"sum"` -} - -func (m *GenesisState_GenMsgs) Reset() { *m = GenesisState_GenMsgs{} } -func (m *GenesisState_GenMsgs) String() string { return proto.CompactTextString(m) } -func (*GenesisState_GenMsgs) ProtoMessage() {} -func (*GenesisState_GenMsgs) Descriptor() ([]byte, []int) { - return fileDescriptor_2ab3f539b23472a6, []int{0, 0} -} - -func (m *GenesisState_GenMsgs) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} - -func (m *GenesisState_GenMsgs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_GenesisState_GenMsgs.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} - -func (m *GenesisState_GenMsgs) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenesisState_GenMsgs.Merge(m, src) -} - -func (m *GenesisState_GenMsgs) XXX_Size() int { - return m.Size() -} - -func (m *GenesisState_GenMsgs) XXX_DiscardUnknown() { - xxx_messageInfo_GenesisState_GenMsgs.DiscardUnknown(m) -} - -var xxx_messageInfo_GenesisState_GenMsgs proto.InternalMessageInfo - -type isGenesisState_GenMsgs_Sum interface { - isGenesisState_GenMsgs_Sum() - MarshalTo([]byte) (int, error) - Size() int -} - -type GenesisState_GenMsgs_StoreCode struct { - StoreCode *MsgStoreCode `protobuf:"bytes,1,opt,name=store_code,json=storeCode,proto3,oneof" json:"store_code,omitempty"` -} -type GenesisState_GenMsgs_InstantiateContract struct { - InstantiateContract *MsgInstantiateContract `protobuf:"bytes,2,opt,name=instantiate_contract,json=instantiateContract,proto3,oneof" json:"instantiate_contract,omitempty"` -} -type GenesisState_GenMsgs_ExecuteContract struct { - ExecuteContract *MsgExecuteContract `protobuf:"bytes,3,opt,name=execute_contract,json=executeContract,proto3,oneof" json:"execute_contract,omitempty"` -} - -func (*GenesisState_GenMsgs_StoreCode) isGenesisState_GenMsgs_Sum() {} -func (*GenesisState_GenMsgs_InstantiateContract) isGenesisState_GenMsgs_Sum() {} -func (*GenesisState_GenMsgs_ExecuteContract) isGenesisState_GenMsgs_Sum() {} - -func (m *GenesisState_GenMsgs) GetSum() isGenesisState_GenMsgs_Sum { - if m != nil { - return m.Sum - } - return nil -} - -func (m *GenesisState_GenMsgs) GetStoreCode() *MsgStoreCode { - if x, ok := m.GetSum().(*GenesisState_GenMsgs_StoreCode); ok { - return x.StoreCode - } - return nil -} - -func (m *GenesisState_GenMsgs) GetInstantiateContract() *MsgInstantiateContract { - if x, ok := m.GetSum().(*GenesisState_GenMsgs_InstantiateContract); ok { - return x.InstantiateContract - } - return nil -} - -func (m *GenesisState_GenMsgs) GetExecuteContract() *MsgExecuteContract { - if x, ok := m.GetSum().(*GenesisState_GenMsgs_ExecuteContract); ok { - return x.ExecuteContract - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*GenesisState_GenMsgs) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*GenesisState_GenMsgs_StoreCode)(nil), - (*GenesisState_GenMsgs_InstantiateContract)(nil), - (*GenesisState_GenMsgs_ExecuteContract)(nil), - } -} - // Code struct encompasses CodeInfo and CodeBytes type Code struct { CodeID uint64 `protobuf:"varint,1,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` @@ -424,7 +309,6 @@ func (m *Sequence) GetValue() uint64 { func init() { proto.RegisterType((*GenesisState)(nil), "cosmwasm.wasm.v1.GenesisState") - proto.RegisterType((*GenesisState_GenMsgs)(nil), "cosmwasm.wasm.v1.GenesisState.GenMsgs") proto.RegisterType((*Code)(nil), "cosmwasm.wasm.v1.Code") proto.RegisterType((*Contract)(nil), "cosmwasm.wasm.v1.Contract") proto.RegisterType((*Sequence)(nil), "cosmwasm.wasm.v1.Sequence") @@ -433,50 +317,42 @@ func init() { func init() { proto.RegisterFile("cosmwasm/wasm/v1/genesis.proto", fileDescriptor_2ab3f539b23472a6) } var fileDescriptor_2ab3f539b23472a6 = []byte{ - // 676 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x94, 0xcf, 0x6e, 0xd3, 0x40, - 0x10, 0xc6, 0xe3, 0x24, 0x4e, 0x93, 0x69, 0xa0, 0xd5, 0xb6, 0xb4, 0xc6, 0x80, 0x13, 0x05, 0x54, - 0x05, 0x84, 0x12, 0xb5, 0x48, 0xdc, 0x10, 0xe0, 0xb6, 0xa2, 0x51, 0x55, 0x09, 0x5c, 0x21, 0x24, - 0xa4, 0x2a, 0x72, 0xed, 0xad, 0x6b, 0x51, 0x7b, 0x43, 0x76, 0x53, 0xea, 0x33, 0x2f, 0xc0, 0x23, - 0xc0, 0x9d, 0x07, 0xe9, 0xb1, 0x47, 0x4e, 0x11, 0x4a, 0x6f, 0x3c, 0x05, 0xda, 0x3f, 0x76, 0x0d, - 0x49, 0x2e, 0x56, 0x76, 0xe6, 0x9b, 0xdf, 0xee, 0x7e, 0x99, 0x59, 0xb0, 0x3c, 0x42, 0xa3, 0x2f, - 0x2e, 0x8d, 0xba, 0xe2, 0x73, 0xbe, 0xd9, 0x0d, 0x70, 0x8c, 0x69, 0x48, 0x3b, 0x83, 0x21, 0x61, - 0x04, 0x2d, 0xa7, 0xf9, 0x8e, 0xf8, 0x9c, 0x6f, 0x9a, 0xab, 0x01, 0x09, 0x88, 0x48, 0x76, 0xf9, - 0x2f, 0xa9, 0x33, 0xef, 0x4f, 0x71, 0x58, 0x32, 0xc0, 0x8a, 0x62, 0xde, 0x9d, 0xce, 0x5e, 0xc8, - 0x54, 0xeb, 0xbb, 0x0e, 0xf5, 0x37, 0x72, 0xcb, 0x43, 0xe6, 0x32, 0x8c, 0x9e, 0x43, 0x65, 0xe0, - 0x0e, 0xdd, 0x88, 0x1a, 0x5a, 0x53, 0x6b, 0x2f, 0x6e, 0x19, 0x9d, 0xff, 0x8f, 0xd0, 0x79, 0x2b, - 0xf2, 0x76, 0xf9, 0x72, 0xdc, 0x28, 0x38, 0x4a, 0x8d, 0x76, 0x41, 0xf7, 0x88, 0x8f, 0xa9, 0x51, - 0x6c, 0x96, 0xda, 0x8b, 0x5b, 0x6b, 0xd3, 0x65, 0xdb, 0xc4, 0xc7, 0xf6, 0x3a, 0x2f, 0xfa, 0x33, - 0x6e, 0x2c, 0x09, 0xf1, 0x53, 0x12, 0x85, 0x0c, 0x47, 0x03, 0x96, 0x38, 0xb2, 0x1a, 0xbd, 0x87, - 0x9a, 0x47, 0x62, 0x36, 0x74, 0x3d, 0x46, 0x8d, 0x92, 0x40, 0x99, 0xb3, 0x50, 0x52, 0x62, 0xdf, - 0x53, 0xb8, 0x95, 0xac, 0x28, 0x87, 0xbc, 0x21, 0x71, 0x2c, 0xc5, 0x9f, 0x47, 0x38, 0xf6, 0x30, - 0x35, 0xca, 0xf3, 0xb0, 0x87, 0x4a, 0x72, 0x83, 0xcd, 0x8a, 0xf2, 0xd8, 0x2c, 0x88, 0x8e, 0xa0, - 0x1a, 0xe0, 0xb8, 0x1f, 0xd1, 0x80, 0x1a, 0xba, 0xa0, 0x6e, 0x4c, 0x53, 0xf3, 0xf6, 0xf2, 0xc5, - 0x01, 0x0d, 0xa8, 0x6d, 0xaa, 0x1d, 0x50, 0x5a, 0x9f, 0xdb, 0x60, 0x21, 0x90, 0x22, 0xf3, 0x6b, - 0x11, 0x16, 0x54, 0x01, 0x7a, 0x09, 0x40, 0x19, 0x19, 0xe2, 0x3e, 0xf7, 0x49, 0xfd, 0x37, 0xd6, - 0xf4, 0x66, 0x07, 0x34, 0x38, 0xe4, 0x32, 0x6e, 0xf6, 0x5e, 0xc1, 0xa9, 0xd1, 0x74, 0x81, 0x8e, - 0x60, 0x35, 0x8c, 0x29, 0x73, 0x63, 0x16, 0xba, 0x8c, 0x63, 0xa4, 0x37, 0x46, 0x51, 0xa0, 0xda, - 0x33, 0x51, 0xbd, 0x9b, 0x82, 0xd4, 0xf2, 0xbd, 0x82, 0xb3, 0x12, 0x4e, 0x87, 0xd1, 0x3b, 0x58, - 0xc6, 0x17, 0xd8, 0x1b, 0xe5, 0xd1, 0x25, 0x81, 0x7e, 0x34, 0x13, 0xbd, 0x2b, 0xc5, 0x39, 0xec, - 0x12, 0xfe, 0x37, 0x64, 0xeb, 0x50, 0xa2, 0xa3, 0xa8, 0xf5, 0x43, 0x83, 0xb2, 0xb8, 0xc1, 0x43, - 0x58, 0xe0, 0x97, 0xef, 0x87, 0xbe, 0xb8, 0x7f, 0xd9, 0x86, 0xc9, 0xb8, 0x51, 0xe1, 0xa9, 0xde, - 0x8e, 0x53, 0xe1, 0xa9, 0x9e, 0x8f, 0x5e, 0xf0, 0x06, 0xe2, 0xa2, 0xf8, 0x84, 0xa8, 0xbb, 0x99, - 0xb3, 0x7b, 0xb1, 0x17, 0x9f, 0x10, 0xd5, 0xc4, 0x55, 0x4f, 0xad, 0xd1, 0x03, 0x00, 0x51, 0x7e, - 0x9c, 0x30, 0x4c, 0xc5, 0x05, 0xea, 0x8e, 0x00, 0xda, 0x3c, 0x80, 0xd6, 0xa0, 0x32, 0x08, 0xe3, - 0x18, 0xfb, 0x46, 0xb9, 0xa9, 0xb5, 0xab, 0x8e, 0x5a, 0xb5, 0x7e, 0x16, 0xa1, 0x9a, 0x59, 0xf1, - 0x18, 0x96, 0x53, 0x0b, 0xfa, 0xae, 0xef, 0x0f, 0x31, 0x95, 0xc3, 0x54, 0x73, 0x96, 0xd2, 0xf8, - 0x6b, 0x19, 0x46, 0x3d, 0xb8, 0x95, 0x49, 0x73, 0x27, 0xb6, 0xe6, 0xb7, 0x7c, 0xee, 0xd4, 0x75, - 0x2f, 0x17, 0x43, 0x3b, 0x70, 0x3b, 0x43, 0x51, 0xde, 0x6b, 0x6a, 0x7c, 0xd6, 0x67, 0xd8, 0x4f, - 0x7c, 0x7c, 0xa6, 0x20, 0xd9, 0xfe, 0x72, 0xfc, 0x7d, 0xb8, 0x93, 0x51, 0x84, 0x11, 0xa7, 0x21, - 0x6f, 0xa1, 0x44, 0x0d, 0xcd, 0x93, 0xf9, 0x07, 0x13, 0x1d, 0x27, 0xc5, 0xbb, 0x31, 0x1b, 0x26, - 0x8a, 0x9f, 0x4d, 0x66, 0x2e, 0xdf, 0xb2, 0xa1, 0x9a, 0xce, 0x1a, 0x6a, 0x42, 0x25, 0xf4, 0xfb, - 0x9f, 0x70, 0x22, 0x3c, 0xaa, 0xdb, 0xb5, 0xc9, 0xb8, 0xa1, 0xf7, 0x76, 0xf6, 0x71, 0xe2, 0xe8, - 0xa1, 0xbf, 0x8f, 0x13, 0xb4, 0x0a, 0xfa, 0xb9, 0x7b, 0x36, 0xc2, 0xc2, 0x9c, 0xb2, 0x23, 0x17, - 0xf6, 0xab, 0xcb, 0x89, 0xa5, 0x5d, 0x4d, 0x2c, 0xed, 0xf7, 0xc4, 0xd2, 0xbe, 0x5d, 0x5b, 0x85, - 0xab, 0x6b, 0xab, 0xf0, 0xeb, 0xda, 0x2a, 0x7c, 0xdc, 0x08, 0x42, 0x76, 0x3a, 0x3a, 0xee, 0x78, - 0x24, 0xea, 0x6e, 0x13, 0x1a, 0x7d, 0x48, 0x5f, 0x3e, 0xbf, 0x7b, 0x21, 0x5f, 0x40, 0xf1, 0x38, - 0x1e, 0x57, 0xc4, 0x13, 0xf8, 0xec, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xb6, 0x2c, 0x20, - 0x85, 0x05, 0x00, 0x00, + // 546 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xe3, 0xd4, 0x31, 0xe9, 0x36, 0xd0, 0x6a, 0x29, 0xad, 0x15, 0xc0, 0x89, 0x82, 0x84, + 0x02, 0x42, 0xb6, 0x5a, 0x24, 0x6e, 0x48, 0xe0, 0xa6, 0x02, 0xab, 0x42, 0x42, 0xae, 0x10, 0x12, + 0x97, 0xc8, 0xf1, 0x6e, 0x53, 0x8b, 0xda, 0x6b, 0xbc, 0x9b, 0x80, 0xdf, 0x82, 0x57, 0xe0, 0xce, + 0x1b, 0xf0, 0x02, 0x3d, 0xf6, 0xc8, 0x29, 0x42, 0xce, 0x8d, 0xa7, 0x40, 0xfb, 0xc7, 0xae, 0x45, + 0x9a, 0x8b, 0xe5, 0x9d, 0xf9, 0xe6, 0xe7, 0xf5, 0x37, 0x33, 0xc0, 0x0a, 0x09, 0x8d, 0xbf, 0x06, + 0x34, 0x76, 0xc4, 0x63, 0x7e, 0xe0, 0x4c, 0x71, 0x82, 0x69, 0x44, 0xed, 0x34, 0x23, 0x8c, 0xc0, + 0x9d, 0x32, 0x6f, 0x8b, 0xc7, 0xfc, 0xa0, 0xbb, 0x3b, 0x25, 0x53, 0x22, 0x92, 0x0e, 0x7f, 0x93, + 0xba, 0xee, 0x83, 0x15, 0x0e, 0xcb, 0x53, 0xac, 0x28, 0x83, 0x5f, 0x4d, 0xd0, 0x79, 0x23, 0xb9, + 0xa7, 0x2c, 0x60, 0x18, 0xbe, 0x00, 0x46, 0x1a, 0x64, 0x41, 0x4c, 0x4d, 0xad, 0xaf, 0x0d, 0xb7, + 0x0e, 0x4d, 0xfb, 0xff, 0xef, 0xd8, 0xef, 0x45, 0xde, 0xd5, 0x2f, 0x17, 0xbd, 0x86, 0xaf, 0xd4, + 0xf0, 0x18, 0xb4, 0x42, 0x82, 0x30, 0x35, 0x9b, 0xfd, 0x8d, 0xe1, 0xd6, 0xe1, 0xde, 0x6a, 0xd9, + 0x11, 0x41, 0xd8, 0xdd, 0xe7, 0x45, 0x7f, 0x17, 0xbd, 0x6d, 0x21, 0x7e, 0x46, 0xe2, 0x88, 0xe1, + 0x38, 0x65, 0xb9, 0x2f, 0xab, 0xe1, 0x07, 0xb0, 0x19, 0x92, 0x84, 0x65, 0x41, 0xc8, 0xa8, 0xb9, + 0x21, 0x50, 0xdd, 0x9b, 0x50, 0x52, 0xe2, 0xde, 0x57, 0xb8, 0xbb, 0x55, 0x51, 0x0d, 0x79, 0x4d, + 0xe2, 0x58, 0x8a, 0xbf, 0xcc, 0x70, 0x12, 0x62, 0x6a, 0xea, 0xeb, 0xb0, 0xa7, 0x4a, 0x72, 0x8d, + 0xad, 0x8a, 0xea, 0xd8, 0x2a, 0x38, 0xf8, 0xa1, 0x01, 0x9d, 0xff, 0x16, 0x7c, 0x04, 0x6e, 0xf1, + 0xfb, 0x8f, 0x23, 0x24, 0x6c, 0xd3, 0x5d, 0x50, 0x2c, 0x7a, 0x06, 0x4f, 0x79, 0x23, 0xdf, 0xe0, + 0x29, 0x0f, 0xc1, 0x97, 0xfc, 0xdf, 0xb8, 0x28, 0x39, 0x23, 0x66, 0x53, 0xb8, 0xdb, 0xbd, 0xd9, + 0x26, 0x2f, 0x39, 0x23, 0xca, 0xdf, 0x76, 0xa8, 0xce, 0xf0, 0x21, 0x00, 0xa2, 0x7c, 0x92, 0x33, + 0xcc, 0xbd, 0xd1, 0x86, 0x1d, 0x5f, 0x00, 0x5d, 0x1e, 0x80, 0x7b, 0xc0, 0x48, 0xa3, 0x24, 0xc1, + 0xc8, 0xd4, 0xfb, 0xda, 0xb0, 0xed, 0xab, 0xd3, 0xe0, 0x67, 0x13, 0xb4, 0x4b, 0xbf, 0xe0, 0x13, + 0xb0, 0x53, 0x9a, 0x32, 0x0e, 0x10, 0xca, 0x30, 0x95, 0x7d, 0xde, 0xf4, 0xb7, 0xcb, 0xf8, 0x6b, + 0x19, 0x86, 0x1e, 0xb8, 0x5d, 0x49, 0x6b, 0x37, 0xb6, 0xd6, 0x77, 0xa3, 0x76, 0xeb, 0x4e, 0x58, + 0x8b, 0xc1, 0x11, 0xb8, 0x53, 0xa1, 0x28, 0x9f, 0x32, 0xd5, 0xd9, 0xfd, 0x55, 0xd6, 0x3b, 0x82, + 0xf0, 0x85, 0x82, 0x54, 0xdf, 0x97, 0x93, 0x89, 0xc0, 0xbd, 0x8a, 0x22, 0x8c, 0x38, 0x8f, 0x28, + 0x23, 0x59, 0xae, 0xfa, 0xf9, 0x74, 0xfd, 0xc5, 0xb8, 0xa5, 0x6f, 0xa5, 0xf8, 0x38, 0x61, 0x59, + 0xae, 0xf8, 0xd5, 0xd0, 0xd4, 0xf2, 0x03, 0x17, 0xb4, 0xcb, 0x31, 0x80, 0x7d, 0x60, 0x44, 0x68, + 0xfc, 0x19, 0xe7, 0xc2, 0xa3, 0x8e, 0xbb, 0x59, 0x2c, 0x7a, 0x2d, 0x6f, 0x74, 0x82, 0x73, 0xbf, + 0x15, 0xa1, 0x13, 0x9c, 0xc3, 0x5d, 0xd0, 0x9a, 0x07, 0x17, 0x33, 0x2c, 0xcc, 0xd1, 0x7d, 0x79, + 0x70, 0x5f, 0x5d, 0x16, 0x96, 0x76, 0x55, 0x58, 0xda, 0x9f, 0xc2, 0xd2, 0xbe, 0x2f, 0xad, 0xc6, + 0xd5, 0xd2, 0x6a, 0xfc, 0x5e, 0x5a, 0x8d, 0x4f, 0x8f, 0xa7, 0x11, 0x3b, 0x9f, 0x4d, 0xec, 0x90, + 0xc4, 0xce, 0x11, 0xa1, 0xf1, 0xc7, 0x72, 0x2f, 0x91, 0xf3, 0x4d, 0xee, 0xa7, 0x58, 0xce, 0x89, + 0x21, 0xb6, 0xf3, 0xf9, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0x33, 0x7b, 0x9f, 0x05, 0x04, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -499,20 +375,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.GenMsgs) > 0 { - for iNdEx := len(m.GenMsgs) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.GenMsgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - } if len(m.Sequences) > 0 { for iNdEx := len(m.Sequences) - 1; iNdEx >= 0; iNdEx-- { { @@ -568,104 +430,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *GenesisState_GenMsgs) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GenesisState_GenMsgs) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState_GenMsgs) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Sum != nil { - { - size := m.Sum.Size() - i -= size - if _, err := m.Sum.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *GenesisState_GenMsgs_StoreCode) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState_GenMsgs_StoreCode) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.StoreCode != nil { - { - size, err := m.StoreCode.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *GenesisState_GenMsgs_InstantiateContract) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState_GenMsgs_InstantiateContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.InstantiateContract != nil { - { - size, err := m.InstantiateContract.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} - -func (m *GenesisState_GenMsgs_ExecuteContract) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *GenesisState_GenMsgs_ExecuteContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.ExecuteContract != nil { - { - size, err := m.ExecuteContract.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - return len(dAtA) - i, nil -} - func (m *Code) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -862,63 +626,6 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.GenMsgs) > 0 { - for _, e := range m.GenMsgs { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } - return n -} - -func (m *GenesisState_GenMsgs) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Sum != nil { - n += m.Sum.Size() - } - return n -} - -func (m *GenesisState_GenMsgs_StoreCode) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.StoreCode != nil { - l = m.StoreCode.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - -func (m *GenesisState_GenMsgs_InstantiateContract) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.InstantiateContract != nil { - l = m.InstantiateContract.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - -func (m *GenesisState_GenMsgs_ExecuteContract) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ExecuteContract != nil { - l = m.ExecuteContract.Size() - n += 1 + l + sovGenesis(uint64(l)) - } return n } @@ -1158,196 +865,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GenMsgs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GenMsgs = append(m.GenMsgs, GenesisState_GenMsgs{}) - if err := m.GenMsgs[len(m.GenMsgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} - -func (m *GenesisState_GenMsgs) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GenMsgs: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GenMsgs: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StoreCode", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &MsgStoreCode{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Sum = &GenesisState_GenMsgs_StoreCode{v} - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InstantiateContract", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &MsgInstantiateContract{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Sum = &GenesisState_GenMsgs_InstantiateContract{v} - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecuteContract", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &MsgExecuteContract{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Sum = &GenesisState_GenMsgs_ExecuteContract{v} - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/wasm/types/genesis_test.go b/x/wasm/types/genesis_test.go index f45d3f07f0..51c95e4d16 100644 --- a/x/wasm/types/genesis_test.go +++ b/x/wasm/types/genesis_test.go @@ -47,30 +47,6 @@ func TestValidateGenesisState(t *testing.T) { }, expError: true, }, - "genesis store code message invalid": { - srcMutator: func(s *GenesisState) { - s.GenMsgs[0].GetStoreCode().WASMByteCode = nil - }, - expError: true, - }, - "genesis instantiate contract message invalid": { - srcMutator: func(s *GenesisState) { - s.GenMsgs[1].GetInstantiateContract().CodeID = 0 - }, - expError: true, - }, - "genesis execute contract message invalid": { - srcMutator: func(s *GenesisState) { - s.GenMsgs[2].GetExecuteContract().Sender = "invalid" - }, - expError: true, - }, - "genesis invalid message type": { - srcMutator: func(s *GenesisState) { - s.GenMsgs[0].Sum = nil - }, - expError: true, - }, } for msg, spec := range specs { t.Run(msg, func(t *testing.T) { diff --git a/x/wasm/types/proposal.pb.go b/x/wasm/types/proposal.pb.go index 6062ffdbfa..4f10a4684c 100644 --- a/x/wasm/types/proposal.pb.go +++ b/x/wasm/types/proposal.pb.go @@ -148,7 +148,8 @@ func (m *InstantiateContractProposal) XXX_DiscardUnknown() { var xxx_messageInfo_InstantiateContractProposal proto.InternalMessageInfo -// InstantiateContract2Proposal gov proposal content type to instantiate contract 2 +// InstantiateContract2Proposal gov proposal content type to instantiate +// contract 2 type InstantiateContract2Proposal struct { // Title is a short summary Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index 1f68e4bb56..e84b61fd7d 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -36,11 +36,7 @@ func GenesisFixture(mutators ...func(*GenesisState)) GenesisState { Value: uint64(i), } } - fixture.GenMsgs = []GenesisState_GenMsgs{ - {Sum: &GenesisState_GenMsgs_StoreCode{StoreCode: MsgStoreCodeFixture()}}, - {Sum: &GenesisState_GenMsgs_InstantiateContract{InstantiateContract: MsgInstantiateContractFixture()}}, - {Sum: &GenesisState_GenMsgs_ExecuteContract{ExecuteContract: MsgExecuteContractFixture()}}, - } + for _, m := range mutators { m(&fixture) } From e7b0a53e5dd7dc94bb40b946a6e75b0818dcd69d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 08:10:19 +0000 Subject: [PATCH 040/294] Bump actions/checkout from 3.1.0 to 3.2.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.1.0...v3.2.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analizer.yml | 2 +- .github/workflows/proto-buf-publisher.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analizer.yml b/.github/workflows/codeql-analizer.yml index 67b8a1a44c..1dd29ad4b7 100644 --- a/.github/workflows/codeql-analizer.yml +++ b/.github/workflows/codeql-analizer.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v3.2.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 88b2f465e9..436faca243 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -16,7 +16,7 @@ jobs: push: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.1.0 + - uses: actions/checkout@v3.2.0 - uses: bufbuild/buf-setup-action@v1.9.0 # lint checks From b8c5724463edd243f3a94d2b0c004dea87d05f95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 09:42:42 +0100 Subject: [PATCH 041/294] Bump bufbuild/buf-setup-action from 1.9.0 to 1.10.0 (#1124) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.9.0 to 1.10.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 436faca243..27eeb52f35 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.2.0 - - uses: bufbuild/buf-setup-action@v1.9.0 + - uses: bufbuild/buf-setup-action@v1.10.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From cb6b85499705e4324890a0b83a022f8b42d82d15 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sun, 18 Dec 2022 02:28:36 -0800 Subject: [PATCH 042/294] add proposal annotations --- proto/cosmwasm/wasm/v1/proposal.proto | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/proto/cosmwasm/wasm/v1/proposal.proto b/proto/cosmwasm/wasm/v1/proposal.proto index 1b8fffaa00..013b4daf5a 100644 --- a/proto/cosmwasm/wasm/v1/proposal.proto +++ b/proto/cosmwasm/wasm/v1/proposal.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package cosmwasm.wasm.v1; import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; import "cosmos/base/v1beta1/coin.proto"; import "cosmwasm/wasm/v1/types.proto"; @@ -12,6 +13,8 @@ option (gogoproto.equal_all) = true; // StoreCodeProposal gov proposal content type to submit WASM code to the system message StoreCodeProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -39,6 +42,8 @@ message StoreCodeProposal { // InstantiateContractProposal gov proposal content type to instantiate a // contract. message InstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -63,6 +68,8 @@ message InstantiateContractProposal { // InstantiateContract2Proposal gov proposal content type to instantiate // contract 2 message InstantiateContract2Proposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -91,6 +98,8 @@ message InstantiateContract2Proposal { // MigrateContractProposal gov proposal content type to migrate a contract. message MigrateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -107,6 +116,8 @@ message MigrateContractProposal { // SudoContractProposal gov proposal content type to call sudo on a contract. message SudoContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -120,6 +131,8 @@ message SudoContractProposal { // ExecuteContractProposal gov proposal content type to call execute on a // contract. message ExecuteContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -139,6 +152,8 @@ message ExecuteContractProposal { // UpdateAdminProposal gov proposal content type to set an admin for a contract. message UpdateAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -152,6 +167,8 @@ message UpdateAdminProposal { // ClearAdminProposal gov proposal content type to clear the admin of a // contract. message ClearAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text @@ -163,6 +180,8 @@ message ClearAdminProposal { // PinCodesProposal gov proposal content type to pin a set of code ids in the // wasmvm cache. message PinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; // Description is a human readable text @@ -177,6 +196,8 @@ message PinCodesProposal { // UnpinCodesProposal gov proposal content type to unpin a set of code ids in // the wasmvm cache. message UnpinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; // Description is a human readable text @@ -200,6 +221,8 @@ message AccessConfigUpdate { // UpdateInstantiateConfigProposal gov proposal content type to update // instantiate config to a set of code ids. message UpdateInstantiateConfigProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; // Description is a human readable text @@ -213,6 +236,8 @@ message UpdateInstantiateConfigProposal { // StoreAndInstantiateContractProposal gov proposal content type to store // and instantiate the contract. message StoreAndInstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // Title is a short summary string title = 1; // Description is a human readable text From 204db586fd37a72e848c790d6393e331727dacec Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 19 Dec 2022 10:33:57 +0100 Subject: [PATCH 043/294] Update changelog for v0.30.0 --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd4922a8a8..121a566e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ ## [v0.30.0](https://github.com/CosmWasm/wasmd/tree/v0.30.0) (2022-12-02) [Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.29.2...v0.30.0) -* Provide source, builder and codehash information in store code proposal message[\#1072](https://github.com/CosmWasm/wasmd/pull/1072) +- Provide source, builder and codehash information in store code proposal message[\#1072](https://github.com/CosmWasm/wasmd/pull/1072) +- Add new CLI query/ endpoint to get contracts by creator address [\#998](https://github.com/CosmWasm/wasmd/pull/998) - Upgrade to Go v1.19 [\#1044](https://github.com/CosmWasm/wasmd/pull/1044) - Upgrade to Cosmos-sdk to v0.45.11 [/#1096](https://github.com/CosmWasm/wasmd/pull/1096/) - Upgrade to IBC v4.2.0 with interchain-accounts v0.2.4 [\#1088](https://github.com/CosmWasm/wasmd/pull/1088) @@ -20,9 +21,10 @@ - IBC fee middleware is setup in `app.go`. Please note that it can be enabled with new channels only. A nice read is this [article](https://medium.com/the-interchain-foundation/ibc-relaying-as-a-service-the-in-protocol-incentivization-story-2c008861a957). - Authz for wasm contracts can be granted via `wasmd tx wasm grant` and executed via `wasmd tx authz exec` command - Go v1.19 required to prevent a mixed chain setup with older versions. Just to be on the safe side. -- Store code proposal types have new metadata fields added that can help to build client side tooling to verify the wasm contract in the proposal +- Store code proposal types have new metadata fields added that can help to build client side tooling to verify the wasm contract in the proposal ### Migration notes: +- The wasmd module version was bumped and a [state migration](https://github.com/CosmWasm/wasmd/pull/1021/files#diff-4357c2137e24f583b8f852cc210320cb71af18e2fdfb8c21b55d8667cfe54690R20) registered. - See ibc-go [migration notes](https://github.com/cosmos/ibc-go/blob/v4.2.0/docs/migrations) - See interchain-accounts [`MsgRegisterAccount.Version` field](https://github.com/cosmos/interchain-accounts-demo/compare/v0.1.0...v0.2.4#diff-ac8bca25810de6d3eef95f74fc9acf2223f3687822e6227b584e0d3b40db6566). Full diff [v0.1.0 to v0.2.4](https://github.com/cosmos/interchain-accounts-demo/compare/v0.1.0...v0.2.4) From 14c2daa66711be3b8eba43a22751426468300217 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Tue, 20 Dec 2022 12:03:52 +0100 Subject: [PATCH 044/294] Add UpdateInstantiateConfig command (#1121) * Add UpdateInstantiateConfig msg * Add implementation * Add cli command * Fix field description * Fix review comments and add unit tests --- docs/proto/proto-docs.md | 32 +- proto/cosmwasm/wasm/v1/tx.proto | 18 +- x/wasm/client/cli/new_tx.go | 42 +++ x/wasm/handler.go | 2 + x/wasm/keeper/msg_server.go | 13 + x/wasm/types/codec.go | 2 + x/wasm/types/tx.go | 40 +++ x/wasm/types/tx.pb.go | 532 ++++++++++++++++++++++++++++---- x/wasm/types/tx_test.go | 62 ++++ 9 files changed, 686 insertions(+), 57 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index 54d3c82f17..bed0967db1 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -95,6 +95,8 @@ - [MsgStoreCodeResponse](#cosmwasm.wasm.v1.MsgStoreCodeResponse) - [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) - [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) + - [MsgUpdateInstantiateConfig](#cosmwasm.wasm.v1.MsgUpdateInstantiateConfig) + - [MsgUpdateInstantiateConfigResponse](#cosmwasm.wasm.v1.MsgUpdateInstantiateConfigResponse) - [Msg](#cosmwasm.wasm.v1.Msg) @@ -1287,7 +1289,7 @@ MsgClearAdmin removes any admin stored for a smart contract | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `sender` | [string](#string) | | Sender is the actor that signed the messages | | `contract` | [string](#string) | | Contract is the address of the smart contract | @@ -1506,6 +1508,33 @@ MsgUpdateAdminResponse returns empty data + + + +### MsgUpdateInstantiateConfig +MsgUpdateInstantiateConfig updates instantiate config for a smart contract + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `sender` | [string](#string) | | Sender is the that actor that signed the messages | +| `code_id` | [uint64](#uint64) | | CodeID references the stored WASM code | +| `new_instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | NewInstantiatePermission is the new access control | + + + + + + + + +### MsgUpdateInstantiateConfigResponse +MsgUpdateInstantiateConfigResponse returns empty data + + + + + @@ -1527,6 +1556,7 @@ Msg defines the wasm Msg service. | `MigrateContract` | [MsgMigrateContract](#cosmwasm.wasm.v1.MsgMigrateContract) | [MsgMigrateContractResponse](#cosmwasm.wasm.v1.MsgMigrateContractResponse) | Migrate runs a code upgrade/ downgrade for a smart contract | | | `UpdateAdmin` | [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) | [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) | UpdateAdmin sets a new admin for a smart contract | | | `ClearAdmin` | [MsgClearAdmin](#cosmwasm.wasm.v1.MsgClearAdmin) | [MsgClearAdminResponse](#cosmwasm.wasm.v1.MsgClearAdminResponse) | ClearAdmin removes any admin stored for a smart contract | | +| `UpdateInstantiateConfig` | [MsgUpdateInstantiateConfig](#cosmwasm.wasm.v1.MsgUpdateInstantiateConfig) | [MsgUpdateInstantiateConfigResponse](#cosmwasm.wasm.v1.MsgUpdateInstantiateConfigResponse) | UpdateInstantiateConfig updates instantiate config for a smart contract | | diff --git a/proto/cosmwasm/wasm/v1/tx.proto b/proto/cosmwasm/wasm/v1/tx.proto index 04acc8ef7f..51078e2541 100644 --- a/proto/cosmwasm/wasm/v1/tx.proto +++ b/proto/cosmwasm/wasm/v1/tx.proto @@ -28,6 +28,9 @@ service Msg { rpc UpdateAdmin(MsgUpdateAdmin) returns (MsgUpdateAdminResponse); // ClearAdmin removes any admin stored for a smart contract rpc ClearAdmin(MsgClearAdmin) returns (MsgClearAdminResponse); + // UpdateInstantiateConfig updates instantiate config for a smart contract + rpc UpdateInstantiateConfig(MsgUpdateInstantiateConfig) + returns (MsgUpdateInstantiateConfigResponse); } // MsgStoreCode submit Wasm code to the system @@ -166,7 +169,7 @@ message MsgUpdateAdminResponse {} // MsgClearAdmin removes any admin stored for a smart contract message MsgClearAdmin { - // Sender is the that actor that signed the messages + // Sender is the actor that signed the messages string sender = 1; // Contract is the address of the smart contract string contract = 3; @@ -174,3 +177,16 @@ message MsgClearAdmin { // MsgClearAdminResponse returns empty data message MsgClearAdminResponse {} + +// MsgUpdateInstantiateConfig updates instantiate config for a smart contract +message MsgUpdateInstantiateConfig { + // Sender is the that actor that signed the messages + string sender = 1; + // CodeID references the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // NewInstantiatePermission is the new access control + AccessConfig new_instantiate_permission = 3; +} + +// MsgUpdateInstantiateConfigResponse returns empty data +message MsgUpdateInstantiateConfigResponse {} \ No newline at end of file diff --git a/x/wasm/client/cli/new_tx.go b/x/wasm/client/cli/new_tx.go index 2be19350ac..21731768ea 100644 --- a/x/wasm/client/cli/new_tx.go +++ b/x/wasm/client/cli/new_tx.go @@ -122,3 +122,45 @@ func ClearContractAdminCmd() *cobra.Command { flags.AddTxFlagsToCmd(cmd) return cmd } + +// UpdateInstantiateConfigCmd updates instantiate config for a smart contract. +func UpdateInstantiateConfigCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-instantiate-config [code_id_int64]", + Short: "Update instantiate config for a codeID", + Aliases: []string{"update-instantiate-config"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + codeID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + perm, err := parseAccessConfigFlags(cmd.Flags()) + if err != nil { + return err + } + + msg := types.MsgUpdateInstantiateConfig{ + Sender: string(clientCtx.GetFromAddress()), + CodeID: codeID, + NewInstantiatePermission: perm, + } + if err = msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + SilenceUsage: true, + } + + cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional") + cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional") + cmd.Flags().String(flagInstantiateByAddress, "", "Deprecated: Only this address can instantiate a contract from the code, optional") + cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/wasm/handler.go b/x/wasm/handler.go index c7f27b754b..b350e7d37c 100644 --- a/x/wasm/handler.go +++ b/x/wasm/handler.go @@ -39,6 +39,8 @@ func NewHandler(k types.ContractOpsKeeper) sdk.Handler { res, err = msgServer.UpdateAdmin(sdk.WrapSDKContext(ctx), msg) case *MsgClearAdmin: res, err = msgServer.ClearAdmin(sdk.WrapSDKContext(ctx), msg) + case *types.MsgUpdateInstantiateConfig: + res, err = msgServer.UpdateInstantiateConfig(sdk.WrapSDKContext(ctx), msg) default: errMsg := fmt.Sprintf("unrecognized wasm message type: %T", msg) return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) diff --git a/x/wasm/keeper/msg_server.go b/x/wasm/keeper/msg_server.go index c91ff2124d..e7d35c3398 100644 --- a/x/wasm/keeper/msg_server.go +++ b/x/wasm/keeper/msg_server.go @@ -236,3 +236,16 @@ func (m msgServer) ClearAdmin(goCtx context.Context, msg *types.MsgClearAdmin) ( return &types.MsgClearAdminResponse{}, nil } + +func (m msgServer) UpdateInstantiateConfig(goCtx context.Context, msg *types.MsgUpdateInstantiateConfig) (*types.MsgUpdateInstantiateConfigResponse, error) { + if err := msg.ValidateBasic(); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := m.keeper.SetAccessConfig(ctx, msg.CodeID, sdk.AccAddress(msg.Sender), *msg.NewInstantiatePermission); err != nil { + return nil, err + } + + return &types.MsgUpdateInstantiateConfigResponse{}, nil +} diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index d1c2b9eb92..7d8ebcbe46 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -19,6 +19,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&MsgMigrateContract{}, "wasm/MsgMigrateContract", nil) cdc.RegisterConcrete(&MsgUpdateAdmin{}, "wasm/MsgUpdateAdmin", nil) cdc.RegisterConcrete(&MsgClearAdmin{}, "wasm/MsgClearAdmin", nil) + cdc.RegisterConcrete(&MsgUpdateInstantiateConfig{}, "wasm/MsgUpdateInstantiateConfig", nil) cdc.RegisterConcrete(&PinCodesProposal{}, "wasm/PinCodesProposal", nil) cdc.RegisterConcrete(&UnpinCodesProposal{}, "wasm/UnpinCodesProposal", nil) @@ -61,6 +62,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgClearAdmin{}, &MsgIBCCloseChannel{}, &MsgIBCSend{}, + &MsgUpdateInstantiateConfig{}, ) registry.RegisterImplementations( (*govtypes.Content)(nil), diff --git a/x/wasm/types/tx.go b/x/wasm/types/tx.go index 6742224df7..5739721ff8 100644 --- a/x/wasm/types/tx.go +++ b/x/wasm/types/tx.go @@ -395,3 +395,43 @@ func (msg MsgInstantiateContract2) GetSigners() []sdk.AccAddress { } return []sdk.AccAddress{senderAddr} } + +func (msg MsgUpdateInstantiateConfig) Route() string { + return RouterKey +} + +func (msg MsgUpdateInstantiateConfig) Type() string { + return "update-instantiate-config" +} + +func (msg MsgUpdateInstantiateConfig) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return sdkerrors.Wrap(err, "sender") + } + + if msg.CodeID == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code id is required") + } + + if msg.NewInstantiatePermission == nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "instantiate permission is required") + } + + if err := msg.NewInstantiatePermission.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "instantiate permission") + } + + return nil +} + +func (msg MsgUpdateInstantiateConfig) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg)) +} + +func (msg MsgUpdateInstantiateConfig) GetSigners() []sdk.AccAddress { + senderAddr, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { // should never happen as valid basic rejects invalid addresses + panic(err.Error()) + } + return []sdk.AccAddress{senderAddr} +} diff --git a/x/wasm/types/tx.pb.go b/x/wasm/types/tx.pb.go index 4aa9676b37..ed9d4add68 100644 --- a/x/wasm/types/tx.pb.go +++ b/x/wasm/types/tx.pb.go @@ -615,7 +615,7 @@ var xxx_messageInfo_MsgUpdateAdminResponse proto.InternalMessageInfo // MsgClearAdmin removes any admin stored for a smart contract type MsgClearAdmin struct { - // Sender is the that actor that signed the messages + // Sender is the actor that signed the messages Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` // Contract is the address of the smart contract Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` @@ -700,6 +700,95 @@ func (m *MsgClearAdminResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgClearAdminResponse proto.InternalMessageInfo +// MsgUpdateInstantiateConfig updates instantiate config for a smart contract +type MsgUpdateInstantiateConfig struct { + // Sender is the that actor that signed the messages + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // CodeID references the stored WASM code + CodeID uint64 `protobuf:"varint,2,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // NewInstantiatePermission is the new access control + NewInstantiatePermission *AccessConfig `protobuf:"bytes,3,opt,name=new_instantiate_permission,json=newInstantiatePermission,proto3" json:"new_instantiate_permission,omitempty"` +} + +func (m *MsgUpdateInstantiateConfig) Reset() { *m = MsgUpdateInstantiateConfig{} } +func (m *MsgUpdateInstantiateConfig) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateInstantiateConfig) ProtoMessage() {} +func (*MsgUpdateInstantiateConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_4f74d82755520264, []int{14} +} + +func (m *MsgUpdateInstantiateConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MsgUpdateInstantiateConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateInstantiateConfig.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MsgUpdateInstantiateConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateInstantiateConfig.Merge(m, src) +} + +func (m *MsgUpdateInstantiateConfig) XXX_Size() int { + return m.Size() +} + +func (m *MsgUpdateInstantiateConfig) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateInstantiateConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateInstantiateConfig proto.InternalMessageInfo + +// MsgUpdateInstantiateConfigResponse returns empty data +type MsgUpdateInstantiateConfigResponse struct{} + +func (m *MsgUpdateInstantiateConfigResponse) Reset() { *m = MsgUpdateInstantiateConfigResponse{} } +func (m *MsgUpdateInstantiateConfigResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateInstantiateConfigResponse) ProtoMessage() {} +func (*MsgUpdateInstantiateConfigResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4f74d82755520264, []int{15} +} + +func (m *MsgUpdateInstantiateConfigResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *MsgUpdateInstantiateConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateInstantiateConfigResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *MsgUpdateInstantiateConfigResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateInstantiateConfigResponse.Merge(m, src) +} + +func (m *MsgUpdateInstantiateConfigResponse) XXX_Size() int { + return m.Size() +} + +func (m *MsgUpdateInstantiateConfigResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateInstantiateConfigResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateInstantiateConfigResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgStoreCode)(nil), "cosmwasm.wasm.v1.MsgStoreCode") proto.RegisterType((*MsgStoreCodeResponse)(nil), "cosmwasm.wasm.v1.MsgStoreCodeResponse") @@ -715,65 +804,71 @@ func init() { proto.RegisterType((*MsgUpdateAdminResponse)(nil), "cosmwasm.wasm.v1.MsgUpdateAdminResponse") proto.RegisterType((*MsgClearAdmin)(nil), "cosmwasm.wasm.v1.MsgClearAdmin") proto.RegisterType((*MsgClearAdminResponse)(nil), "cosmwasm.wasm.v1.MsgClearAdminResponse") + proto.RegisterType((*MsgUpdateInstantiateConfig)(nil), "cosmwasm.wasm.v1.MsgUpdateInstantiateConfig") + proto.RegisterType((*MsgUpdateInstantiateConfigResponse)(nil), "cosmwasm.wasm.v1.MsgUpdateInstantiateConfigResponse") } func init() { proto.RegisterFile("cosmwasm/wasm/v1/tx.proto", fileDescriptor_4f74d82755520264) } var fileDescriptor_4f74d82755520264 = []byte{ - // 840 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0x4d, 0x6f, 0xe3, 0x44, - 0x18, 0x8e, 0x1b, 0xe7, 0xeb, 0x6d, 0x58, 0x22, 0x93, 0x4d, 0xbd, 0x06, 0x39, 0x91, 0x41, 0x8b, - 0x91, 0xc0, 0x6e, 0x82, 0xc4, 0xbd, 0xc9, 0x72, 0xe8, 0x4a, 0x06, 0xe4, 0x6a, 0xa9, 0xe0, 0x12, - 0x4d, 0xec, 0x89, 0xd7, 0xda, 0xd8, 0x13, 0x3c, 0x93, 0x26, 0xfd, 0x13, 0x88, 0x1b, 0xff, 0x81, - 0xdf, 0xc0, 0x05, 0x89, 0x43, 0x8f, 0x7b, 0x41, 0xe2, 0x14, 0x20, 0xfd, 0x17, 0x9c, 0x90, 0x3f, - 0xeb, 0xcd, 0x3a, 0x69, 0x00, 0x71, 0xe2, 0x92, 0xcc, 0xeb, 0x79, 0xde, 0xaf, 0x67, 0x9e, 0x77, - 0x6c, 0x78, 0x64, 0x11, 0xea, 0x2d, 0x11, 0xf5, 0xf4, 0xe8, 0xe7, 0xaa, 0xaf, 0xb3, 0x95, 0x36, - 0x0f, 0x08, 0x23, 0x42, 0x2b, 0xdd, 0xd2, 0xa2, 0x9f, 0xab, 0xbe, 0x24, 0x87, 0x4f, 0x08, 0xd5, - 0x27, 0x88, 0x62, 0xfd, 0xaa, 0x3f, 0xc1, 0x0c, 0xf5, 0x75, 0x8b, 0xb8, 0x7e, 0xec, 0x21, 0xb5, - 0x1d, 0xe2, 0x90, 0x68, 0xa9, 0x87, 0xab, 0xe4, 0xe9, 0x3b, 0xaf, 0xa7, 0xb8, 0x9e, 0x63, 0x1a, - 0xef, 0x2a, 0x3f, 0x71, 0xd0, 0x34, 0xa8, 0x73, 0xc1, 0x48, 0x80, 0x47, 0xc4, 0xc6, 0x42, 0x07, - 0xaa, 0x14, 0xfb, 0x36, 0x0e, 0x44, 0xae, 0xc7, 0xa9, 0x0d, 0x33, 0xb1, 0x84, 0x4f, 0xe0, 0x41, - 0xe8, 0x3f, 0x9e, 0x5c, 0x33, 0x3c, 0xb6, 0x88, 0x8d, 0xc5, 0xa3, 0x1e, 0xa7, 0x36, 0x87, 0xad, - 0xcd, 0xba, 0xdb, 0xbc, 0x3c, 0xbb, 0x30, 0x86, 0xd7, 0x2c, 0x8a, 0x60, 0x36, 0x43, 0x5c, 0x6a, - 0x09, 0xcf, 0xa0, 0xe3, 0xfa, 0x94, 0x21, 0x9f, 0xb9, 0x88, 0xe1, 0xf1, 0x1c, 0x07, 0x9e, 0x4b, - 0xa9, 0x4b, 0x7c, 0xb1, 0xd2, 0xe3, 0xd4, 0xe3, 0x81, 0xac, 0x6d, 0xf7, 0xa9, 0x9d, 0x59, 0x16, - 0xa6, 0x74, 0x44, 0xfc, 0xa9, 0xeb, 0x98, 0x0f, 0x73, 0xde, 0x5f, 0x64, 0xce, 0x4f, 0xf9, 0x7a, - 0xb9, 0xc5, 0x3f, 0xe5, 0xeb, 0x7c, 0xab, 0xa2, 0x5c, 0x42, 0x3b, 0xdf, 0x82, 0x89, 0xe9, 0x9c, - 0xf8, 0x14, 0x0b, 0xef, 0x42, 0x2d, 0x2c, 0x74, 0xec, 0xda, 0x51, 0x2f, 0xfc, 0x10, 0x36, 0xeb, - 0x6e, 0x35, 0x84, 0x9c, 0x3f, 0x31, 0xab, 0xe1, 0xd6, 0xb9, 0x2d, 0x48, 0x50, 0xb7, 0x9e, 0x63, - 0xeb, 0x05, 0x5d, 0x78, 0x71, 0x47, 0x66, 0x66, 0x2b, 0xdf, 0x1e, 0x41, 0xc7, 0xa0, 0xce, 0xf9, - 0x5d, 0x05, 0x23, 0xe2, 0xb3, 0x00, 0x59, 0x6c, 0x27, 0x4d, 0x6d, 0xa8, 0x20, 0xdb, 0x73, 0xfd, - 0x28, 0x56, 0xc3, 0x8c, 0x8d, 0x7c, 0x25, 0xe5, 0x9d, 0x95, 0xb4, 0xa1, 0x32, 0x43, 0x13, 0x3c, - 0x13, 0xf9, 0xd8, 0x35, 0x32, 0x04, 0x15, 0xca, 0x1e, 0x75, 0x22, 0xb2, 0x9a, 0xc3, 0xce, 0x9f, - 0xeb, 0xae, 0x60, 0xa2, 0x65, 0x5a, 0x86, 0x81, 0x29, 0x45, 0x0e, 0x36, 0x43, 0x88, 0x80, 0xa0, - 0x32, 0x5d, 0xf8, 0x36, 0x15, 0xab, 0xbd, 0xb2, 0x7a, 0x3c, 0x78, 0xa4, 0xc5, 0x72, 0xd1, 0x42, - 0xb9, 0x68, 0x89, 0x5c, 0xb4, 0x11, 0x71, 0xfd, 0xe1, 0xe9, 0xcd, 0xba, 0x5b, 0xfa, 0xe1, 0xb7, - 0xae, 0xea, 0xb8, 0xec, 0xf9, 0x62, 0xa2, 0x59, 0xc4, 0xd3, 0x13, 0x6d, 0xc5, 0x7f, 0x1f, 0x51, - 0xfb, 0x45, 0x22, 0x93, 0xd0, 0x81, 0x9a, 0x71, 0x64, 0xe5, 0xc7, 0x23, 0x38, 0x29, 0x26, 0x64, - 0xf0, 0xff, 0x64, 0x44, 0x10, 0x80, 0xa7, 0x68, 0xc6, 0xc4, 0x5a, 0x24, 0x9d, 0x68, 0x2d, 0x9c, - 0x40, 0x6d, 0xea, 0xae, 0xc6, 0x61, 0x91, 0xf5, 0x1e, 0xa7, 0xd6, 0xcd, 0xea, 0xd4, 0x5d, 0x19, - 0xd4, 0x51, 0x3e, 0x03, 0xb9, 0x98, 0xbd, 0x4c, 0xb2, 0x22, 0xd4, 0x90, 0x6d, 0x07, 0x98, 0xd2, - 0x84, 0xc5, 0xd4, 0x0c, 0x13, 0xd9, 0x88, 0xa1, 0x44, 0xa3, 0xd1, 0x5a, 0xf9, 0x1c, 0xba, 0x3b, - 0x4e, 0xe3, 0x1f, 0x06, 0xfc, 0x85, 0x03, 0xc1, 0xa0, 0xce, 0xa7, 0x2b, 0x6c, 0x2d, 0x0e, 0x10, - 0x7b, 0x38, 0x3b, 0x09, 0x26, 0x39, 0xdd, 0xcc, 0x4e, 0x4f, 0xa9, 0xfc, 0x37, 0x4e, 0xa9, 0xf2, - 0x9f, 0xe9, 0xf6, 0x14, 0xa4, 0xd7, 0xdb, 0xca, 0x38, 0x4a, 0x99, 0xe0, 0x72, 0x4c, 0x7c, 0x1f, - 0x33, 0x61, 0xb8, 0x4e, 0x80, 0xfe, 0x25, 0x13, 0x07, 0x49, 0x3d, 0xa1, 0x8b, 0xbf, 0x97, 0xae, - 0xa4, 0x97, 0xad, 0xc2, 0xf6, 0xf6, 0x82, 0xe0, 0x81, 0x41, 0x9d, 0x67, 0x73, 0x1b, 0x31, 0x7c, - 0x16, 0x4d, 0xdf, 0xae, 0x36, 0xde, 0x86, 0x86, 0x8f, 0x97, 0xe3, 0xfc, 0xbc, 0xd6, 0x7d, 0xbc, - 0x8c, 0x9d, 0xf2, 0x3d, 0x96, 0x5f, 0xed, 0x51, 0x11, 0xa3, 0x8b, 0x32, 0x97, 0x22, 0x2d, 0x48, - 0x19, 0xc1, 0x1b, 0x06, 0x75, 0x46, 0x33, 0x8c, 0x82, 0xfd, 0xb9, 0xf7, 0x85, 0x3f, 0x81, 0x87, - 0xaf, 0x04, 0x49, 0xa3, 0x0f, 0x7e, 0xae, 0x40, 0xd9, 0xa0, 0x8e, 0x70, 0x01, 0x8d, 0xbb, 0x57, - 0x58, 0xc1, 0x2b, 0x25, 0xff, 0x7e, 0x90, 0x1e, 0xef, 0xdf, 0xcf, 0xb8, 0xfc, 0x06, 0xde, 0x2a, - 0xba, 0xfa, 0xd5, 0x42, 0xf7, 0x02, 0xa4, 0x74, 0x7a, 0x28, 0x32, 0x4b, 0xc9, 0xa0, 0x5d, 0x78, - 0xb9, 0x7e, 0x70, 0x68, 0xa4, 0x81, 0xd4, 0x3f, 0x18, 0x9a, 0x65, 0xc5, 0xf0, 0xe6, 0xf6, 0xc8, - 0xbf, 0x57, 0x18, 0x65, 0x0b, 0x25, 0x7d, 0x78, 0x08, 0x2a, 0x9f, 0x66, 0x7b, 0x9e, 0x8a, 0xd3, - 0x6c, 0xa1, 0x76, 0xa4, 0xd9, 0x35, 0x02, 0x5f, 0xc1, 0x71, 0x5e, 0xeb, 0xbd, 0x42, 0xe7, 0x1c, - 0x42, 0x52, 0xef, 0x43, 0x64, 0xa1, 0xbf, 0x04, 0xc8, 0x29, 0xb9, 0x5b, 0xe8, 0x77, 0x07, 0x90, - 0xde, 0xbf, 0x07, 0x90, 0xc6, 0x1d, 0x3e, 0xb9, 0xf9, 0x43, 0x2e, 0xdd, 0x6c, 0x64, 0xee, 0xe5, - 0x46, 0xe6, 0x7e, 0xdf, 0xc8, 0xdc, 0x77, 0xb7, 0x72, 0xe9, 0xe5, 0xad, 0x5c, 0xfa, 0xf5, 0x56, - 0x2e, 0x7d, 0xfd, 0x38, 0x77, 0xdd, 0x8d, 0x08, 0xf5, 0x2e, 0xd3, 0x8f, 0x39, 0x5b, 0x5f, 0xc5, - 0x1f, 0x75, 0xd1, 0x95, 0x37, 0xa9, 0x46, 0x9f, 0x74, 0x1f, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, - 0x1a, 0x2c, 0xa2, 0xcd, 0x55, 0x0a, 0x00, 0x00, + // 908 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x8f, 0x9b, 0x3f, 0x4d, 0x5f, 0xc3, 0x52, 0x99, 0x6c, 0xeb, 0x35, 0xc8, 0x89, 0xcc, 0x6a, + 0x31, 0xd2, 0x62, 0x37, 0x01, 0x71, 0x6f, 0xb2, 0x1c, 0xba, 0x92, 0x01, 0xb9, 0x5a, 0x2a, 0x10, + 0x52, 0x34, 0xb1, 0x27, 0x5e, 0x6b, 0x6b, 0x4f, 0xf0, 0x4c, 0x9b, 0xf4, 0xc0, 0x57, 0x40, 0xdc, + 0xf8, 0x0e, 0x7c, 0x01, 0x2e, 0x5c, 0x10, 0x97, 0x1e, 0xf7, 0x82, 0xc4, 0xa9, 0x40, 0xfa, 0x2d, + 0x38, 0x21, 0x8f, 0xff, 0xd4, 0x4d, 0xed, 0x34, 0x0b, 0xe2, 0xb4, 0x97, 0x64, 0xc6, 0xf3, 0x7b, + 0xef, 0xf7, 0xde, 0x6f, 0xde, 0xf3, 0x33, 0x3c, 0xb0, 0x09, 0xf5, 0x67, 0x88, 0xfa, 0x06, 0xff, + 0x39, 0xeb, 0x19, 0x6c, 0xae, 0x4f, 0x43, 0xc2, 0x88, 0xb8, 0x93, 0x1e, 0xe9, 0xfc, 0xe7, 0xac, + 0x27, 0x2b, 0xd1, 0x13, 0x42, 0x8d, 0x31, 0xa2, 0xd8, 0x38, 0xeb, 0x8d, 0x31, 0x43, 0x3d, 0xc3, + 0x26, 0x5e, 0x10, 0x5b, 0xc8, 0x6d, 0x97, 0xb8, 0x84, 0x2f, 0x8d, 0x68, 0x95, 0x3c, 0x7d, 0xe7, + 0x36, 0xc5, 0xf9, 0x14, 0xd3, 0xf8, 0x54, 0xfd, 0x45, 0x80, 0x96, 0x49, 0xdd, 0x23, 0x46, 0x42, + 0x3c, 0x24, 0x0e, 0x16, 0x77, 0xa1, 0x41, 0x71, 0xe0, 0xe0, 0x50, 0x12, 0xba, 0x82, 0xb6, 0x65, + 0x25, 0x3b, 0xf1, 0x63, 0xb8, 0x17, 0xd9, 0x8f, 0xc6, 0xe7, 0x0c, 0x8f, 0x6c, 0xe2, 0x60, 0x69, + 0xa3, 0x2b, 0x68, 0xad, 0xc1, 0xce, 0xe2, 0xb2, 0xd3, 0x3a, 0x3e, 0x38, 0x32, 0x07, 0xe7, 0x8c, + 0x7b, 0xb0, 0x5a, 0x11, 0x2e, 0xdd, 0x89, 0xcf, 0x60, 0xd7, 0x0b, 0x28, 0x43, 0x01, 0xf3, 0x10, + 0xc3, 0xa3, 0x29, 0x0e, 0x7d, 0x8f, 0x52, 0x8f, 0x04, 0x52, 0xbd, 0x2b, 0x68, 0xdb, 0x7d, 0x45, + 0x5f, 0xce, 0x53, 0x3f, 0xb0, 0x6d, 0x4c, 0xe9, 0x90, 0x04, 0x13, 0xcf, 0xb5, 0xee, 0xe7, 0xac, + 0x3f, 0xcf, 0x8c, 0x9f, 0xd6, 0x9a, 0xd5, 0x9d, 0xda, 0xd3, 0x5a, 0xb3, 0xb6, 0x53, 0x57, 0x8f, + 0xa1, 0x9d, 0x4f, 0xc1, 0xc2, 0x74, 0x4a, 0x02, 0x8a, 0xc5, 0x77, 0x61, 0x33, 0x0a, 0x74, 0xe4, + 0x39, 0x3c, 0x97, 0xda, 0x00, 0x16, 0x97, 0x9d, 0x46, 0x04, 0x39, 0x7c, 0x62, 0x35, 0xa2, 0xa3, + 0x43, 0x47, 0x94, 0xa1, 0x69, 0x3f, 0xc7, 0xf6, 0x0b, 0x7a, 0xea, 0xc7, 0x19, 0x59, 0xd9, 0x5e, + 0xfd, 0x6e, 0x03, 0x76, 0x4d, 0xea, 0x1e, 0x5e, 0x47, 0x30, 0x24, 0x01, 0x0b, 0x91, 0xcd, 0x4a, + 0x65, 0x6a, 0x43, 0x1d, 0x39, 0xbe, 0x17, 0x70, 0x5f, 0x5b, 0x56, 0xbc, 0xc9, 0x47, 0x52, 0x2d, + 0x8d, 0xa4, 0x0d, 0xf5, 0x13, 0x34, 0xc6, 0x27, 0x52, 0x2d, 0x36, 0xe5, 0x1b, 0x51, 0x83, 0xaa, + 0x4f, 0x5d, 0x2e, 0x56, 0x6b, 0xb0, 0xfb, 0xf7, 0x65, 0x47, 0xb4, 0xd0, 0x2c, 0x0d, 0xc3, 0xc4, + 0x94, 0x22, 0x17, 0x5b, 0x11, 0x44, 0x44, 0x50, 0x9f, 0x9c, 0x06, 0x0e, 0x95, 0x1a, 0xdd, 0xaa, + 0xb6, 0xdd, 0x7f, 0xa0, 0xc7, 0xe5, 0xa2, 0x47, 0xe5, 0xa2, 0x27, 0xe5, 0xa2, 0x0f, 0x89, 0x17, + 0x0c, 0xf6, 0x2f, 0x2e, 0x3b, 0x95, 0x1f, 0xff, 0xe8, 0x68, 0xae, 0xc7, 0x9e, 0x9f, 0x8e, 0x75, + 0x9b, 0xf8, 0x46, 0x52, 0x5b, 0xf1, 0xdf, 0x07, 0xd4, 0x79, 0x91, 0x94, 0x49, 0x64, 0x40, 0xad, + 0xd8, 0xb3, 0xfa, 0xf3, 0x06, 0xec, 0x15, 0x0b, 0xd2, 0x7f, 0x3d, 0x15, 0x11, 0x45, 0xa8, 0x51, + 0x74, 0xc2, 0xa4, 0x4d, 0x5e, 0x3a, 0x7c, 0x2d, 0xee, 0xc1, 0xe6, 0xc4, 0x9b, 0x8f, 0xa2, 0x20, + 0x9b, 0x5d, 0x41, 0x6b, 0x5a, 0x8d, 0x89, 0x37, 0x37, 0xa9, 0xab, 0x7e, 0x0a, 0x4a, 0xb1, 0x7a, + 0x59, 0xc9, 0x4a, 0xb0, 0x89, 0x1c, 0x27, 0xc4, 0x94, 0x26, 0x2a, 0xa6, 0xdb, 0x88, 0xc8, 0x41, + 0x0c, 0x25, 0x35, 0xca, 0xd7, 0xea, 0x67, 0xd0, 0x29, 0xb9, 0x8d, 0x7f, 0xe9, 0xf0, 0x37, 0x01, + 0x44, 0x93, 0xba, 0x9f, 0xcc, 0xb1, 0x7d, 0xba, 0x46, 0xb1, 0x47, 0xbd, 0x93, 0x60, 0x92, 0xdb, + 0xcd, 0xf6, 0xe9, 0x2d, 0x55, 0x5f, 0xe1, 0x96, 0xea, 0xff, 0x5b, 0xdd, 0xee, 0x83, 0x7c, 0x3b, + 0xad, 0x4c, 0xa3, 0x54, 0x09, 0x21, 0xa7, 0xc4, 0x0f, 0xb1, 0x12, 0xa6, 0xe7, 0x86, 0xe8, 0x3f, + 0x2a, 0xb1, 0x56, 0xa9, 0x27, 0x72, 0xd5, 0xee, 0x94, 0x2b, 0xc9, 0x65, 0x29, 0xb0, 0x95, 0xb9, + 0x20, 0xb8, 0x67, 0x52, 0xf7, 0xd9, 0xd4, 0x41, 0x0c, 0x1f, 0xf0, 0xee, 0x2b, 0x4b, 0xe3, 0x6d, + 0xd8, 0x0a, 0xf0, 0x6c, 0x94, 0xef, 0xd7, 0x66, 0x80, 0x67, 0xb1, 0x51, 0x3e, 0xc7, 0xea, 0xcd, + 0x1c, 0x55, 0x89, 0xbf, 0x28, 0x73, 0x14, 0x69, 0x40, 0xea, 0x10, 0xde, 0x30, 0xa9, 0x3b, 0x3c, + 0xc1, 0x28, 0x5c, 0xcd, 0xbd, 0xca, 0xfd, 0x1e, 0xdc, 0xbf, 0xe1, 0x24, 0xf3, 0xfe, 0x93, 0xc0, + 0xd5, 0x88, 0x89, 0x6f, 0x36, 0xc2, 0xc4, 0x73, 0x4b, 0xb9, 0x72, 0x57, 0xb2, 0x51, 0x7a, 0x25, + 0x5f, 0x83, 0x1c, 0x89, 0x51, 0x32, 0xbd, 0xaa, 0x6b, 0x4d, 0x2f, 0x29, 0xc0, 0xb3, 0xc3, 0xa2, + 0x01, 0xa6, 0x3e, 0x04, 0xb5, 0x3c, 0xf0, 0x34, 0xbf, 0xfe, 0xaf, 0x0d, 0xa8, 0x9a, 0xd4, 0x15, + 0x8f, 0x60, 0xeb, 0x7a, 0x44, 0x17, 0x90, 0xe6, 0xe7, 0x9f, 0xfc, 0x68, 0xf5, 0x79, 0x56, 0x2b, + 0xdf, 0xc0, 0x5b, 0x45, 0xa3, 0x4d, 0x2b, 0x34, 0x2f, 0x40, 0xca, 0xfb, 0xeb, 0x22, 0x33, 0x4a, + 0x06, 0xed, 0xc2, 0xe1, 0xf1, 0xfe, 0xba, 0x9e, 0xfa, 0x72, 0x6f, 0x6d, 0x68, 0xc6, 0x8a, 0xe1, + 0xcd, 0xe5, 0x57, 0xda, 0xc3, 0x42, 0x2f, 0x4b, 0x28, 0xf9, 0xf1, 0x3a, 0xa8, 0x3c, 0xcd, 0xf2, + 0xfb, 0xa2, 0x98, 0x66, 0x09, 0x55, 0x42, 0x53, 0xd6, 0xe2, 0x5f, 0xc2, 0x76, 0xbe, 0x97, 0xbb, + 0x85, 0xc6, 0x39, 0x84, 0xac, 0xdd, 0x85, 0xc8, 0x5c, 0x7f, 0x01, 0x90, 0xeb, 0xd4, 0x4e, 0xa1, + 0xdd, 0x35, 0x40, 0x7e, 0xef, 0x0e, 0x40, 0xe6, 0xf7, 0x5b, 0xd8, 0x2b, 0x6b, 0xd1, 0xc7, 0x2b, + 0x82, 0xbb, 0x85, 0x96, 0x3f, 0x7a, 0x15, 0x74, 0x4a, 0x3f, 0x78, 0x72, 0xf1, 0x97, 0x52, 0xb9, + 0x58, 0x28, 0xc2, 0xcb, 0x85, 0x22, 0xfc, 0xb9, 0x50, 0x84, 0xef, 0xaf, 0x94, 0xca, 0xcb, 0x2b, + 0xa5, 0xf2, 0xfb, 0x95, 0x52, 0xf9, 0xea, 0x51, 0x6e, 0x9a, 0x0c, 0x09, 0xf5, 0x8f, 0xd3, 0x6f, + 0x65, 0xc7, 0x98, 0xc7, 0xdf, 0xcc, 0x7c, 0xa2, 0x8c, 0x1b, 0xfc, 0x8b, 0xf9, 0xc3, 0x7f, 0x02, + 0x00, 0x00, 0xff, 0xff, 0x2a, 0x98, 0x99, 0x8e, 0xb4, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -806,6 +901,8 @@ type MsgClient interface { UpdateAdmin(ctx context.Context, in *MsgUpdateAdmin, opts ...grpc.CallOption) (*MsgUpdateAdminResponse, error) // ClearAdmin removes any admin stored for a smart contract ClearAdmin(ctx context.Context, in *MsgClearAdmin, opts ...grpc.CallOption) (*MsgClearAdminResponse, error) + // UpdateInstantiateConfig updates instantiate config for a smart contract + UpdateInstantiateConfig(ctx context.Context, in *MsgUpdateInstantiateConfig, opts ...grpc.CallOption) (*MsgUpdateInstantiateConfigResponse, error) } type msgClient struct { @@ -879,6 +976,15 @@ func (c *msgClient) ClearAdmin(ctx context.Context, in *MsgClearAdmin, opts ...g return out, nil } +func (c *msgClient) UpdateInstantiateConfig(ctx context.Context, in *MsgUpdateInstantiateConfig, opts ...grpc.CallOption) (*MsgUpdateInstantiateConfigResponse, error) { + out := new(MsgUpdateInstantiateConfigResponse) + err := c.cc.Invoke(ctx, "/cosmwasm.wasm.v1.Msg/UpdateInstantiateConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // StoreCode to submit Wasm code to the system @@ -897,6 +1003,8 @@ type MsgServer interface { UpdateAdmin(context.Context, *MsgUpdateAdmin) (*MsgUpdateAdminResponse, error) // ClearAdmin removes any admin stored for a smart contract ClearAdmin(context.Context, *MsgClearAdmin) (*MsgClearAdminResponse, error) + // UpdateInstantiateConfig updates instantiate config for a smart contract + UpdateInstantiateConfig(context.Context, *MsgUpdateInstantiateConfig) (*MsgUpdateInstantiateConfigResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -930,6 +1038,10 @@ func (*UnimplementedMsgServer) ClearAdmin(ctx context.Context, req *MsgClearAdmi return nil, status.Errorf(codes.Unimplemented, "method ClearAdmin not implemented") } +func (*UnimplementedMsgServer) UpdateInstantiateConfig(ctx context.Context, req *MsgUpdateInstantiateConfig) (*MsgUpdateInstantiateConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateInstantiateConfig not implemented") +} + func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } @@ -1060,6 +1172,24 @@ func _Msg_ClearAdmin_Handler(srv interface{}, ctx context.Context, dec func(inte return interceptor(ctx, in, info, handler) } +func _Msg_UpdateInstantiateConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateInstantiateConfig) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateInstantiateConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmwasm.wasm.v1.Msg/UpdateInstantiateConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateInstantiateConfig(ctx, req.(*MsgUpdateInstantiateConfig)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmwasm.wasm.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -1092,6 +1222,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "ClearAdmin", Handler: _Msg_ClearAdmin_Handler, }, + { + MethodName: "UpdateInstantiateConfig", + Handler: _Msg_UpdateInstantiateConfig_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmwasm/wasm/v1/tx.proto", @@ -1706,6 +1840,76 @@ func (m *MsgClearAdminResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MsgUpdateInstantiateConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateInstantiateConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateInstantiateConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.NewInstantiatePermission != nil { + { + size, err := m.NewInstantiatePermission.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.CodeID != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x10 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateInstantiateConfigResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateInstantiateConfigResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateInstantiateConfigResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -1997,6 +2201,35 @@ func (m *MsgClearAdminResponse) Size() (n int) { return n } +func (m *MsgUpdateInstantiateConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.CodeID != 0 { + n += 1 + sovTx(uint64(m.CodeID)) + } + if m.NewInstantiatePermission != nil { + l = m.NewInstantiatePermission.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUpdateInstantiateConfigResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3903,6 +4136,195 @@ func (m *MsgClearAdminResponse) Unmarshal(dAtA []byte) error { return nil } +func (m *MsgUpdateInstantiateConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateInstantiateConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateInstantiateConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewInstantiatePermission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NewInstantiatePermission == nil { + m.NewInstantiatePermission = &AccessConfig{} + } + if err := m.NewInstantiatePermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *MsgUpdateInstantiateConfigResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateInstantiateConfigResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateInstantiateConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/wasm/types/tx_test.go b/x/wasm/types/tx_test.go index a3c29b4f8b..10c5c8b52c 100644 --- a/x/wasm/types/tx_test.go +++ b/x/wasm/types/tx_test.go @@ -679,3 +679,65 @@ func TestMsgJsonSignBytes(t *testing.T) { }) } } + +func TestMsgUpdateInstantiateConfig(t *testing.T) { + bad, err := sdk.AccAddressFromHex("012345") + require.NoError(t, err) + badAddress := bad.String() + // proper address size + goodAddress := sdk.AccAddress(make([]byte, 20)).String() + anotherGoodAddress := sdk.AccAddress(bytes.Repeat([]byte{0x2}, 20)).String() + + specs := map[string]struct { + src MsgUpdateInstantiateConfig + expErr bool + }{ + "all good": { + src: MsgUpdateInstantiateConfig{ + Sender: goodAddress, + CodeID: 1, + NewInstantiatePermission: &AccessConfig{Permission: AccessTypeOnlyAddress, Address: anotherGoodAddress}, + }, + }, + "bad sender": { + src: MsgUpdateInstantiateConfig{ + Sender: badAddress, + CodeID: 1, + NewInstantiatePermission: &AccessConfig{Permission: AccessTypeOnlyAddress, Address: anotherGoodAddress}, + }, + expErr: true, + }, + "invalid NewInstantiatePermission": { + src: MsgUpdateInstantiateConfig{ + Sender: goodAddress, + CodeID: 1, + NewInstantiatePermission: &AccessConfig{Permission: AccessTypeOnlyAddress, Address: badAddress}, + }, + expErr: true, + }, + "missing code id": { + src: MsgUpdateInstantiateConfig{ + Sender: goodAddress, + NewInstantiatePermission: &AccessConfig{Permission: AccessTypeOnlyAddress, Address: anotherGoodAddress}, + }, + expErr: true, + }, + "missing NewInstantiatePermission": { + src: MsgUpdateInstantiateConfig{ + Sender: goodAddress, + CodeID: 1, + }, + expErr: true, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + err := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} From 3ab7e767542778fe279a6f522d9c85c079359e24 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Wed, 21 Dec 2022 20:16:16 +0700 Subject: [PATCH 045/294] Update config.yml --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3003f55f72..1fc750c49c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,7 @@ jobs: lint: docker: - - image: golangci/golangci-lint:v1.46.2 + - image: golangci/golangci-lint:v1.50.1 steps: - checkout - run: From ca0f5453567684869f9859bc76e9a2c7b4057cc4 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Thu, 22 Dec 2022 12:50:52 +0100 Subject: [PATCH 046/294] Setup feature branch support (#1137) * Setup feature branch support * Require 1 approval --- .mergify.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .mergify.yml diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000000..531d83345c --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,14 @@ +queue_rules: + - name: default + conditions: + - "#approved-reviews-by>0" + +pull_request_rules: + - name: backport patches to sdk47 feature branch + conditions: + - base=main + - label=backport/sdk47-dev + actions: + backport: + branches: + - develop_sdk47 From 8160dc66d2e41376413b0108a90a10a47eca94be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 11:33:27 +0100 Subject: [PATCH 047/294] Bump bufbuild/buf-setup-action from 1.10.0 to 1.11.0 (#1138) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.10.0 to 1.11.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.10.0...v1.11.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 27eeb52f35..0c66e1e71e 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.2.0 - - uses: bufbuild/buf-setup-action@v1.10.0 + - uses: bufbuild/buf-setup-action@v1.11.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From 0888758d73ee38e0f89aaaa965448a183f93a505 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 14:36:25 +0100 Subject: [PATCH 048/294] Bump github.com/cosmos/cosmos-proto from 1.0.0-alpha8 to 1.0.0-beta.1 (#1116) Bumps [github.com/cosmos/cosmos-proto](https://github.com/cosmos/cosmos-proto) from 1.0.0-alpha8 to 1.0.0-beta.1. - [Release notes](https://github.com/cosmos/cosmos-proto/releases) - [Commits](https://github.com/cosmos/cosmos-proto/compare/v1.0.0-alpha8...v1.0.0-beta.1) --- updated-dependencies: - dependency-name: github.com/cosmos/cosmos-proto dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9140e8e461..d3d031c63f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/CosmWasm/wasmvm v1.1.1 - github.com/cosmos/cosmos-proto v1.0.0-alpha8 + github.com/cosmos/cosmos-proto v1.0.0-beta.1 github.com/cosmos/cosmos-sdk v0.45.11 github.com/cosmos/gogoproto v1.4.3 github.com/cosmos/iavl v0.19.4 diff --git a/go.sum b/go.sum index c7b2fad923..e5eb5a2b56 100644 --- a/go.sum +++ b/go.sum @@ -160,8 +160,8 @@ github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= -github.com/cosmos/cosmos-proto v1.0.0-alpha8 h1:d3pCRuMYYvGA5bM0ZbbjKn+AoQD4A7dyNG2wzwWalUw= -github.com/cosmos/cosmos-proto v1.0.0-alpha8/go.mod h1:6/p+Bc4O8JKeZqe0VqUGTX31eoYqemTT4C1hLCWsO7I= +github.com/cosmos/cosmos-proto v1.0.0-beta.1 h1:iDL5qh++NoXxG8hSy93FdYJut4XfgbShIocllGaXx/0= +github.com/cosmos/cosmos-proto v1.0.0-beta.1/go.mod h1:8k2GNZghi5sDRFw/scPL8gMSowT1vDA+5ouxL8GjaUE= github.com/cosmos/cosmos-sdk v0.45.11 h1:Pc44fFEkai0KXFND5Ys/2ZJkfVdstMIBzKBN8MY7Ll0= github.com/cosmos/cosmos-sdk v0.45.11/go.mod h1:45z8Q1Ah4iypFycu2Kl4kBPIsQKUiND8G2CUX+HTtPM= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= From b1b21d9f883564e90e81e8b02d5338793fd23f03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:11:53 +0000 Subject: [PATCH 049/294] Bump actions/checkout from 3.2.0 to 3.3.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analizer.yml | 2 +- .github/workflows/proto-buf-publisher.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analizer.yml b/.github/workflows/codeql-analizer.yml index 1dd29ad4b7..991d4e5f42 100644 --- a/.github/workflows/codeql-analizer.yml +++ b/.github/workflows/codeql-analizer.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.3.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index 0c66e1e71e..c4be716578 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -16,7 +16,7 @@ jobs: push: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.3.0 - uses: bufbuild/buf-setup-action@v1.11.0 # lint checks From 558147d054c88840a804a3ec4e0bba5b3cb5905a Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Tue, 10 Jan 2023 15:38:23 +0100 Subject: [PATCH 050/294] Address cli behaviour on tx and query errors (#1125) * Add SilenceUsage missing flags * Remove old script * Edit script comment --- contrib/local/00-genesis.sh | 28 ---------------------------- contrib/local/start_node.sh | 2 +- x/wasm/client/cli/query.go | 2 ++ 3 files changed, 3 insertions(+), 29 deletions(-) delete mode 100755 contrib/local/00-genesis.sh diff --git a/contrib/local/00-genesis.sh b/contrib/local/00-genesis.sh deleted file mode 100755 index 2d8834c700..0000000000 --- a/contrib/local/00-genesis.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -set -o errexit -o nounset -o pipefail - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -BASE_ACCOUNT=$(wasmd keys show validator -a) - -echo "-----------------------" -echo "## Genesis CosmWasm contract" -wasmd add-wasm-genesis-message store "$DIR/../../x/wasm/keeper/testdata/hackatom.wasm" --instantiate-everybody true --builder=foo/bar:latest --run-as validator - -echo "-----------------------" -echo "## Genesis CosmWasm instance" -INIT="{\"verifier\":\"$(wasmd keys show validator -a)\", \"beneficiary\":\"$(wasmd keys show fred -a)\"}" -wasmd add-wasm-genesis-message instantiate-contract 1 "$INIT" --run-as validator --label=foobar --amount=100ustake --admin "$BASE_ACCOUNT" - -echo "-----------------------" -echo "## Genesis CosmWasm execute" -FIRST_CONTRACT_ADDR=wasm18vd8fpwxzck93qlwghaj6arh4p7c5n89k7fvsl -MSG='{"release":{}}' -wasmd add-wasm-genesis-message execute $FIRST_CONTRACT_ADDR "$MSG" --run-as validator --amount=1ustake - -echo "-----------------------" -echo "## List Genesis CosmWasm codes" -wasmd add-wasm-genesis-message list-codes - -echo "-----------------------" -echo "## List Genesis CosmWasm contracts" -wasmd add-wasm-genesis-message list-contracts diff --git a/contrib/local/start_node.sh b/contrib/local/start_node.sh index 95785c3b62..30e078eb9f 100755 --- a/contrib/local/start_node.sh +++ b/contrib/local/start_node.sh @@ -1,4 +1,4 @@ #!/bin/bash set -eu -wasmd start --rpc.laddr tcp://0.0.0.0:26657 --log_level=info --trace # --trace # does not work anymore: --log_level="main:info,state:debug,*:error" +wasmd start --rpc.laddr tcp://0.0.0.0:26657 --log_level=info --trace #remove trace flag if you don't wantg the stack trace to be printed diff --git a/x/wasm/client/cli/query.go b/x/wasm/client/cli/query.go index a621ba0825..ab346bcfe1 100644 --- a/x/wasm/client/cli/query.go +++ b/x/wasm/client/cli/query.go @@ -63,6 +63,7 @@ func GetCmdLibVersion() *cobra.Command { fmt.Println(version) return nil }, + SilenceUsage: true, } return cmd } @@ -103,6 +104,7 @@ func GetCmdBuildAddress() *cobra.Command { cmd.Println(keeper.BuildContractAddressPredictable(codeHash, creator, salt, msg).String()) return nil }, + SilenceUsage: true, } decoder.RegisterFlags(cmd.PersistentFlags(), "salt") return cmd From f4905955b54900bd9dc91a33ade1ed1e0854e789 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 08:10:13 +0000 Subject: [PATCH 051/294] Bump bufbuild/buf-setup-action from 1.11.0 to 1.12.0 Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/proto-buf-publisher.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-buf-publisher.yml b/.github/workflows/proto-buf-publisher.yml index c4be716578..d8b250f272 100644 --- a/.github/workflows/proto-buf-publisher.yml +++ b/.github/workflows/proto-buf-publisher.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3.3.0 - - uses: bufbuild/buf-setup-action@v1.11.0 + - uses: bufbuild/buf-setup-action@v1.12.0 # lint checks - uses: bufbuild/buf-lint-action@v1 From 38d466adfd8bd0e71a60e1dce3881b54000483e8 Mon Sep 17 00:00:00 2001 From: llllllluc <58892938+llllllluc@users.noreply.github.com> Date: Sat, 21 Jan 2023 18:16:36 -0800 Subject: [PATCH 052/294] fix msg format in EVENTS.md --- EVENTS.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/EVENTS.md b/EVENTS.md index c1d119cd8e..371e1c405e 100644 --- a/EVENTS.md +++ b/EVENTS.md @@ -166,13 +166,13 @@ sdk.NewEvent( sdk.NewEvent( "instantiate", sdk.NewAttribute("code_id", fmt.Sprintf("%d", msg.CodeID)), - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ) // Execute Contract sdk.NewEvent( "execute", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ) // Migrate Contract @@ -180,20 +180,20 @@ sdk.NewEvent( "migrate", // Note: this is the new code id that is being migrated to sdk.NewAttribute("code_id", fmt.Sprintf("%d", msg.CodeID)), - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ) // Set new admin sdk.NewEvent( "update_admin", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("admin", msg.NewAdmin), ) // Clear admin sdk.NewEvent( "clear_admin", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ) // Pin Code @@ -211,7 +211,7 @@ sdk.NewEvent( // Emitted when processing a submessage reply sdk.NewEvent( "reply", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), // If the submessage was successful, and reply is processing the success case sdk.NewAttribute("mode", "handle_success"), // If the submessage returned an error that was "caught" by the reply block @@ -221,12 +221,12 @@ sdk.NewEvent( // Emitted when handling sudo sdk.NewEvent( "sudo", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ) ``` -Note that every event that affects a contract (not store code, pin or unpin) will return the contract_addr as -`_contract_addr`. The events that are related to a particular wasm code (store code, instantiate, pin, unpin, and migrate) +Note that every event that affects a contract (not store code, pin or unpin) will return the contract_address as +`_contract_address`. The events that are related to a particular wasm code (store code, instantiate, pin, unpin, and migrate) will emit that as `code_id`. All attributes prefixed with `_` are reserved and may not be emitted by a smart contract, so we use the underscore prefix consistently with attributes that may be injected into custom events. @@ -247,14 +247,14 @@ an eg. `transfer` event from the bank module. The output here may look like: ```go sdk.NewEvent( "wasm-promote" - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("batch_id", "6"), sdk.NewAttribute("address", "cosmos1234567"), sdk.NewAttribute("address", "cosmos1765432"), ), sdk.NewEvent( "wasm-promote" - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("batch_id", "7"), sdk.NewAttribute("address", "cosmos19875632"), ) @@ -267,7 +267,7 @@ more than flattening them all into one event like: ```go sdk.NewEvent( "wasm" - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("action", "promote"), sdk.NewAttribute("batch_id", "6"), sdk.NewAttribute("address", "cosmos1234567"), @@ -338,11 +338,11 @@ sdk.NewEvent( // top-level exection call sdk.NewEvent( "execute", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), ), sdk.NewEvent( "wasm", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("custom", "from contract"), ), @@ -350,24 +350,24 @@ sdk.NewEvent( sdk.NewEvent( "instantiate", sdk.NewAttribute("code_id", fmt.Sprintf("%d", msg.CodeID)), - sdk.NewAttribute("_contract_addr", newContract.String()), + sdk.NewAttribute("_contract_address", newContract.String()), ) // didn't emit any attributes, but one event sdk.NewEvent( "wasm-custom", - sdk.NewAttribute("_contract_addr", newContract.String()), + sdk.NewAttribute("_contract_address", newContract.String()), sdk.NewAttribute("foobar", "baz"), ), // handling the reply (this doesn't emit a message event as it never goes through the message server) sdk.NewEvent( "reply", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("mode", "handle_success"), ), sdk.NewEvent( "wasm", - sdk.NewAttribute("_contract_addr", contractAddr.String()), + sdk.NewAttribute("_contract_address", contractAddr.String()), sdk.NewAttribute("custom", "from contract"), ), @@ -389,11 +389,11 @@ field, and the following in the `events` field: sdk.NewEvent( "instantiate", sdk.NewAttribute("code_id", fmt.Sprintf("%d", msg.CodeID)), - sdk.NewAttribute("_contract_addr", newContract.String()), + sdk.NewAttribute("_contract_address", newContract.String()), ) sdk.NewEvent( "wasm-custom", - sdk.NewAttribute("_contract_addr", newContract.String()), + sdk.NewAttribute("_contract_address", newContract.String()), sdk.NewAttribute("foobar", "baz"), ), ``` From a925a9ed61752c335c66964ec4241dac5cb0ff70 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Tue, 24 Jan 2023 09:03:11 +0100 Subject: [PATCH 053/294] Better to sdk coin convertion (#1164) * Better to sdk coin convertion * Review feedback --- x/wasm/keeper/handler_plugin.go | 3 + x/wasm/keeper/handler_plugin_encoders.go | 5 +- x/wasm/keeper/handler_plugin_encoders_test.go | 82 +++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/x/wasm/keeper/handler_plugin.go b/x/wasm/keeper/handler_plugin.go index c23a09b020..82c9dbdf47 100644 --- a/x/wasm/keeper/handler_plugin.go +++ b/x/wasm/keeper/handler_plugin.go @@ -209,6 +209,9 @@ func NewBurnCoinMessageHandler(burner types.Burner) MessageHandlerFunc { if err != nil { return nil, nil, err } + if coins.IsZero() { + return nil, nil, types.ErrEmpty.Wrap("amount") + } if err := burner.SendCoinsFromAccountToModule(ctx, contractAddr, types.ModuleName, coins); err != nil { return nil, nil, sdkerrors.Wrap(err, "transfer to module") } diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index 3c7184dde4..394c1ff89e 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -329,10 +329,9 @@ func ConvertWasmCoinsToSdkCoins(coins []wasmvmtypes.Coin) (sdk.Coins, error) { if err != nil { return nil, err } - toSend = append(toSend, c) + toSend = toSend.Add(c) } - toSend.Sort() - return toSend, nil + return toSend.Sort(), nil } // ConvertWasmCoinToSdkCoin converts a wasm vm type coin to sdk type coin diff --git a/x/wasm/keeper/handler_plugin_encoders_test.go b/x/wasm/keeper/handler_plugin_encoders_test.go index 7f56776e48..d6cef9c793 100644 --- a/x/wasm/keeper/handler_plugin_encoders_test.go +++ b/x/wasm/keeper/handler_plugin_encoders_test.go @@ -635,3 +635,85 @@ func TestConvertWasmCoinToSdkCoin(t *testing.T) { }) } } + +func TestConvertWasmCoinsToSdkCoins(t *testing.T) { + specs := map[string]struct { + src []wasmvmtypes.Coin + exp sdk.Coins + expErr bool + }{ + "empty": { + src: []wasmvmtypes.Coin{}, + exp: nil, + }, + "single coin": { + src: []wasmvmtypes.Coin{{Denom: "foo", Amount: "1"}}, + exp: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1))), + }, + "multiple coins": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "bar", Amount: "2"}, + }, + exp: sdk.NewCoins( + sdk.NewCoin("bar", sdk.NewInt(2)), + sdk.NewCoin("foo", sdk.NewInt(1)), + ), + }, + "sorted": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "other", Amount: "1"}, + {Denom: "bar", Amount: "1"}, + }, + exp: []sdk.Coin{ + sdk.NewCoin("bar", sdk.NewInt(1)), + sdk.NewCoin("foo", sdk.NewInt(1)), + sdk.NewCoin("other", sdk.NewInt(1)), + }, + }, + "zero amounts dropped": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "bar", Amount: "0"}, + }, + exp: sdk.NewCoins( + sdk.NewCoin("foo", sdk.NewInt(1)), + ), + }, + "duplicate denoms merged": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "foo", Amount: "1"}, + }, + exp: []sdk.Coin{sdk.NewCoin("foo", sdk.NewInt(2))}, + }, + "duplicate denoms with one 0 amount does not fail": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "0"}, + {Denom: "foo", Amount: "1"}, + }, + exp: []sdk.Coin{sdk.NewCoin("foo", sdk.NewInt(1))}, + }, + "empty denom rejected": { + src: []wasmvmtypes.Coin{{Denom: "", Amount: "1"}}, + expErr: true, + }, + "invalid denom rejected": { + src: []wasmvmtypes.Coin{{Denom: "!%&", Amount: "1"}}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotCoins, gotErr := ConvertWasmCoinsToSdkCoins(spec.src) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, gotCoins) + assert.NoError(t, gotCoins.Validate()) + }) + } +} From 957b38e0a548e7caa2f4955fdd53d631c33a4965 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Wed, 25 Jan 2023 10:01:26 +0100 Subject: [PATCH 054/294] Integrate wasmvm v1.2.0 (#1161) * Bump wasmvm version * Bump wasm test contracts * Encode weighted votes * Encode instantiate2 * Handle code info query; better wasmvm errors * Fix readme * Make linter happy * add non cgo build * Review comments * Bump wasmvm to release version Co-authored-by: jhernandezb --- Dockerfile | 9 +- README.md | 2 + app/app.go | 3 +- go.mod | 4 +- go.sum | 4 +- x/wasm/client/cli/gov_tx_test.go | 2 +- x/wasm/keeper/handler_plugin_encoders.go | 61 ++++- x/wasm/keeper/handler_plugin_encoders_test.go | 257 ++++++++++++++++-- x/wasm/keeper/keeper.go | 56 ---- x/wasm/keeper/keeper_cgo.go | 69 +++++ x/wasm/keeper/keeper_no_cgo.go | 35 +++ x/wasm/keeper/keeper_test.go | 9 +- x/wasm/keeper/proposal_integration_test.go | 4 +- x/wasm/keeper/query_plugins.go | 34 ++- x/wasm/keeper/query_plugins_test.go | 87 +++++- x/wasm/keeper/recurse_test.go | 32 +-- x/wasm/keeper/testdata/burner.wasm | Bin 124838 -> 127528 bytes x/wasm/keeper/testdata/hackatom.wasm | Bin 208805 -> 177474 bytes x/wasm/keeper/testdata/hackatom.wasm.gzip | Bin 74777 -> 64560 bytes x/wasm/keeper/testdata/ibc_reflect.wasm | Bin 274438 -> 254798 bytes x/wasm/keeper/testdata/ibc_reflect_send.wasm | Bin 278731 -> 269429 bytes x/wasm/keeper/testdata/reflect.wasm | Bin 265746 -> 257191 bytes x/wasm/keeper/testdata/staking.wasm | Bin 229117 -> 222166 bytes x/wasm/keeper/testdata/version.txt | 2 +- x/wasm/types/errors.go | 74 ++++- x/wasm/types/errors_test.go | 86 ++++++ 26 files changed, 688 insertions(+), 142 deletions(-) create mode 100644 x/wasm/keeper/keeper_cgo.go create mode 100644 x/wasm/keeper/keeper_no_cgo.go create mode 100644 x/wasm/types/errors_test.go diff --git a/Dockerfile b/Dockerfile index 649cf7eb5b..de15ee3218 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,12 +14,11 @@ RUN apk add git WORKDIR /code COPY . /code/ - # See https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.1.1/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.1.1/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 9ecb037336bd56076573dc18c26631a9d2099a7f2b40dc04b6cae31ffb4c8f9a -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 6e4de7ba9bad4ae9679c7f9ecf7e283dd0160e71567c6a7be6ae47c81ebe7f32 +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.2.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep cba4b334893456c64df177939cbdd09afe4812432c02ae37d60d69a111b1b50d +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 6f87082f7a62602f9725d529677f330b9c4dd4607887be52a86328c6c919495b # Copy the library you want to the final location that will be found by the linker flag `-lwasmvm_muslc` RUN cp /lib/libwasmvm_muslc.${arch}.a /lib/libwasmvm_muslc.a diff --git a/README.md b/README.md index 367492f4f1..e85a21f328 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # Wasm Zone [![CircleCI](https://circleci.com/gh/CosmWasm/wasmd/tree/main.svg?style=shield)](https://circleci.com/gh/CosmWasm/wasmd/tree/main) @@ -26,6 +27,7 @@ compatibility list: | wasmd | wasmvm | cosmwasm-vm | cosmwasm-std | |-------|--------------|-------------|--------------| +| 0.31 | v1.2.0 | | 1.0-1.2 | | 0.30 | v1.1.0 | | 1.0-1.1 | | 0.29 | v1.1.0 | | 1.0-1.1 | | 0.28 | v1.0.0 | | 1.0-1.1 | diff --git a/app/app.go b/app/app.go index 569f22e490..55d8f7ccec 100644 --- a/app/app.go +++ b/app/app.go @@ -513,7 +513,8 @@ func NewWasmApp( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks - availableCapabilities := "iterator,staking,stargate,cosmwasm_1_1" + // See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md + availableCapabilities := "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2" app.WasmKeeper = wasm.NewKeeper( appCodec, keys[wasm.StoreKey], diff --git a/go.mod b/go.mod index d3d031c63f..a3f432ea0a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/CosmWasm/wasmd go 1.19 require ( - github.com/CosmWasm/wasmvm v1.1.1 + github.com/CosmWasm/wasmvm v1.2.0 github.com/cosmos/cosmos-proto v1.0.0-beta.1 github.com/cosmos/cosmos-sdk v0.45.11 github.com/cosmos/gogoproto v1.4.3 @@ -24,7 +24,6 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.6.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.14.0 github.com/stretchr/testify v1.8.1 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/tendermint v0.34.23 @@ -111,6 +110,7 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.14.0 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect diff --git a/go.sum b/go.sum index e5eb5a2b56..9e4330d270 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmvm v1.1.1 h1:0xtdrmmsP9fibe+x42WcMkp5aQ738BICgcH3FNVLzm4= -github.com/CosmWasm/wasmvm v1.1.1/go.mod h1:ei0xpvomwSdONsxDuONzV7bL1jSET1M8brEx0FCXc+A= +github.com/CosmWasm/wasmvm v1.2.0 h1:pNCp175id+r/dSa4Ii5zoTkmauOoeipkvepvEJM1bao= +github.com/CosmWasm/wasmvm v1.2.0/go.mod h1:OIhXFPi9BbcEL1USBj4OIrBTtSSds+9eEql56fsdyfE= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= diff --git a/x/wasm/client/cli/gov_tx_test.go b/x/wasm/client/cli/gov_tx_test.go index 147b9f61b1..265cad4939 100644 --- a/x/wasm/client/cli/gov_tx_test.go +++ b/x/wasm/client/cli/gov_tx_test.go @@ -104,7 +104,7 @@ func TestParseCodeInfoFlags(t *testing.T) { wasmBin, err := os.ReadFile("../../keeper/testdata/hackatom.wasm") require.NoError(t, err) - checksumStr := "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5" + checksumStr := "beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b" specs := map[string]struct { args []string diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index 394c1ff89e..d41d8f1012 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -237,6 +237,24 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, Funds: coins, } return []sdk.Msg{&sdkMsg}, nil + case msg.Instantiate2 != nil: + coins, err := ConvertWasmCoinsToSdkCoins(msg.Instantiate2.Funds) + if err != nil { + return nil, err + } + + sdkMsg := types.MsgInstantiateContract2{ + Sender: sender.String(), + Admin: msg.Instantiate2.Admin, + CodeID: msg.Instantiate2.CodeID, + Label: msg.Instantiate2.Label, + Msg: msg.Instantiate2.Msg, + Funds: coins, + Salt: msg.Instantiate2.Salt, + // FixMsg is discouraged, see: https://medium.com/cosmwasm/dev-note-3-limitations-of-instantiate2-and-how-to-deal-with-them-a3f946874230 + FixMsg: false, + } + return []sdk.Msg{&sdkMsg}, nil case msg.Migrate != nil: sdkMsg := types.MsgMigrateContract{ Sender: sender.String(), @@ -288,14 +306,44 @@ func EncodeIBCMsg(portSource types.ICS20TransferPortSource) func(ctx sdk.Context } return []sdk.Msg{msg}, nil default: - return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "Unknown variant of IBC") + return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "unknown variant of IBC") } } } func EncodeGovMsg(sender sdk.AccAddress, msg *wasmvmtypes.GovMsg) ([]sdk.Msg, error) { + switch { + case msg.Vote != nil: + voteOption, err := convertVoteOption(msg.Vote.Vote) + if err != nil { + return nil, sdkerrors.Wrap(err, "vote option") + } + m := govtypes.NewMsgVote(sender, msg.Vote.ProposalId, voteOption) + return []sdk.Msg{m}, nil + case msg.VoteWeighted != nil: + opts := make([]govtypes.WeightedVoteOption, len(msg.VoteWeighted.Options)) + for i, v := range msg.VoteWeighted.Options { + weight, err := sdk.NewDecFromStr(v.Weight) + if err != nil { + return nil, sdkerrors.Wrapf(err, "weight for vote %d", i+1) + } + voteOption, err := convertVoteOption(v.Option) + if err != nil { + return nil, sdkerrors.Wrap(err, "vote option") + } + opts[i] = govtypes.WeightedVoteOption{Option: voteOption, Weight: weight} + } + m := govtypes.NewMsgVoteWeighted(sender, msg.VoteWeighted.ProposalId, opts) + return []sdk.Msg{m}, nil + + default: + return nil, types.ErrUnknownMsg.Wrap("unknown variant of gov") + } +} + +func convertVoteOption(s interface{}) (govtypes.VoteOption, error) { var option govtypes.VoteOption - switch msg.Vote.Vote { + switch s { case wasmvmtypes.Yes: option = govtypes.OptionYes case wasmvmtypes.No: @@ -304,13 +352,10 @@ func EncodeGovMsg(sender sdk.AccAddress, msg *wasmvmtypes.GovMsg) ([]sdk.Msg, er option = govtypes.OptionNoWithVeto case wasmvmtypes.Abstain: option = govtypes.OptionAbstain + default: + return govtypes.OptionEmpty, types.ErrInvalid } - vote := &govtypes.MsgVote{ - ProposalId: msg.Vote.ProposalId, - Voter: sender.String(), - Option: option, - } - return []sdk.Msg{vote}, nil + return option, nil } // ConvertWasmIBCTimeoutHeightToCosmosHeight converts a wasmvm type ibc timeout height to ibc module type height diff --git a/x/wasm/keeper/handler_plugin_encoders_test.go b/x/wasm/keeper/handler_plugin_encoders_test.go index d6cef9c793..60b66fbc0d 100644 --- a/x/wasm/keeper/handler_plugin_encoders_test.go +++ b/x/wasm/keeper/handler_plugin_encoders_test.go @@ -65,8 +65,10 @@ func TestEncoding(t *testing.T) { transferPortSource types.ICS20TransferPortSource // set if valid output []sdk.Msg - // set if invalid - isError bool + // set if expect mapping fails + expError bool + // set if sdk validate basic should fail + expInvalid bool }{ "simple send": { sender: addr1, @@ -113,7 +115,7 @@ func TestEncoding(t *testing.T) { }, }, }, - isError: true, + expError: true, }, "invalid address": { sender: addr1, @@ -130,7 +132,8 @@ func TestEncoding(t *testing.T) { }, }, }, - isError: false, // addresses are checked in the handler + expError: false, // addresses are checked in the handler + expInvalid: true, output: []sdk.Msg{ &banktypes.MsgSend{ FromAddress: addr1.String(), @@ -189,6 +192,35 @@ func TestEncoding(t *testing.T) { }, }, }, + "wasm instantiate2": { + sender: addr1, + srcMsg: wasmvmtypes.CosmosMsg{ + Wasm: &wasmvmtypes.WasmMsg{ + Instantiate2: &wasmvmtypes.Instantiate2Msg{ + CodeID: 7, + Msg: jsonMsg, + Funds: []wasmvmtypes.Coin{ + wasmvmtypes.NewCoin(123, "eth"), + }, + Label: "myLabel", + Admin: addr2.String(), + Salt: []byte("mySalt"), + }, + }, + }, + output: []sdk.Msg{ + &types.MsgInstantiateContract2{ + Sender: addr1.String(), + Admin: addr2.String(), + CodeID: 7, + Label: "myLabel", + Msg: jsonMsg, + Funds: sdk.NewCoins(sdk.NewInt64Coin("eth", 123)), + Salt: []byte("mySalt"), + FixMsg: false, + }, + }, + }, "wasm migrate": { sender: addr2, srcMsg: wasmvmtypes.CosmosMsg{ @@ -271,7 +303,7 @@ func TestEncoding(t *testing.T) { }, }, }, - isError: false, // fails in the handler + expError: false, // fails in the handler output: []sdk.Msg{ &stakingtypes.MsgDelegate{ DelegatorAddress: addr1.String(), @@ -378,7 +410,7 @@ func TestEncoding(t *testing.T) { Value: bankMsgBin, }, }, - isError: true, + expError: true, }, "IBC transfer with block timeout": { sender: addr1, @@ -500,9 +532,49 @@ func TestEncoding(t *testing.T) { }, }, }, + } + encodingConfig := MakeEncodingConfig(t) + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + var ctx sdk.Context + encoder := DefaultEncoders(encodingConfig.Marshaler, tc.transferPortSource) + res, err := encoder.Encode(ctx, tc.sender, tc.srcContractIBCPort, tc.srcMsg) + if tc.expError { + assert.Error(t, err) + return + } else { + require.NoError(t, err) + assert.Equal(t, tc.output, res) + } + // and valid sdk message + for _, v := range res { + gotErr := v.ValidateBasic() + if tc.expInvalid { + assert.Error(t, gotErr) + } else { + assert.NoError(t, gotErr) + } + } + }) + } +} + +func TestEncodeGovMsg(t *testing.T) { + myAddr := RandomAccountAddress(t) + + cases := map[string]struct { + sender sdk.AccAddress + srcMsg wasmvmtypes.CosmosMsg + transferPortSource types.ICS20TransferPortSource + // set if valid + output []sdk.Msg + // set if expect mapping fails + expError bool + // set if sdk validate basic should fail + expInvalid bool + }{ "Gov vote: yes": { - sender: addr1, - srcContractIBCPort: "myIBCPort", + sender: myAddr, srcMsg: wasmvmtypes.CosmosMsg{ Gov: &wasmvmtypes.GovMsg{ Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.Yes}, @@ -511,14 +583,13 @@ func TestEncoding(t *testing.T) { output: []sdk.Msg{ &govtypes.MsgVote{ ProposalId: 1, - Voter: addr1.String(), + Voter: myAddr.String(), Option: govtypes.OptionYes, }, }, }, "Gov vote: No": { - sender: addr1, - srcContractIBCPort: "myIBCPort", + sender: myAddr, srcMsg: wasmvmtypes.CosmosMsg{ Gov: &wasmvmtypes.GovMsg{ Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.No}, @@ -527,14 +598,13 @@ func TestEncoding(t *testing.T) { output: []sdk.Msg{ &govtypes.MsgVote{ ProposalId: 1, - Voter: addr1.String(), + Voter: myAddr.String(), Option: govtypes.OptionNo, }, }, }, "Gov vote: Abstain": { - sender: addr1, - srcContractIBCPort: "myIBCPort", + sender: myAddr, srcMsg: wasmvmtypes.CosmosMsg{ Gov: &wasmvmtypes.GovMsg{ Vote: &wasmvmtypes.VoteMsg{ProposalId: 10, Vote: wasmvmtypes.Abstain}, @@ -543,14 +613,13 @@ func TestEncoding(t *testing.T) { output: []sdk.Msg{ &govtypes.MsgVote{ ProposalId: 10, - Voter: addr1.String(), + Voter: myAddr.String(), Option: govtypes.OptionAbstain, }, }, }, "Gov vote: No with veto": { - sender: addr1, - srcContractIBCPort: "myIBCPort", + sender: myAddr, srcMsg: wasmvmtypes.CosmosMsg{ Gov: &wasmvmtypes.GovMsg{ Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.NoWithVeto}, @@ -559,24 +628,168 @@ func TestEncoding(t *testing.T) { output: []sdk.Msg{ &govtypes.MsgVote{ ProposalId: 1, - Voter: addr1.String(), + Voter: myAddr.String(), Option: govtypes.OptionNoWithVeto, }, }, }, + "Gov vote: unset option": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + Vote: &wasmvmtypes.VoteMsg{ProposalId: 1}, + }, + }, + expError: true, + }, + "Gov weighted vote: single vote": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + VoteWeighted: &wasmvmtypes.VoteWeightedMsg{ + ProposalId: 1, + Options: []wasmvmtypes.WeightedVoteOption{ + {Option: wasmvmtypes.Yes, Weight: "1"}, + }, + }, + }, + }, + output: []sdk.Msg{ + &govtypes.MsgVoteWeighted{ + ProposalId: 1, + Voter: myAddr.String(), + Options: []govtypes.WeightedVoteOption{ + {Option: govtypes.OptionYes, Weight: sdk.NewDec(1)}, + }, + }, + }, + }, + "Gov weighted vote: splitted": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + VoteWeighted: &wasmvmtypes.VoteWeightedMsg{ + ProposalId: 1, + Options: []wasmvmtypes.WeightedVoteOption{ + {Option: wasmvmtypes.Yes, Weight: "0.23"}, + {Option: wasmvmtypes.No, Weight: "0.24"}, + {Option: wasmvmtypes.Abstain, Weight: "0.26"}, + {Option: wasmvmtypes.NoWithVeto, Weight: "0.27"}, + }, + }, + }, + }, + output: []sdk.Msg{ + &govtypes.MsgVoteWeighted{ + ProposalId: 1, + Voter: myAddr.String(), + Options: []govtypes.WeightedVoteOption{ + {Option: govtypes.OptionYes, Weight: sdk.NewDecWithPrec(23, 2)}, + {Option: govtypes.OptionNo, Weight: sdk.NewDecWithPrec(24, 2)}, + {Option: govtypes.OptionAbstain, Weight: sdk.NewDecWithPrec(26, 2)}, + {Option: govtypes.OptionNoWithVeto, Weight: sdk.NewDecWithPrec(27, 2)}, + }, + }, + }, + }, + "Gov weighted vote: duplicate option": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + VoteWeighted: &wasmvmtypes.VoteWeightedMsg{ + ProposalId: 1, + Options: []wasmvmtypes.WeightedVoteOption{ + {Option: wasmvmtypes.Yes, Weight: "0.5"}, + {Option: wasmvmtypes.Yes, Weight: "0.5"}, + }, + }, + }, + }, + output: []sdk.Msg{ + &govtypes.MsgVoteWeighted{ + ProposalId: 1, + Voter: myAddr.String(), + Options: []govtypes.WeightedVoteOption{ + {Option: govtypes.OptionYes, Weight: sdk.NewDecWithPrec(5, 1)}, + {Option: govtypes.OptionYes, Weight: sdk.NewDecWithPrec(5, 1)}, + }, + }, + }, + expInvalid: true, + }, + "Gov weighted vote: weight sum exceeds 1": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + VoteWeighted: &wasmvmtypes.VoteWeightedMsg{ + ProposalId: 1, + Options: []wasmvmtypes.WeightedVoteOption{ + {Option: wasmvmtypes.Yes, Weight: "0.51"}, + {Option: wasmvmtypes.No, Weight: "0.5"}, + }, + }, + }, + }, + output: []sdk.Msg{ + &govtypes.MsgVoteWeighted{ + ProposalId: 1, + Voter: myAddr.String(), + Options: []govtypes.WeightedVoteOption{ + {Option: govtypes.OptionYes, Weight: sdk.NewDecWithPrec(51, 2)}, + {Option: govtypes.OptionNo, Weight: sdk.NewDecWithPrec(5, 1)}, + }, + }, + }, + expInvalid: true, + }, + "Gov weighted vote: weight sum less than 1": { + sender: myAddr, + srcMsg: wasmvmtypes.CosmosMsg{ + Gov: &wasmvmtypes.GovMsg{ + VoteWeighted: &wasmvmtypes.VoteWeightedMsg{ + ProposalId: 1, + Options: []wasmvmtypes.WeightedVoteOption{ + {Option: wasmvmtypes.Yes, Weight: "0.49"}, + {Option: wasmvmtypes.No, Weight: "0.5"}, + }, + }, + }, + }, + output: []sdk.Msg{ + &govtypes.MsgVoteWeighted{ + ProposalId: 1, + Voter: myAddr.String(), + Options: []govtypes.WeightedVoteOption{ + {Option: govtypes.OptionYes, Weight: sdk.NewDecWithPrec(49, 2)}, + {Option: govtypes.OptionNo, Weight: sdk.NewDecWithPrec(5, 1)}, + }, + }, + }, + expInvalid: true, + }, } encodingConfig := MakeEncodingConfig(t) for name, tc := range cases { t.Run(name, func(t *testing.T) { var ctx sdk.Context encoder := DefaultEncoders(encodingConfig.Marshaler, tc.transferPortSource) - res, err := encoder.Encode(ctx, tc.sender, tc.srcContractIBCPort, tc.srcMsg) - if tc.isError { - require.Error(t, err) + res, gotEncErr := encoder.Encode(ctx, tc.sender, "myIBCPort", tc.srcMsg) + if tc.expError { + assert.Error(t, gotEncErr) + return } else { - require.NoError(t, err) + require.NoError(t, gotEncErr) assert.Equal(t, tc.output, res) } + // and valid sdk message + for _, v := range res { + gotErr := v.ValidateBasic() + if tc.expInvalid { + assert.Error(t, gotErr) + } else { + assert.NoError(t, gotErr) + } + } }) } } diff --git a/x/wasm/keeper/keeper.go b/x/wasm/keeper/keeper.go index 195a4614ce..5adb2075fd 100644 --- a/x/wasm/keeper/keeper.go +++ b/x/wasm/keeper/keeper.go @@ -7,7 +7,6 @@ import ( "encoding/hex" "fmt" "math" - "path/filepath" "reflect" "strconv" "strings" @@ -104,61 +103,6 @@ type Keeper struct { accountPruner AccountPruner } -// NewKeeper creates a new contract Keeper instance -// If customEncoders is non-nil, we can use this to override some of the message handler, especially custom -func NewKeeper( - cdc codec.Codec, - storeKey sdk.StoreKey, - paramSpace paramtypes.Subspace, - accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, - stakingKeeper types.StakingKeeper, - distKeeper types.DistributionKeeper, - channelKeeper types.ChannelKeeper, - portKeeper types.PortKeeper, - capabilityKeeper types.CapabilityKeeper, - portSource types.ICS20TransferPortSource, - router MessageRouter, - _ GRPCQueryRouter, - homeDir string, - wasmConfig types.WasmConfig, - availableCapabilities string, - opts ...Option, -) Keeper { - wasmer, err := wasmvm.NewVM(filepath.Join(homeDir, "wasm"), availableCapabilities, contractMemoryLimit, wasmConfig.ContractDebugMode, wasmConfig.MemoryCacheSize) - if err != nil { - panic(err) - } - // set KeyTable if it has not already been set - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) - } - - keeper := &Keeper{ - storeKey: storeKey, - cdc: cdc, - wasmVM: wasmer, - accountKeeper: accountKeeper, - bank: NewBankCoinTransferrer(bankKeeper), - accountPruner: NewVestingCoinBurner(bankKeeper), - portKeeper: portKeeper, - capabilityKeeper: capabilityKeeper, - messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource), - queryGasLimit: wasmConfig.SmartQueryGasLimit, - paramSpace: paramSpace, - gasRegister: NewDefaultWasmGasRegister(), - maxQueryStackSize: types.DefaultMaxQueryStackSize, - acceptedAccountTypes: defaultAcceptedAccountTypes, - } - keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, keeper) - for _, o := range opts { - o.apply(keeper) - } - // not updateable, yet - keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper)) - return *keeper -} - func (k Keeper) getUploadAccessConfig(ctx sdk.Context) types.AccessConfig { var a types.AccessConfig k.paramSpace.Get(ctx, types.ParamStoreKeyUploadAccess, &a) diff --git a/x/wasm/keeper/keeper_cgo.go b/x/wasm/keeper/keeper_cgo.go new file mode 100644 index 0000000000..06a0ccabe6 --- /dev/null +++ b/x/wasm/keeper/keeper_cgo.go @@ -0,0 +1,69 @@ +//go:build cgo + +package keeper + +import ( + "path/filepath" + + wasmvm "github.com/CosmWasm/wasmvm" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +// NewKeeper creates a new contract Keeper instance +// If customEncoders is non-nil, we can use this to override some of the message handler, especially custom +func NewKeeper( + cdc codec.Codec, + storeKey sdk.StoreKey, + paramSpace paramtypes.Subspace, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + stakingKeeper types.StakingKeeper, + distKeeper types.DistributionKeeper, + channelKeeper types.ChannelKeeper, + portKeeper types.PortKeeper, + capabilityKeeper types.CapabilityKeeper, + portSource types.ICS20TransferPortSource, + router MessageRouter, + queryRouter GRPCQueryRouter, + homeDir string, + wasmConfig types.WasmConfig, + availableCapabilities string, + opts ...Option, +) Keeper { + wasmer, err := wasmvm.NewVM(filepath.Join(homeDir, "wasm"), availableCapabilities, contractMemoryLimit, wasmConfig.ContractDebugMode, wasmConfig.MemoryCacheSize) + if err != nil { + panic(err) + } + // set KeyTable if it has not already been set + if !paramSpace.HasKeyTable() { + paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) + } + + keeper := &Keeper{ + storeKey: storeKey, + cdc: cdc, + wasmVM: wasmer, + accountKeeper: accountKeeper, + bank: NewBankCoinTransferrer(bankKeeper), + accountPruner: NewVestingCoinBurner(bankKeeper), + portKeeper: portKeeper, + capabilityKeeper: capabilityKeeper, + messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource), + queryGasLimit: wasmConfig.SmartQueryGasLimit, + paramSpace: paramSpace, + gasRegister: NewDefaultWasmGasRegister(), + maxQueryStackSize: types.DefaultMaxQueryStackSize, + acceptedAccountTypes: defaultAcceptedAccountTypes, + } + keeper.wasmVMQueryHandler = DefaultQueryPlugins(bankKeeper, stakingKeeper, distKeeper, channelKeeper, keeper) + for _, o := range opts { + o.apply(keeper) + } + // not updateable, yet + keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper)) + return *keeper +} diff --git a/x/wasm/keeper/keeper_no_cgo.go b/x/wasm/keeper/keeper_no_cgo.go new file mode 100644 index 0000000000..196b9ee1ee --- /dev/null +++ b/x/wasm/keeper/keeper_no_cgo.go @@ -0,0 +1,35 @@ +//go:build !cgo + +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + "github.com/CosmWasm/wasmd/x/wasm/types" +) + +// NewKeeper creates a new contract Keeper instance +// If customEncoders is non-nil, we can use this to override some of the message handler, especially custom +func NewKeeper( + cdc codec.Codec, + storeKey sdk.StoreKey, + paramSpace paramtypes.Subspace, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + stakingKeeper types.StakingKeeper, + distKeeper types.DistributionKeeper, + channelKeeper types.ChannelKeeper, + portKeeper types.PortKeeper, + capabilityKeeper types.CapabilityKeeper, + portSource types.ICS20TransferPortSource, + router MessageRouter, + queryRouter GRPCQueryRouter, + homeDir string, + wasmConfig types.WasmConfig, + availableCapabilities string, + opts ...Option, +) Keeper { + panic("not implemented, please build with cgo enabled") +} diff --git a/x/wasm/keeper/keeper_test.go b/x/wasm/keeper/keeper_test.go index 98136f5204..53485003f1 100644 --- a/x/wasm/keeper/keeper_test.go +++ b/x/wasm/keeper/keeper_test.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "os" + "strings" "testing" "time" @@ -59,7 +60,7 @@ func TestCreateSuccess(t *testing.T) { require.NoError(t, err) require.Equal(t, hackatomWasm, storedCode) // and events emitted - codeHash := "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5" + codeHash := strings.ToLower("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") exp := sdk.Events{sdk.NewEvent("store_code", sdk.NewAttribute("code_checksum", codeHash), sdk.NewAttribute("code_id", "1"))} assert.Equal(t, exp, em.Events()) } @@ -409,7 +410,7 @@ func TestInstantiate(t *testing.T) { gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x1a7bb), gasAfter-gasBefore) + require.Equal(t, uint64(0x1a7b6), gasAfter-gasBefore) } // ensure it is stored properly @@ -853,7 +854,7 @@ func TestExecute(t *testing.T) { // make sure gas is properly deducted from ctx gasAfter := ctx.GasMeter().GasConsumed() if types.EnableGasVerification { - require.Equal(t, uint64(0x17d87), gasAfter-gasBefore) + require.Equal(t, uint64(0x17d7f), gasAfter-gasBefore) } // ensure bob now exists and got both payments released bobAcct = accKeeper.GetAccount(ctx, bob) @@ -1008,7 +1009,7 @@ func TestExecuteWithPanic(t *testing.T) { require.Error(t, err) require.True(t, errors.Is(err, types.ErrExecuteFailed)) // test with contains as "Display" implementation of the Wasmer "RuntimeError" is different for Mac and Linux - assert.Contains(t, err.Error(), "Error calling the VM: Error executing Wasm: Wasmer runtime error: RuntimeError: unreachable") + assert.Contains(t, err.Error(), "Error calling the VM: Error executing Wasm: Wasmer runtime error: RuntimeError: Aborted: panicked at 'This page intentionally faulted', src/contract.rs:169:5: execute wasm contract failed") } func TestExecuteWithCpuLoop(t *testing.T) { diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 7ea9f657d9..fc2288d69c 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -29,7 +29,7 @@ func TestStoreCodeProposal(t *testing.T) { }) wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - checksum, err := hex.DecodeString("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5") + checksum, err := hex.DecodeString("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") require.NoError(t, err) specs := map[string]struct { @@ -288,7 +288,7 @@ func TestStoreAndInstantiateContractProposal(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) - checksum, err := hex.DecodeString("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5") + checksum, err := hex.DecodeString("beb3de5e9b93b52e514c74ce87ccddb594b9bcd33b7f1af1bb6da63fc883917b") require.NoError(t, err) var ( diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index c98afda693..91abcf5dc6 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -61,10 +61,10 @@ func (q QueryHandler) Query(request wasmvmtypes.QueryRequest, gasLimit uint64) ( return res, nil } - // special mappings to system error (which are not redacted) - var noSuchContract *types.ErrNoSuchContract - if ok := errors.As(err, &noSuchContract); ok { - err = wasmvmtypes.NoSuchContract{Addr: noSuchContract.Addr} + // special mappings to wasmvm system error (which are not redacted) + var wasmvmErr types.WasmVMErrorable + if ok := errors.As(err, &wasmvmErr); ok { + err = wasmvmErr.ToWasmVMError() } // Issue #759 - we don't return error string for worries of non-determinism @@ -92,6 +92,7 @@ type contractMetaDataSource interface { type wasmQueryKeeper interface { contractMetaDataSource + GetCodeInfo(ctx sdk.Context, codeID uint64) *types.CodeInfo QueryRaw(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) IsPinnedCode(ctx sdk.Context, codeID uint64) bool @@ -528,15 +529,16 @@ func WasmQuerier(k wasmQueryKeeper) func(ctx sdk.Context, request *wasmvmtypes.W } return k.QueryRaw(ctx, addr, request.Raw.Key), nil case request.ContractInfo != nil: - addr, err := sdk.AccAddressFromBech32(request.ContractInfo.ContractAddr) + contractAddr := request.ContractInfo.ContractAddr + addr, err := sdk.AccAddressFromBech32(contractAddr) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, request.ContractInfo.ContractAddr) + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, contractAddr) } info := k.GetContractInfo(ctx, addr) if info == nil { - return nil, &types.ErrNoSuchContract{Addr: request.ContractInfo.ContractAddr} + return nil, types.ErrNoSuchContractFn(contractAddr). + Wrapf("address %s", contractAddr) } - res := wasmvmtypes.ContractInfoResponse{ CodeID: info.CodeID, Creator: info.Creator, @@ -545,6 +547,22 @@ func WasmQuerier(k wasmQueryKeeper) func(ctx sdk.Context, request *wasmvmtypes.W IBCPort: info.IBCPortID, } return json.Marshal(res) + case request.CodeInfo != nil: + if request.CodeInfo.CodeID == 0 { + return nil, types.ErrEmpty.Wrap("code id") + } + info := k.GetCodeInfo(ctx, request.CodeInfo.CodeID) + if info == nil { + return nil, types.ErrNoSuchCodeFn(request.CodeInfo.CodeID). + Wrapf("code id %d", request.CodeInfo.CodeID) + } + + res := wasmvmtypes.CodeInfoResponse{ + CodeID: request.CodeInfo.CodeID, + Creator: info.Creator, + Checksum: info.CodeHash, + } + return json.Marshal(res) } return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown WasmQuery variant"} } diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index 0572cd28c3..c28a4462a3 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -460,6 +460,73 @@ func TestContractInfoWasmQuerier(t *testing.T) { } } +func TestCodeInfoWasmQuerier(t *testing.T) { + myCreatorAddr := keeper.RandomBech32AccountAddress(t) + var ctx sdk.Context + + myRawChecksum := []byte("myHash78901234567890123456789012") + specs := map[string]struct { + req *wasmvmtypes.WasmQuery + mock mockWasmQueryKeeper + expRes wasmvmtypes.CodeInfoResponse + expErr bool + }{ + "all good": { + req: &wasmvmtypes.WasmQuery{ + CodeInfo: &wasmvmtypes.CodeInfoQuery{CodeID: 1}, + }, + mock: mockWasmQueryKeeper{ + GetCodeInfoFn: func(ctx sdk.Context, codeID uint64) *types.CodeInfo { + return &types.CodeInfo{ + CodeHash: myRawChecksum, + Creator: myCreatorAddr, + InstantiateConfig: types.AccessConfig{ + Permission: types.AccessTypeNobody, + Addresses: []string{myCreatorAddr}, + }, + } + }, + }, + expRes: wasmvmtypes.CodeInfoResponse{ + CodeID: 1, + Creator: myCreatorAddr, + Checksum: myRawChecksum, + }, + }, + "empty code id": { + req: &wasmvmtypes.WasmQuery{ + CodeInfo: &wasmvmtypes.CodeInfoQuery{}, + }, + expErr: true, + }, + "unknown code id": { + req: &wasmvmtypes.WasmQuery{ + CodeInfo: &wasmvmtypes.CodeInfoQuery{CodeID: 1}, + }, + mock: mockWasmQueryKeeper{ + GetCodeInfoFn: func(ctx sdk.Context, codeID uint64) *types.CodeInfo { + return nil + }, + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + q := keeper.WasmQuerier(spec.mock) + gotBz, gotErr := q(ctx, spec.req) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + var gotRes wasmvmtypes.CodeInfoResponse + require.NoError(t, json.Unmarshal(gotBz, &gotRes), string(gotBz)) + assert.Equal(t, spec.expRes, gotRes) + }) + } +} + func TestQueryErrors(t *testing.T) { specs := map[string]struct { src error @@ -467,13 +534,21 @@ func TestQueryErrors(t *testing.T) { }{ "no error": {}, "no such contract": { - src: &types.ErrNoSuchContract{Addr: "contract-addr"}, + src: types.ErrNoSuchContractFn("contract-addr"), expErr: wasmvmtypes.NoSuchContract{Addr: "contract-addr"}, }, "no such contract - wrapped": { - src: sdkerrors.Wrap(&types.ErrNoSuchContract{Addr: "contract-addr"}, "my additional data"), + src: sdkerrors.Wrap(types.ErrNoSuchContractFn("contract-addr"), "my additional data"), expErr: wasmvmtypes.NoSuchContract{Addr: "contract-addr"}, }, + "no such code": { + src: types.ErrNoSuchCodeFn(123), + expErr: wasmvmtypes.NoSuchCode{CodeID: 123}, + }, + "no such code - wrapped": { + src: sdkerrors.Wrap(types.ErrNoSuchCodeFn(123), "my additional data"), + expErr: wasmvmtypes.NoSuchCode{CodeID: 123}, + }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { @@ -558,6 +633,7 @@ type mockWasmQueryKeeper struct { QueryRawFn func(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte QuerySmartFn func(ctx sdk.Context, contractAddr sdk.AccAddress, req types.RawContractMessage) ([]byte, error) IsPinnedCodeFn func(ctx sdk.Context, codeID uint64) bool + GetCodeInfoFn func(ctx sdk.Context, codeID uint64) *types.CodeInfo } func (m mockWasmQueryKeeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo { @@ -588,6 +664,13 @@ func (m mockWasmQueryKeeper) IsPinnedCode(ctx sdk.Context, codeID uint64) bool { return m.IsPinnedCodeFn(ctx, codeID) } +func (m mockWasmQueryKeeper) GetCodeInfo(ctx sdk.Context, codeID uint64) *types.CodeInfo { + if m.GetCodeInfoFn == nil { + panic("not expected to be called") + } + return m.GetCodeInfoFn(ctx, codeID) +} + type bankKeeperMock struct { GetSupplyFn func(ctx sdk.Context, denom string) sdk.Coin GetBalanceFn func(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin diff --git a/x/wasm/keeper/recurse_test.go b/x/wasm/keeper/recurse_test.go index 0c0831aa49..5bfb20bdec 100644 --- a/x/wasm/keeper/recurse_test.go +++ b/x/wasm/keeper/recurse_test.go @@ -16,9 +16,8 @@ import ( ) type Recurse struct { - Depth uint32 `json:"depth"` - Work uint32 `json:"work"` - Contract sdk.AccAddress `json:"contract"` + Depth uint32 `json:"depth"` + Work uint32 `json:"work"` } type recurseWrapper struct { @@ -54,12 +53,12 @@ func initRecurseContract(t *testing.T) (contract sdk.AccAddress, creator sdk.Acc func TestGasCostOnQuery(t *testing.T) { const ( - GasNoWork uint64 = 63_958 + GasNoWork uint64 = 63_950 // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 - GasWork50 uint64 = 64_401 // this is a little shy of 50k gas - to keep an eye on the limit + GasWork50 uint64 = 64_218 // this is a little shy of 50k gas - to keep an eye on the limit - GasReturnUnhashed uint64 = 33 - GasReturnHashed uint64 = 25 + GasReturnUnhashed uint64 = 32 + GasReturnHashed uint64 = 27 ) cases := map[string]struct { @@ -92,7 +91,7 @@ func TestGasCostOnQuery(t *testing.T) { Depth: 1, Work: 50, }, - expectedGas: 2*GasWork50 + GasReturnHashed + 1, // +1 for rounding + expectedGas: 2*GasWork50 + GasReturnHashed, }, "recursion 4, some work": { gasLimit: 400_000, @@ -100,7 +99,7 @@ func TestGasCostOnQuery(t *testing.T) { Depth: 4, Work: 50, }, - expectedGas: 5*GasWork50 + 4*GasReturnHashed + 1, + expectedGas: 5*GasWork50 + 4*GasReturnHashed, }, } @@ -117,7 +116,6 @@ func TestGasCostOnQuery(t *testing.T) { // do the query recurse := tc.msg - recurse.Contract = contractAddr msg := buildRecurseQuery(t, recurse) data, err := keeper.QuerySmart(ctx, contractAddr, msg) require.NoError(t, err) @@ -186,7 +184,6 @@ func TestGasOnExternalQuery(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { recurse := tc.msg - recurse.Contract = contractAddr msg := buildRecurseQuery(t, recurse) querier := NewGrpcQuerier(keeper.cdc, keeper.storeKey, keeper, tc.gasLimit) @@ -211,9 +208,9 @@ func TestLimitRecursiveQueryGas(t *testing.T) { const ( // Note: about 100 SDK gas (10k wasmer gas) for each round of sha256 - GasWork2k uint64 = 84_236 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance + GasWork2k uint64 = 77_206 // = NewContractInstanceCosts + x // we have 6x gas used in cpu than in the instance // This is overhead for calling into a sub-contract - GasReturnHashed uint64 = 26 + GasReturnHashed uint64 = 27 ) cases := map[string]struct { @@ -241,10 +238,10 @@ func TestLimitRecursiveQueryGas(t *testing.T) { }, expectQueriesFromContract: 5, // FIXME: why -1 ... confused a bit by calculations, seems like rounding issues - expectedGas: GasWork2k + 5*(GasWork2k+GasReturnHashed) - 1, + expectedGas: GasWork2k + 5*(GasWork2k+GasReturnHashed), }, // this is where we expect an error... - // it has enough gas to run 4 times and die on the 5th (4th time dispatching to sub-contract) + // it has enough gas to run 5 times and die on the 6th (5th time dispatching to sub-contract) // however, if we don't charge the cpu gas before sub-dispatching, we can recurse over 20 times "deep recursion, should die on 5th level": { gasLimit: 400_000, @@ -252,7 +249,7 @@ func TestLimitRecursiveQueryGas(t *testing.T) { Depth: 50, Work: 2000, }, - expectQueriesFromContract: 4, + expectQueriesFromContract: 5, expectOutOfGas: true, }, "very deep recursion, hits recursion limit": { @@ -264,7 +261,7 @@ func TestLimitRecursiveQueryGas(t *testing.T) { expectQueriesFromContract: 10, expectOutOfGas: false, expectError: "query wasm contract failed", // Error we get from the contract instance doing the failing query, not wasmd - expectedGas: 10*(GasWork2k+GasReturnHashed) - 264, + expectedGas: 10*(GasWork2k+GasReturnHashed) - 247, }, } @@ -281,7 +278,6 @@ func TestLimitRecursiveQueryGas(t *testing.T) { // prepare the query recurse := tc.msg - recurse.Contract = contractAddr msg := buildRecurseQuery(t, recurse) // if we expect out of gas, make sure this panics diff --git a/x/wasm/keeper/testdata/burner.wasm b/x/wasm/keeper/testdata/burner.wasm index 4e65059f7c44782d3c97612f7f8414c7371b527a..6639075611b73e21f3d0045d772ce84b406718e4 100644 GIT binary patch literal 127528 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 OE3W{~0~P?eROl~tF*(Hm literal 124838 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

p84TO=eIQtp6zxsI`ca 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 Q<*WH!!>@y1!`hbrAG;7^s{jB1 literal 208805 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

}GU#h*Z)$o|;7eU!8k$7&m@*^f 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 D^F!=F diff --git a/x/wasm/keeper/testdata/hackatom.wasm.gzip b/x/wasm/keeper/testdata/hackatom.wasm.gzip index 29b10c7d57cb0530d07f01496e5649842ce01d75..3c95e9b1d4cac2f9f0623b3336cdb068744e613e 100644 GIT binary patch literal 64560 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 Bn7IG| literal 74777 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%0A4d9R|u1j%o^zKJe>u!|;+ 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 diff --git a/x/wasm/keeper/testdata/ibc_reflect.wasm b/x/wasm/keeper/testdata/ibc_reflect.wasm index ec1739d898d9ef679373ae57d99e7fd421296c62..ec737104c434584f9e38d4aff968d29c128c3cc7 100644 GIT binary patch literal 254798 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 WrBhPB_oLIkiQnb?+W9r~w*3DY_Xp+x literal 274438 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

{>NVz3P?ishb_(Z}E?_9TsF2I>%fFrsFc(R0iK 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%0A*f(aN@$z#YMg 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 z 0 { - // Keep a queue on the chain that we can relay in tests - chain.PendingAckPackets = append(chain.PendingAckPackets, toAck...) - } } // GetClientState retrieves the client state for the provided clientID. The client is @@ -387,12 +449,12 @@ func (chain *TestChain) ExpireClient(amount time.Duration) { // CurrentTMClientHeader creates a TM header using the current header parameters // on the chain. The trusted fields in the header are set to nil. func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header { - return chain.CreateTMClientHeader(chain.ChainID, chain.CurrentHeader.Height, clienttypes.Height{}, chain.CurrentHeader.Time, chain.Vals, nil, chain.Signers) + return chain.CreateTMClientHeader(chain.ChainID, chain.CurrentHeader.Height, clienttypes.Height{}, chain.CurrentHeader.Time, chain.Vals, chain.NextVals, nil, chain.Signers) } // CreateTMClientHeader creates a TM header to update the TM client. Args are passed in to allow // caller flexibility to use params that differ from the chain. -func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *ibctmtypes.Header { +func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, nextVals, tmTrustedVals *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *ibctmtypes.Header { var ( valSet *tmproto.ValidatorSet trustedVals *tmproto.ValidatorSet @@ -400,6 +462,7 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, require.NotNil(chain.t, tmValSet) vsetHash := tmValSet.Hash() + nextValHash := nextVals.Hash() tmHeader := tmtypes.Header{ Version: tmprotoversion.Consensus{Block: tmversion.BlockProtocol, App: 2}, @@ -410,18 +473,27 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, LastCommitHash: chain.App.LastCommitID().Hash, DataHash: tmhash.Sum([]byte("data_hash")), ValidatorsHash: vsetHash, - NextValidatorsHash: vsetHash, + NextValidatorsHash: nextValHash, ConsensusHash: tmhash.Sum([]byte("consensus_hash")), AppHash: chain.CurrentHeader.AppHash, LastResultsHash: tmhash.Sum([]byte("last_results_hash")), EvidenceHash: tmhash.Sum([]byte("evidence_hash")), ProposerAddress: tmValSet.Proposer.Address, //nolint:staticcheck } + hhash := tmHeader.Hash() blockID := MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) voteSet := tmtypes.NewVoteSet(chainID, blockHeight, 1, tmproto.PrecommitType, tmValSet) - commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signers, timestamp) + // MakeCommit expects a signer array in the same order as the validator array. + // Thus we iterate over the ordered validator set and construct a signer array + // from the signer map in the same order. + signerArr := make([]tmtypes.PrivValidator, len(tmValSet.Validators)) + for i, v := range tmValSet.Validators { + signerArr[i] = signers[v.Address.String()] + } + + commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signerArr, timestamp) require.NoError(chain.t, err) signedHeader := &tmproto.SignedHeader{ @@ -430,15 +502,11 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, } valSet, err = tmValSet.ToProto() - if err != nil { - panic(err) - } + require.NoError(chain.t, err) if tmTrustedVals != nil { trustedVals, err = tmTrustedVals.ToProto() - if err != nil { - panic(err) - } + require.NoError(chain.t, err) } // The trusted fields may be nil. They may be filled before relaying messages to a client. @@ -462,29 +530,9 @@ func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.Bl } } -// CreateSortedSignerArray takes two PrivValidators, and the corresponding Validator structs -// (including voting power). It returns a signer array of PrivValidators that matches the -// sorting of ValidatorSet. -// The sorting is first by .VotingPower (descending), with secondary index of .Address (ascending). -func CreateSortedSignerArray(altPrivVal, suitePrivVal tmtypes.PrivValidator, - altVal, suiteVal *tmtypes.Validator, -) []tmtypes.PrivValidator { - switch { - case altVal.VotingPower > suiteVal.VotingPower: - return []tmtypes.PrivValidator{altPrivVal, suitePrivVal} - case altVal.VotingPower < suiteVal.VotingPower: - return []tmtypes.PrivValidator{suitePrivVal, altPrivVal} - default: - if bytes.Compare(altVal.Address, suiteVal.Address) == -1 { - return []tmtypes.PrivValidator{altPrivVal, suitePrivVal} - } - return []tmtypes.PrivValidator{suitePrivVal, altPrivVal} - } -} - // CreatePortCapability binds and claims a capability for the given portID if it does not // already exist. This function will fail testing on any resulting error. -// NOTE: only creation of a capbility for a transfer or mock port is supported +// NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.ScopedKeeper, portID string) { // check if the portId is already binded, if not bind it @@ -499,8 +547,6 @@ func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.Scope require.NoError(chain.t, err) } - chain.App.Commit() - chain.NextBlock() } @@ -527,8 +573,6 @@ func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.Sc require.NoError(chain.t, err) } - chain.App.Commit() - chain.NextBlock() } diff --git a/x/wasm/ibctesting/coordinator.go b/x/wasm/ibctesting/coordinator.go index ed85a4e786..9ceadc0a76 100644 --- a/x/wasm/ibctesting/coordinator.go +++ b/x/wasm/ibctesting/coordinator.go @@ -6,9 +6,9 @@ import ( "testing" "time" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v3/testing" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v4/testing" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -191,7 +191,6 @@ func GetChainID(index int) string { // CONTRACT: the passed in list of indexes must not contain duplicates func (coord *Coordinator) CommitBlock(chains ...*TestChain) { for _, chain := range chains { - chain.App.Commit() chain.NextBlock() } coord.IncrementTime() @@ -201,7 +200,6 @@ func (coord *Coordinator) CommitBlock(chains ...*TestChain) { func (coord *Coordinator) CommitNBlocks(chain *TestChain, n uint64) { for i := uint64(0); i < n; i++ { chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) - chain.App.Commit() chain.NextBlock() coord.IncrementTime() } @@ -254,48 +252,27 @@ func (coord *Coordinator) ChanOpenInitOnBothChains(path *Path) error { return nil } -// from A to B +// RelayAndAckPendingPackets sends pending packages from path.EndpointA to the counterparty chain and acks func (coord *Coordinator) RelayAndAckPendingPackets(path *Path) error { // get all the packet to relay src->dest src := path.EndpointA - dest := path.EndpointB - toSend := src.Chain.PendingSendPackets - coord.t.Logf("Relay %d Packets A->B\n", len(toSend)) - - // send this to the other side - coord.IncrementTime() - coord.CommitBlock(src.Chain) - err := dest.UpdateClient() - if err != nil { - return err - } - for _, packet := range toSend { - err = dest.RecvPacket(packet) + coord.t.Logf("Relay: %d Packets A->B, %d Packets B->A\n", len(src.Chain.PendingSendPackets), len(path.EndpointB.Chain.PendingSendPackets)) + for i, v := range src.Chain.PendingSendPackets { + err := path.RelayPacket(v, nil) if err != nil { return err } + src.Chain.PendingSendPackets = append(src.Chain.PendingSendPackets[0:i], src.Chain.PendingSendPackets[i+1:]...) } - src.Chain.PendingSendPackets = nil - - // get all the acks to relay dest->src - toAck := dest.Chain.PendingAckPackets - // TODO: assert >= len(toSend)? - coord.t.Logf("Ack %d Packets B->A\n", len(toAck)) - // send the ack back from dest -> src - coord.IncrementTime() - coord.CommitBlock(dest.Chain) - err = src.UpdateClient() - if err != nil { - return err - } - for _, ack := range toAck { - err = src.AcknowledgePacket(ack.Packet, ack.Ack) + src = path.EndpointB + for i, v := range src.Chain.PendingSendPackets { + err := path.RelayPacket(v, nil) if err != nil { return err } + src.Chain.PendingSendPackets = append(src.Chain.PendingSendPackets[0:i], src.Chain.PendingSendPackets[i+1:]...) } - dest.Chain.PendingAckPackets = nil return nil } @@ -325,7 +302,6 @@ func (coord *Coordinator) TimeoutPendingPackets(path *Path) error { } } src.Chain.PendingSendPackets = nil - dest.Chain.PendingAckPackets = nil return nil } diff --git a/x/wasm/ibctesting/endpoint.go b/x/wasm/ibctesting/endpoint.go index 9d62ce7f62..e56c5d06ef 100644 --- a/x/wasm/ibctesting/endpoint.go +++ b/x/wasm/ibctesting/endpoint.go @@ -3,18 +3,16 @@ package ibctesting import ( "fmt" - ibctesting "github.com/cosmos/ibc-go/v3/testing" - - // sdk "github.com/cosmos/cosmos-sdk/types" + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" "github.com/stretchr/testify/require" - - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v3/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" - "github.com/cosmos/ibc-go/v3/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types" ) // Endpoint is a which represents a channel endpoint and its associated @@ -69,7 +67,7 @@ func (endpoint *Endpoint) QueryProof(key []byte) ([]byte, clienttypes.Height) { } // QueryProofAtHeight queries proof associated with this endpoint using the proof height -// providied +// provided func (endpoint *Endpoint) QueryProofAtHeight(key []byte, height uint64) ([]byte, clienttypes.Height) { // query proof on the counterparty using the latest height of the IBC client return endpoint.Chain.QueryProofAtHeight(key, int64(height)) @@ -184,8 +182,7 @@ func (endpoint *Endpoint) ConnOpenTry() error { counterpartyClient, proofClient, proofConsensus, consensusHeight, proofInit, proofHeight := endpoint.QueryConnectionHandshakeProof() msg := connectiontypes.NewMsgConnectionOpenTry( - "", endpoint.ClientID, // does not support handshake continuation - endpoint.Counterparty.ConnectionID, endpoint.Counterparty.ClientID, + endpoint.ClientID, endpoint.Counterparty.ConnectionID, endpoint.Counterparty.ClientID, counterpartyClient, endpoint.Counterparty.Chain.GetPrefix(), []*connectiontypes.Version{ibctesting.ConnectionVersion}, endpoint.ConnectionConfig.DelayPeriod, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, @@ -284,6 +281,10 @@ func (endpoint *Endpoint) ChanOpenInit() error { endpoint.ChannelID, err = ibctesting.ParseChannelIDFromEvents(res.GetEvents()) require.NoError(endpoint.Chain.t, err) + // update version to selected app version + // NOTE: this update must be performed after SendMsgs() + endpoint.ChannelConfig.Version = endpoint.GetChannel().Version + return nil } @@ -297,7 +298,7 @@ func (endpoint *Endpoint) ChanOpenTry() error { proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) msg := channeltypes.NewMsgChannelOpenTry( - endpoint.ChannelConfig.PortID, "", // does not support handshake continuation + endpoint.ChannelConfig.PortID, endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order, []string{endpoint.ConnectionID}, endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID, endpoint.Counterparty.ChannelConfig.Version, proof, height, @@ -313,6 +314,10 @@ func (endpoint *Endpoint) ChanOpenTry() error { require.NoError(endpoint.Chain.t, err) } + // update version to selected app version + // NOTE: this update must be performed after the endpoint channelID is set + endpoint.ChannelConfig.Version = endpoint.GetChannel().Version + return nil } @@ -331,7 +336,12 @@ func (endpoint *Endpoint) ChanOpenAck() error { proof, height, endpoint.Chain.SenderAccount.GetAddress().String(), ) - return endpoint.Chain.sendMsgs(msg) + if err := endpoint.Chain.sendMsgs(msg); err != nil { + return err + } + + endpoint.ChannelConfig.Version = endpoint.GetChannel().Version + return nil } // ChanOpenConfirm will construct and execute a MsgChannelOpenConfirm on the associated endpoint. @@ -395,6 +405,17 @@ func (endpoint *Endpoint) SendPacket(packet exported.PacketI) error { // RecvPacket receives a packet on the associated endpoint. // The counterparty client is updated. func (endpoint *Endpoint) RecvPacket(packet channeltypes.Packet) error { + _, err := endpoint.RecvPacketWithResult(packet) + if err != nil { + return err + } + + return nil +} + +// RecvPacketWithResult receives a packet on the associated endpoint and the result +// of the transaction is returned. The counterparty client is updated. +func (endpoint *Endpoint) RecvPacketWithResult(packet channeltypes.Packet) (*sdk.Result, error) { // get proof of packet commitment on source packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) proof, proofHeight := endpoint.Counterparty.Chain.QueryProof(packetKey) @@ -402,11 +423,16 @@ func (endpoint *Endpoint) RecvPacket(packet channeltypes.Packet) error { recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, endpoint.Chain.SenderAccount.GetAddress().String()) // receive on counterparty and update source client - if err := endpoint.Chain.sendMsgs(recvMsg); err != nil { - return err + res, err := endpoint.Chain.SendMsgs(recvMsg) + if err != nil { + return nil, err } - return endpoint.Counterparty.UpdateClient() + if err := endpoint.Counterparty.UpdateClient(); err != nil { + return nil, err + } + + return res, nil } // WriteAcknowledgement writes an acknowledgement on the channel associated with the endpoint. @@ -463,6 +489,36 @@ func (endpoint *Endpoint) TimeoutPacket(packet channeltypes.Packet) error { return endpoint.Chain.sendMsgs(timeoutMsg) } +// TimeoutOnClose sends a MsgTimeoutOnClose to the channel associated with the endpoint. +func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { + // get proof for timeout based on channel order + var packetKey []byte + + switch endpoint.ChannelConfig.Order { + case channeltypes.ORDERED: + packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) + case channeltypes.UNORDERED: + packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + default: + return fmt.Errorf("unsupported order type %s", endpoint.ChannelConfig.Order) + } + + proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey) + + channelKey := host.ChannelKey(packet.GetDestPort(), packet.GetDestChannel()) + proofClosed, _ := endpoint.Counterparty.QueryProof(channelKey) + + nextSeqRecv, found := endpoint.Counterparty.Chain.App.IBCKeeper.ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) + require.True(endpoint.Chain.t, found) + + timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnClose( + packet, nextSeqRecv, + proof, proofClosed, proofHeight, endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(timeoutOnCloseMsg) +} + // SetChannelClosed sets a channel state to CLOSED. func (endpoint *Endpoint) SetChannelClosed() error { channel := endpoint.GetChannel() diff --git a/x/wasm/ibctesting/event_utils.go b/x/wasm/ibctesting/event_utils.go index 6463515ffa..0933dadd3f 100644 --- a/x/wasm/ibctesting/event_utils.go +++ b/x/wasm/ibctesting/event_utils.go @@ -1,18 +1,22 @@ package ibctesting import ( + "encoding/hex" + "fmt" "strconv" "strings" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" abci "github.com/tendermint/tendermint/abci/types" ) func getSendPackets(evts []abci.Event) []channeltypes.Packet { var res []channeltypes.Packet for _, evt := range evts { - if evt.Type == "send_packet" { + if evt.Type == channeltypes.EventTypeSendPacket { packet := parsePacketFromEvent(evt) res = append(res, packet) } @@ -20,21 +24,6 @@ func getSendPackets(evts []abci.Event) []channeltypes.Packet { return res } -func getAckPackets(evts []abci.Event) []PacketAck { - var res []PacketAck - for _, evt := range evts { - if evt.Type == "write_acknowledgement" { - packet := parsePacketFromEvent(evt) - ack := PacketAck{ - Packet: packet, - Ack: []byte(getField(evt, "packet_ack")), - } - res = append(res, ack) - } - } - return res -} - // Used for various debug statements above when needed... do not remove // func showEvent(evt abci.Event) { // fmt.Printf("evt.Type: %s\n", evt.Type) @@ -45,17 +34,29 @@ func getAckPackets(evts []abci.Event) []PacketAck { func parsePacketFromEvent(evt abci.Event) channeltypes.Packet { return channeltypes.Packet{ - Sequence: getUintField(evt, "packet_sequence"), - SourcePort: getField(evt, "packet_src_port"), - SourceChannel: getField(evt, "packet_src_channel"), - DestinationPort: getField(evt, "packet_dst_port"), - DestinationChannel: getField(evt, "packet_dst_channel"), - Data: []byte(getField(evt, "packet_data")), - TimeoutHeight: parseTimeoutHeight(getField(evt, "packet_timeout_height")), - TimeoutTimestamp: getUintField(evt, "packet_timeout_timestamp"), + Sequence: getUintField(evt, channeltypes.AttributeKeySequence), + SourcePort: getField(evt, channeltypes.AttributeKeySrcPort), + SourceChannel: getField(evt, channeltypes.AttributeKeySrcChannel), + DestinationPort: getField(evt, channeltypes.AttributeKeyDstPort), + DestinationChannel: getField(evt, channeltypes.AttributeKeyDstChannel), + Data: getHexField(evt, channeltypes.AttributeKeyDataHex), + TimeoutHeight: parseTimeoutHeight(getField(evt, channeltypes.AttributeKeyTimeoutHeight)), + TimeoutTimestamp: getUintField(evt, channeltypes.AttributeKeyTimeoutTimestamp), } } +func getHexField(evt abci.Event, key string) []byte { + got := getField(evt, key) + if got == "" { + return nil + } + bz, err := hex.DecodeString(got) + if err != nil { + panic(err) + } + return bz +} + // return the value for the attribute with the given name func getField(evt abci.Event, key string) string { for _, attr := range evt.Attributes { @@ -89,3 +90,29 @@ func parseTimeoutHeight(raw string) clienttypes.Height { RevisionHeight: toUint64(chunks[1]), } } + +func ParsePortIDFromEvents(events sdk.Events) (string, error) { + for _, ev := range events { + if ev.Type == channeltypes.EventTypeChannelOpenInit || ev.Type == channeltypes.EventTypeChannelOpenTry { + for _, attr := range ev.Attributes { + if string(attr.Key) == channeltypes.AttributeKeyPortID { + return string(attr.Value), nil + } + } + } + } + return "", fmt.Errorf("port id event attribute not found") +} + +func ParseChannelVersionFromEvents(events sdk.Events) (string, error) { + for _, ev := range events { + if ev.Type == channeltypes.EventTypeChannelOpenInit || ev.Type == channeltypes.EventTypeChannelOpenTry { + for _, attr := range ev.Attributes { + if string(attr.Key) == channeltypes.AttributeVersion { + return string(attr.Value), nil + } + } + } + } + return "", fmt.Errorf("version event attribute not found") +} diff --git a/x/wasm/ibctesting/path.go b/x/wasm/ibctesting/path.go index 15912bd400..5e861325f0 100644 --- a/x/wasm/ibctesting/path.go +++ b/x/wasm/ibctesting/path.go @@ -5,7 +5,8 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" ) // Path contains two endpoints representing two chains connected over IBC @@ -48,15 +49,21 @@ func (path *Path) RelayPacket(packet channeltypes.Packet, ack []byte) error { return err } - if err := path.EndpointB.RecvPacket(packet); err != nil { + res, err := path.EndpointB.RecvPacketWithResult(packet) + if err != nil { + return err + } + + ack, err := ibctesting.ParseAckFromEvents(res.GetEvents()) + if err != nil { return err } if err := path.EndpointA.AcknowledgePacket(packet, ack); err != nil { return err } - return nil + return nil } pc = path.EndpointB.Chain.App.IBCKeeper.ChannelKeeper.GetPacketCommitment(path.EndpointB.Chain.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) @@ -67,9 +74,16 @@ func (path *Path) RelayPacket(packet channeltypes.Packet, ack []byte) error { return err } - if err := path.EndpointA.RecvPacket(packet); err != nil { + res, err := path.EndpointA.RecvPacketWithResult(packet) + if err != nil { return err } + + ack, err := ibctesting.ParseAckFromEvents(res.GetEvents()) + if err != nil { + return err + } + if err := path.EndpointB.AcknowledgePacket(packet, ack); err != nil { return err } diff --git a/x/wasm/ibctesting/wasm.go b/x/wasm/ibctesting/wasm.go index 293a9f6926..0546f477eb 100644 --- a/x/wasm/ibctesting/wasm.go +++ b/x/wasm/ibctesting/wasm.go @@ -8,7 +8,7 @@ import ( "os" "strings" - ibctesting "github.com/cosmos/ibc-go/v3/testing" + ibctesting "github.com/cosmos/ibc-go/v4/testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/protobuf/proto" //nolint diff --git a/x/wasm/keeper/handler_plugin.go b/x/wasm/keeper/handler_plugin.go index c138e5ed00..c23a09b020 100644 --- a/x/wasm/keeper/handler_plugin.go +++ b/x/wasm/keeper/handler_plugin.go @@ -9,8 +9,8 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v4/modules/core/24-host" "github.com/CosmWasm/wasmd/x/wasm/types" ) diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index 90734c1dc2..3c4712d99b 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -12,9 +12,9 @@ import ( distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/CosmWasm/wasmd/x/wasm/types" ) diff --git a/x/wasm/keeper/handler_plugin_encoders_test.go b/x/wasm/keeper/handler_plugin_encoders_test.go index e1c49c591c..7f56776e48 100644 --- a/x/wasm/keeper/handler_plugin_encoders_test.go +++ b/x/wasm/keeper/handler_plugin_encoders_test.go @@ -5,9 +5,9 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" diff --git a/x/wasm/keeper/handler_plugin_test.go b/x/wasm/keeper/handler_plugin_test.go index 557478fb44..2a41d8a997 100644 --- a/x/wasm/keeper/handler_plugin_test.go +++ b/x/wasm/keeper/handler_plugin_test.go @@ -11,9 +11,9 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/x/wasm/keeper/ibc.go b/x/wasm/keeper/ibc.go index f6f928df62..3857b5f272 100644 --- a/x/wasm/keeper/ibc.go +++ b/x/wasm/keeper/ibc.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - host "github.com/cosmos/ibc-go/v3/modules/core/24-host" + host "github.com/cosmos/ibc-go/v4/modules/core/24-host" "github.com/CosmWasm/wasmd/x/wasm/types" ) diff --git a/x/wasm/keeper/query_plugins.go b/x/wasm/keeper/query_plugins.go index 7196860d90..c98afda693 100644 --- a/x/wasm/keeper/query_plugins.go +++ b/x/wasm/keeper/query_plugins.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" abci "github.com/tendermint/tendermint/abci/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/CosmWasm/wasmd/x/wasm/types" diff --git a/x/wasm/keeper/query_plugins_test.go b/x/wasm/keeper/query_plugins_test.go index 1c0fa231c9..0572cd28c3 100644 --- a/x/wasm/keeper/query_plugins_test.go +++ b/x/wasm/keeper/query_plugins_test.go @@ -18,7 +18,7 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/x/wasm/keeper/relay.go b/x/wasm/keeper/relay.go index 5a74ebe2ca..7c3f0b902c 100644 --- a/x/wasm/keeper/relay.go +++ b/x/wasm/keeper/relay.go @@ -24,8 +24,6 @@ func (k Keeper) OnOpenChannel( msg wasmvmtypes.IBCChannelOpenMsg, ) (string, error) { defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "ibc-open-channel") - version := "" - _, codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr) if err != nil { return "", err @@ -40,12 +38,10 @@ func (k Keeper) OnOpenChannel( if execErr != nil { return "", sdkerrors.Wrap(types.ErrExecuteFailed, execErr.Error()) } - if res != nil { - version = res.Version + return res.Version, nil } - - return version, nil + return "", nil } // OnConnectChannel calls the contract to let it know the IBC channel was established. diff --git a/x/wasm/keeper/snapshotter_integration_test.go b/x/wasm/keeper/snapshotter_integration_test.go index f100a1698c..432d56c79d 100644 --- a/x/wasm/keeper/snapshotter_integration_test.go +++ b/x/wasm/keeper/snapshotter_integration_test.go @@ -118,7 +118,7 @@ func newWasmExampleApp(t *testing.T) (*app.WasmApp, sdk.AccAddress) { } validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - wasmApp := app.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, nil, balance) + wasmApp := app.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, "testing", nil, balance) return wasmApp, senderAddr } diff --git a/x/wasm/keeper/test_common.go b/x/wasm/keeper/test_common.go index 721a327826..8ee5261ee3 100644 --- a/x/wasm/keeper/test_common.go +++ b/x/wasm/keeper/test_common.go @@ -56,11 +56,11 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v3/modules/apps/transfer" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v3/modules/core" - ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" - ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + "github.com/cosmos/ibc-go/v4/modules/apps/transfer" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v4/modules/core" + ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" @@ -170,18 +170,19 @@ func (f *TestFaucet) NewFundedRandomAccount(ctx sdk.Context, amounts ...sdk.Coin } type TestKeepers struct { - AccountKeeper authkeeper.AccountKeeper - StakingKeeper stakingkeeper.Keeper - DistKeeper distributionkeeper.Keeper - BankKeeper bankkeeper.Keeper - GovKeeper govkeeper.Keeper - ContractKeeper types.ContractOpsKeeper - WasmKeeper *Keeper - IBCKeeper *ibckeeper.Keeper - Router *baseapp.Router - EncodingConfig wasmappparams.EncodingConfig - Faucet *TestFaucet - MultiStore sdk.CommitMultiStore + AccountKeeper authkeeper.AccountKeeper + StakingKeeper stakingkeeper.Keeper + DistKeeper distributionkeeper.Keeper + BankKeeper bankkeeper.Keeper + GovKeeper govkeeper.Keeper + ContractKeeper types.ContractOpsKeeper + WasmKeeper *Keeper + IBCKeeper *ibckeeper.Keeper + Router *baseapp.Router + EncodingConfig wasmappparams.EncodingConfig + Faucet *TestFaucet + MultiStore sdk.CommitMultiStore + ScopedWasmKeeper capabilitykeeper.ScopedKeeper } // CreateDefaultTestInput common settings for CreateTestInput @@ -426,18 +427,19 @@ func createTestInput( govKeeper.SetTallyParams(ctx, govtypes.DefaultTallyParams()) keepers := TestKeepers{ - AccountKeeper: accountKeeper, - StakingKeeper: stakingKeeper, - DistKeeper: distKeeper, - ContractKeeper: contractKeeper, - WasmKeeper: &keeper, - BankKeeper: bankKeeper, - GovKeeper: govKeeper, - IBCKeeper: ibcKeeper, - Router: router, - EncodingConfig: encodingConfig, - Faucet: faucet, - MultiStore: ms, + AccountKeeper: accountKeeper, + StakingKeeper: stakingKeeper, + DistKeeper: distKeeper, + ContractKeeper: contractKeeper, + WasmKeeper: &keeper, + BankKeeper: bankKeeper, + GovKeeper: govKeeper, + IBCKeeper: ibcKeeper, + Router: router, + EncodingConfig: encodingConfig, + Faucet: faucet, + MultiStore: ms, + ScopedWasmKeeper: scopedWasmKeeper, } return ctx, keepers } diff --git a/x/wasm/keeper/wasmtesting/mock_engine.go b/x/wasm/keeper/wasmtesting/mock_engine.go index ebf7dbcf19..10c7fdfed2 100644 --- a/x/wasm/keeper/wasmtesting/mock_engine.go +++ b/x/wasm/keeper/wasmtesting/mock_engine.go @@ -346,3 +346,56 @@ func HasIBCAnalyzeFn(wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) { func WithoutIBCAnalyzeFn(wasmvm.Checksum) (*wasmvmtypes.AnalysisReport, error) { return &wasmvmtypes.AnalysisReport{}, nil } + +var _ IBCContractCallbacks = &MockIBCContractCallbacks{} + +type MockIBCContractCallbacks struct { + IBCChannelOpenFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) + IBCChannelConnectFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCChannelCloseFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketReceiveFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) + IBCPacketAckFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) + IBCPacketTimeoutFn func(codeID wasmvm.Checksum, env wasmvmtypes.Env, msg wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) +} + +func (m MockIBCContractCallbacks) IBCChannelOpen(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannelOpenMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBC3ChannelOpenResponse, uint64, error) { + if m.IBCChannelOpenFn == nil { + panic("not expected to be called") + } + return m.IBCChannelOpenFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + +func (m MockIBCContractCallbacks) IBCChannelConnect(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannelConnectMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { + if m.IBCChannelConnectFn == nil { + panic("not expected to be called") + } + return m.IBCChannelConnectFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + +func (m MockIBCContractCallbacks) IBCChannelClose(codeID wasmvm.Checksum, env wasmvmtypes.Env, channel wasmvmtypes.IBCChannelCloseMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { + if m.IBCChannelCloseFn == nil { + panic("not expected to be called") + } + return m.IBCChannelCloseFn(codeID, env, channel, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + +func (m MockIBCContractCallbacks) IBCPacketReceive(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacketReceiveMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCReceiveResult, uint64, error) { + if m.IBCPacketReceiveFn == nil { + panic("not expected to be called") + } + return m.IBCPacketReceiveFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + +func (m MockIBCContractCallbacks) IBCPacketAck(codeID wasmvm.Checksum, env wasmvmtypes.Env, ack wasmvmtypes.IBCPacketAckMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { + if m.IBCPacketAckFn == nil { + panic("not expected to be called") + } + return m.IBCPacketAckFn(codeID, env, ack, store, goapi, querier, gasMeter, gasLimit, deserCost) +} + +func (m MockIBCContractCallbacks) IBCPacketTimeout(codeID wasmvm.Checksum, env wasmvmtypes.Env, packet wasmvmtypes.IBCPacketTimeoutMsg, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.IBCBasicResponse, uint64, error) { + if m.IBCPacketTimeoutFn == nil { + panic("not expected to be called") + } + return m.IBCPacketTimeoutFn(codeID, env, packet, store, goapi, querier, gasMeter, gasLimit, deserCost) +} diff --git a/x/wasm/keeper/wasmtesting/mock_keepers.go b/x/wasm/keeper/wasmtesting/mock_keepers.go index 4295b24ef0..5977db1c80 100644 --- a/x/wasm/keeper/wasmtesting/mock_keepers.go +++ b/x/wasm/keeper/wasmtesting/mock_keepers.go @@ -3,8 +3,8 @@ package wasmtesting import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" "github.com/CosmWasm/wasmd/x/wasm/types" ) diff --git a/x/wasm/relay_pingpong_test.go b/x/wasm/relay_pingpong_test.go index 8dfa403e82..a36cdce6ab 100644 --- a/x/wasm/relay_pingpong_test.go +++ b/x/wasm/relay_pingpong_test.go @@ -5,15 +5,15 @@ import ( "fmt" "testing" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - ibctesting "github.com/cosmos/ibc-go/v3/testing" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" wasmvm "github.com/CosmWasm/wasmvm" wasmvmtypes "github.com/CosmWasm/wasmvm/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -108,11 +108,6 @@ func TestPinPong(t *testing.T) { require.Len(t, chainA.PendingSendPackets, 1) err := coordinator.RelayAndAckPendingPackets(path) require.NoError(t, err) - - // switch side - require.Len(t, chainB.PendingSendPackets, 1) - err = coordinator.RelayAndAckPendingPackets(path.Invert()) - require.NoError(t, err) } // then receive/response state is as expected diff --git a/x/wasm/relay_test.go b/x/wasm/relay_test.go index 4e72bd84f6..df34534fbc 100644 --- a/x/wasm/relay_test.go +++ b/x/wasm/relay_test.go @@ -10,10 +10,10 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v3/testing" + ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v4/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/x/wasm/types/expected_keepers.go b/x/wasm/types/expected_keepers.go index da00047aa4..57cc4073f5 100644 --- a/x/wasm/types/expected_keepers.go +++ b/x/wasm/types/expected_keepers.go @@ -8,9 +8,9 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" + connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" ) // BankViewKeeper defines a subset of methods implemented by the cosmos-sdk bank keeper From a589fe91e8ddba29bdeff84bd40c75deceb688a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orkun=20K=C3=BCl=C3=A7e?= Date: Tue, 22 Nov 2022 17:14:38 +0300 Subject: [PATCH 032/294] feat: Provide source, builder and codehash information in store code proposal message (#1072) * Provide source, builder and codehash information in store code proposal message * Make linter happy * Update x/wasm/simulation/proposals.go Co-authored-by: Alexander Peters * Update x/wasm/client/cli/gov_tx.go * Update x/wasm/client/cli/gov_tx.go * Bump github.com/cosmos/gogoproto from 1.4.2 to 1.4.3 Bumps [github.com/cosmos/gogoproto](https://github.com/cosmos/gogoproto) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/cosmos/gogoproto/releases) - [Changelog](https://github.com/cosmos/gogoproto/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/gogoproto/compare/v1.4.2...v1.4.3) --- updated-dependencies: - dependency-name: github.com/cosmos/gogoproto dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update authz grant examples * Enable larger wasm bytecode upload for gov proposals (#1095) * Enable larger wasm bytecode upload for gov proposals * Set max proposal wasm code size to 3MB * Bump SDK to v0.45.11 * Fix license head * Fix README header * Bump version go to 1.19 (#1044) * bump go 1.19 * add change log * correct change log * Provide source, builder and codehash information in store code proposal message * Implement source, builder, code_info for StoreAndInstantiateProposal * Apply review recommendations * Make linter happy * Fix tests * Formatting only Signed-off-by: dependabot[bot] Co-authored-by: Alexander Peters Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Giancarlos Salas Co-authored-by: pinosu <95283998+pinosu@users.noreply.github.com> Co-authored-by: GNaD13 <89174180+GNaD13@users.noreply.github.com> --- docs/proto/proto-docs.md | 6 + go.mod | 2 + go.sum | 3 + proto/cosmwasm/wasm/v1/proposal.proto | 16 + x/wasm/client/cli/gov_tx.go | 74 +++- x/wasm/client/cli/gov_tx_test.go | 61 +++ x/wasm/client/cli/tx.go | 3 + x/wasm/client/proposal_handler_test.go | 93 ++++- x/wasm/client/rest/gov.go | 11 + x/wasm/keeper/proposal_handler.go | 14 +- x/wasm/keeper/proposal_integration_test.go | 7 + x/wasm/simulation/proposals.go | 3 + x/wasm/types/proposal.go | 42 ++- x/wasm/types/proposal.pb.go | 415 ++++++++++++++++++--- x/wasm/types/proposal_test.go | 56 +++ x/wasm/types/test_fixtures.go | 24 +- x/wasm/types/validation.go | 28 ++ 17 files changed, 786 insertions(+), 72 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index ef464a9f38..abd59632e5 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -1004,6 +1004,9 @@ and instantiate the contract. | `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | | `msg` | [bytes](#bytes) | | Msg json encoded message to be passed to the contract on instantiation | | `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `source` | [string](#string) | | Source is the URL where the code is hosted | +| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | +| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | @@ -1024,6 +1027,9 @@ StoreCodeProposal gov proposal content type to submit WASM code to the system | `wasm_byte_code` | [bytes](#bytes) | | WASMByteCode can be raw or gzip compressed | | `instantiate_permission` | [AccessConfig](#cosmwasm.wasm.v1.AccessConfig) | | InstantiatePermission to apply on contract creation, optional | | `unpin_code` | [bool](#bool) | | UnpinCode code on upload, optional | +| `source` | [string](#string) | | Source is the URL where the code is hosted | +| `builder` | [string](#string) | | Builder is the docker image used to build the code deterministically, used for smart contract verification | +| `code_hash` | [bytes](#bytes) | | CodeHash is the SHA256 sum of the code outputted by builder, used for smart contract verification | diff --git a/go.mod b/go.mod index f7d483c3b7..9140e8e461 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/cosmos/iavl v0.19.4 github.com/cosmos/ibc-go/v4 v4.2.0 github.com/cosmos/interchain-accounts v0.2.4 + github.com/docker/distribution v2.8.1+incompatible github.com/dvsekhvalnov/jose2go v1.5.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 @@ -95,6 +96,7 @@ require ( github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect diff --git a/go.sum b/go.sum index a2fe53b4a0..c7b2fad923 100644 --- a/go.sum +++ b/go.sum @@ -212,6 +212,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -587,6 +589,7 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= diff --git a/proto/cosmwasm/wasm/v1/proposal.proto b/proto/cosmwasm/wasm/v1/proposal.proto index a4e57b7dd9..b8a143b672 100644 --- a/proto/cosmwasm/wasm/v1/proposal.proto +++ b/proto/cosmwasm/wasm/v1/proposal.proto @@ -26,6 +26,14 @@ message StoreCodeProposal { AccessConfig instantiate_permission = 7; // UnpinCode code on upload, optional bool unpin_code = 8; + // Source is the URL where the code is hosted + string source = 9; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 10; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 11; } // InstantiateContractProposal gov proposal content type to instantiate a @@ -199,4 +207,12 @@ message StoreAndInstantiateContractProposal { (gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; + // Source is the URL where the code is hosted + string source = 11; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 12; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 13; } diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 131ccda57d..3c8a7b9f3a 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -1,10 +1,15 @@ package cli import ( + "bytes" + "crypto/sha256" "fmt" + "net/url" "strconv" "strings" + "github.com/docker/distribution/reference" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,13 +18,14 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/pkg/errors" "github.com/spf13/cobra" + flag "github.com/spf13/pflag" "github.com/CosmWasm/wasmd/x/wasm/types" ) func ProposalStoreCodeCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "wasm-store [wasm file] --title [text] --description [text] --run-as [address]", + Use: "wasm-store [wasm file] --title [text] --description [text] --run-as [address] --unpin-code [unpin_code] --source [source] --builder [builder] --code-hash [code_hash]", Short: "Submit a wasm binary proposal", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -45,6 +51,10 @@ func ProposalStoreCodeCmd() *cobra.Command { return err } + source, builder, codeHash, err := parseVerificationFlags(src.WASMByteCode, cmd.Flags()) + if err != nil { + return err + } content := types.StoreCodeProposal{ Title: proposalTitle, Description: proposalDescr, @@ -52,6 +62,9 @@ func ProposalStoreCodeCmd() *cobra.Command { WASMByteCode: src.WASMByteCode, InstantiatePermission: src.InstantiatePermission, UnpinCode: unpinCode, + Source: source, + Builder: builder, + CodeHash: codeHash, } msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress()) @@ -73,6 +86,9 @@ func ProposalStoreCodeCmd() *cobra.Command { cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional") cmd.Flags().Bool(flagUnpinCode, false, "Unpin code on upload, optional") cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") + cmd.Flags().String(flagSource, "", "Code Source URL is a valid absolute HTTPS URI to the contract's source code,") + cmd.Flags().String(flagBuilder, "", "Builder is a valid docker image name with tag, such as \"cosmwasm/workspace-optimizer:0.12.9\"") + cmd.Flags().BytesHex(flagCodeHash, nil, "CodeHash is the sha256 hash of the wasm code") // proposal flags cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") @@ -81,6 +97,48 @@ func ProposalStoreCodeCmd() *cobra.Command { return cmd } +func parseVerificationFlags(wasm []byte, flags *flag.FlagSet) (string, string, []byte, error) { + source, err := flags.GetString(flagSource) + if err != nil { + return "", "", nil, fmt.Errorf("source: %s", err) + } + builder, err := flags.GetString(flagBuilder) + if err != nil { + return "", "", nil, fmt.Errorf("builder: %s", err) + } + codeHash, err := flags.GetBytesHex(flagCodeHash) + if err != nil { + return "", "", nil, fmt.Errorf("codeHash: %s", err) + } + + // if any set require others to be set + if len(source) != 0 || len(builder) != 0 || len(codeHash) != 0 { + if source == "" { + return "", "", nil, fmt.Errorf("source is required") + } + if _, err = url.ParseRequestURI(source); err != nil { + return "", "", nil, fmt.Errorf("source: %s", err) + } + if builder == "" { + return "", "", nil, fmt.Errorf("builder is required") + } + if _, err := reference.ParseDockerRef(builder); err != nil { + return "", "", nil, fmt.Errorf("builder: %s", err) + } + if len(codeHash) == 0 { + return "", "", nil, fmt.Errorf("code hash is required") + } + // wasm is unzipped in parseStoreCodeArgs + // checksum generation will be decoupled here + // reference https://github.com/CosmWasm/wasmvm/issues/359 + checksum := sha256.Sum256(wasm) + if !bytes.Equal(checksum[:], codeHash) { + return "", "", nil, fmt.Errorf("code-hash mismatch: %X, checksum: %X", codeHash, checksum) + } + } + return source, builder, codeHash, nil +} + func ProposalInstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ Use: "instantiate-contract [code_id_int64] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address] --admin [address,optional] --amount [coins,optional]", @@ -143,7 +201,8 @@ func ProposalInstantiateContractCmd() *cobra.Command { func ProposalStoreAndInstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "store-instantiate [wasm file] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address] --admin [address,optional] --amount [coins,optional]", + Use: "store-instantiate [wasm file] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address]" + + "--unpin-code [unpin_code,optional] --source [source,optional] --builder [builder,optional] --code-hash [code_hash,optional] --admin [address,optional] --amount [coins,optional]", Short: "Submit and instantiate a wasm contract proposal", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { @@ -169,6 +228,11 @@ func ProposalStoreAndInstantiateContractCmd() *cobra.Command { return err } + source, builder, codeHash, err := parseVerificationFlags(src.WASMByteCode, cmd.Flags()) + if err != nil { + return err + } + amountStr, err := cmd.Flags().GetString(flagAmount) if err != nil { return fmt.Errorf("amount: %s", err) @@ -208,6 +272,9 @@ func ProposalStoreAndInstantiateContractCmd() *cobra.Command { WASMByteCode: src.WASMByteCode, InstantiatePermission: src.InstantiatePermission, UnpinCode: unpinCode, + Source: source, + Builder: builder, + CodeHash: codeHash, Admin: adminStr, Label: label, Msg: []byte(args[1]), @@ -232,6 +299,9 @@ func ProposalStoreAndInstantiateContractCmd() *cobra.Command { cmd.Flags().String(flagInstantiateNobody, "", "Nobody except the governance process can instantiate a contract from the code, optional") cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional") cmd.Flags().Bool(flagUnpinCode, false, "Unpin code on upload, optional") + cmd.Flags().String(flagSource, "", "Code Source URL is a valid absolute HTTPS URI to the contract's source code,") + cmd.Flags().String(flagBuilder, "", "Builder is a valid docker image name with tag, such as \"cosmwasm/workspace-optimizer:0.12.9\"") + cmd.Flags().BytesHex(flagCodeHash, nil, "CodeHash is the sha256 hash of the wasm code") cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") diff --git a/x/wasm/client/cli/gov_tx_test.go b/x/wasm/client/cli/gov_tx_test.go index 7c8600e07f..147b9f61b1 100644 --- a/x/wasm/client/cli/gov_tx_test.go +++ b/x/wasm/client/cli/gov_tx_test.go @@ -1,6 +1,7 @@ package cli import ( + "os" "testing" "github.com/stretchr/testify/assert" @@ -95,3 +96,63 @@ func TestParseAccessConfigUpdates(t *testing.T) { }) } } + +func TestParseCodeInfoFlags(t *testing.T) { + correctSource := "https://github.com/CosmWasm/wasmd/blob/main/x/wasm/keeper/testdata/hackatom.wasm" + correctBuilderRef := "cosmwasm/workspace-optimizer:0.12.9" + + wasmBin, err := os.ReadFile("../../keeper/testdata/hackatom.wasm") + require.NoError(t, err) + + checksumStr := "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5" + + specs := map[string]struct { + args []string + expErr bool + }{ + "source missing": { + args: []string{"--builder=" + correctBuilderRef, "--code-hash=" + checksumStr}, + expErr: true, + }, + "builder missing": { + args: []string{"--code-source-url=" + correctSource, "--code-hash=" + checksumStr}, + expErr: true, + }, + "code hash missing": { + args: []string{"--code-source-url=" + correctSource, "--builder=" + correctBuilderRef}, + expErr: true, + }, + "source format wrong": { + args: []string{"--code-source-url=" + "format_wrong", "--builder=" + correctBuilderRef, "--code-hash=" + checksumStr}, + expErr: true, + }, + "builder format wrong": { + args: []string{"--code-source-url=" + correctSource, "--builder=" + "format//", "--code-hash=" + checksumStr}, + expErr: true, + }, + "code hash wrong": { + args: []string{"--code-source-url=" + correctSource, "--builder=" + correctBuilderRef, "--code-hash=" + "AA"}, + expErr: true, + }, + "happy path, none set": { + args: []string{}, + expErr: false, + }, + "happy path all set": { + args: []string{"--code-source-url=" + correctSource, "--builder=" + correctBuilderRef, "--code-hash=" + checksumStr}, + expErr: false, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + flags := ProposalStoreCodeCmd().Flags() + require.NoError(t, flags.Parse(spec.args)) + _, _, _, gotErr := parseVerificationFlags(wasmBin, flags) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + }) + } +} diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 35ccd7c1c7..7d7770d086 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -25,6 +25,9 @@ import ( const ( flagAmount = "amount" flagLabel = "label" + flagSource = "code-source-url" + flagBuilder = "builder" + flagCodeHash = "code-hash" flagAdmin = "admin" flagNoAdmin = "no-admin" flagFixMsg = "fix-msg" diff --git a/x/wasm/client/proposal_handler_test.go b/x/wasm/client/proposal_handler_test.go index 3e82c62e07..086e3cb3ae 100644 --- a/x/wasm/client/proposal_handler_test.go +++ b/x/wasm/client/proposal_handler_test.go @@ -62,7 +62,26 @@ func TestGovRestHandlers(t *testing.T) { "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", "wasm_byte_code": []byte("valid wasm byte code"), "source": "https://example.com/", - "builder": "my/builder:tag", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", + "instantiate_permission": dict{ + "permission": "OnlyAddress", + "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + }, + "deposit": []dict{{"denom": "ustake", "amount": "10"}}, + "proposer": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + "base_req": aBaseReq, + }, + expCode: http.StatusOK, + }, + "store-code without verification info": { + srcPath: "/gov/proposals/wasm_store_code", + srcBody: dict{ + "title": "Test Proposal", + "description": "My proposal", + "type": "store-code", + "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", + "wasm_byte_code": []byte("valid wasm byte code"), "instantiate_permission": dict{ "permission": "OnlyAddress", "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", @@ -82,7 +101,8 @@ func TestGovRestHandlers(t *testing.T) { "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", "wasm_byte_code": []byte("valid wasm byte code"), "source": "https://example.com/", - "builder": "my/builder:tag", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", "deposit": []dict{{"denom": "ustake", "amount": "10"}}, "proposer": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", "base_req": aBaseReq, @@ -98,7 +118,8 @@ func TestGovRestHandlers(t *testing.T) { "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", "wasm_byte_code": []byte("valid wasm byte code"), "source": "https://example.com/", - "builder": "my/builder:tag", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", "instantiate_permission": dict{ "permission": "Nobody", "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", @@ -118,7 +139,8 @@ func TestGovRestHandlers(t *testing.T) { "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", "wasm_byte_code": []byte("valid wasm byte code"), "source": "https://example.com/", - "builder": "my/builder:tag", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", "instantiate_permission": dict{ "permission": "OnlyAddress", "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", @@ -130,6 +152,27 @@ func TestGovRestHandlers(t *testing.T) { expCode: http.StatusBadRequest, }, "store-code with incomplete content data: no wasm_byte_code": { + srcPath: "/gov/proposals/wasm_store_code", + srcBody: dict{ + "title": "Test Proposal", + "description": "My proposal", + "type": "store-code", + "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", + "wasm_byte_code": "", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "source": "https://example.com/", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", + "instantiate_permission": dict{ + "permission": "OnlyAddress", + "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + }, + "deposit": []dict{{"denom": "ustake", "amount": "10"}}, + "proposer": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + "base_req": aBaseReq, + }, + expCode: http.StatusBadRequest, + }, + "store-code with incomplete content data: no builder": { srcPath: "/gov/proposals/wasm_store_code", srcBody: dict{ "title": "Test Proposal", @@ -138,7 +181,47 @@ func TestGovRestHandlers(t *testing.T) { "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", "wasm_byte_code": "", "source": "https://example.com/", - "builder": "my/builder:tag", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", + "instantiate_permission": dict{ + "permission": "OnlyAddress", + "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + }, + "deposit": []dict{{"denom": "ustake", "amount": "10"}}, + "proposer": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + "base_req": aBaseReq, + }, + expCode: http.StatusBadRequest, + }, + "store-code with incomplete content data: no code hash": { + srcPath: "/gov/proposals/wasm_store_code", + srcBody: dict{ + "title": "Test Proposal", + "description": "My proposal", + "type": "store-code", + "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", + "wasm_byte_code": "", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "source": "https://example.com/", + "instantiate_permission": dict{ + "permission": "OnlyAddress", + "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + }, + "deposit": []dict{{"denom": "ustake", "amount": "10"}}, + "proposer": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", + "base_req": aBaseReq, + }, + expCode: http.StatusBadRequest, + }, + "store-code with incomplete content data: no source": { + srcPath: "/gov/proposals/wasm_store_code", + srcBody: dict{ + "title": "Test Proposal", + "description": "My proposal", + "type": "store-code", + "run_as": "cosmos100dejzacpanrldpjjwksjm62shqhyss44jf5xz", + "wasm_byte_code": "", + "builder": "cosmwasm/workspace-optimizer:v0.12.9", + "code_hash": "79F174F09BFE3F83398BF7C147929D5F735161BD46D645E85216BB13BF91D42D", "instantiate_permission": dict{ "permission": "OnlyAddress", "address": "cosmos1ve557a5g9yw2g2z57js3pdmcvd5my6g8ze20np", diff --git a/x/wasm/client/rest/gov.go b/x/wasm/client/rest/gov.go index 3a27d2f0d7..c57e3a9ac5 100644 --- a/x/wasm/client/rest/gov.go +++ b/x/wasm/client/rest/gov.go @@ -30,6 +30,14 @@ type StoreCodeProposalJSONReq struct { // UnpinCode indicates if the code should not be pinned as part of the proposal. UnpinCode bool `json:"unpin_code" yaml:"unpin_code"` + + // Source is the URL where the code is hosted + Source string `json:"source" yaml:"source"` + // Builder is the docker image used to build the code deterministically, used for smart + // contract verification + Builder string `json:"builder" yaml:"builder"` + // CodeHash is the SHA256 sum of the code outputted by optimizer, used for smart contract verification + CodeHash []byte `json:"code_hash" yaml:"code_hash"` } func (s StoreCodeProposalJSONReq) Content() govtypes.Content { @@ -40,6 +48,9 @@ func (s StoreCodeProposalJSONReq) Content() govtypes.Content { WASMByteCode: s.WASMByteCode, InstantiatePermission: s.InstantiatePermission, UnpinCode: s.UnpinCode, + Source: s.Source, + Builder: s.Builder, + CodeHash: s.CodeHash, } } diff --git a/x/wasm/keeper/proposal_handler.go b/x/wasm/keeper/proposal_handler.go index b39a8c4238..08f2774f3e 100644 --- a/x/wasm/keeper/proposal_handler.go +++ b/x/wasm/keeper/proposal_handler.go @@ -1,7 +1,9 @@ package keeper import ( + "bytes" "encoding/hex" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -66,11 +68,15 @@ func handleStoreCodeProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types if err != nil { return sdkerrors.Wrap(err, "run as address") } - codeID, _, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission) + codeID, checksum, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission) if err != nil { return err } + if len(p.CodeHash) != 0 && !bytes.Equal(checksum, p.CodeHash) { + return fmt.Errorf("code-hash mismatch: %X, checksum: %X", p.CodeHash, checksum) + } + // if code should not be pinned return earlier if p.UnpinCode { return nil @@ -120,11 +126,15 @@ func handleStoreAndInstantiateContractProposal(ctx sdk.Context, k types.Contract } } - codeID, _, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission) + codeID, checksum, err := k.Create(ctx, runAsAddr, p.WASMByteCode, p.InstantiatePermission) if err != nil { return err } + if p.CodeHash != nil && !bytes.Equal(checksum, p.CodeHash) { + return sdkerrors.Wrap(fmt.Errorf("code-hash mismatch: %X, checksum: %X", p.CodeHash, checksum), "code-hash mismatch") + } + if !p.UnpinCode { if err := k.PinCode(ctx, codeID); err != nil { return err diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 8055ca385a..74ef6928b9 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -29,6 +29,8 @@ func TestStoreCodeProposal(t *testing.T) { }) wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) + checksum, err := hex.DecodeString("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5") + require.NoError(t, err) specs := map[string]struct { codeID int64 @@ -51,6 +53,7 @@ func TestStoreCodeProposal(t *testing.T) { p.RunAs = myActorAddress p.WASMByteCode = wasmCode p.UnpinCode = spec.unpinCode + p.CodeHash = checksum }) // when stored @@ -221,6 +224,9 @@ func TestStoreAndInstantiateContractProposal(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) + checksum, err := hex.DecodeString("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5") + require.NoError(t, err) + var ( oneAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, types.ContractAddrLen) otherAddress sdk.AccAddress = bytes.Repeat([]byte{0x2}, types.ContractAddrLen) @@ -231,6 +237,7 @@ func TestStoreAndInstantiateContractProposal(t *testing.T) { p.RunAs = oneAddress.String() p.Admin = otherAddress.String() p.Label = "testing" + p.CodeHash = checksum }) em := sdk.NewEventManager() diff --git a/x/wasm/simulation/proposals.go b/x/wasm/simulation/proposals.go index 1ee9584811..585827c041 100644 --- a/x/wasm/simulation/proposals.go +++ b/x/wasm/simulation/proposals.go @@ -84,6 +84,9 @@ func SimulateStoreCodeProposal(wasmKeeper WasmKeeper) simtypes.ContentSimulatorF wasmBz, &permission, false, + "", + "", + []byte{}, ) } } diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index e56300a911..1597818597 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -2,6 +2,7 @@ package types import ( "encoding/base64" + "encoding/hex" "fmt" "strings" @@ -94,8 +95,11 @@ func NewStoreCodeProposal( wasmBz []byte, permission *AccessConfig, unpinCode bool, + source string, + builder string, + codeHash []byte, ) *StoreCodeProposal { - return &StoreCodeProposal{title, description, runAs, wasmBz, permission, unpinCode} + return &StoreCodeProposal{title, description, runAs, wasmBz, permission, unpinCode, source, builder, codeHash} } // ProposalRoute returns the routing key of a parameter change proposal. @@ -128,6 +132,10 @@ func (p StoreCodeProposal) ValidateBasic() error { return sdkerrors.Wrap(err, "instantiate permission") } } + + if err := ValidateVerificationInfo(p.Source, p.Builder, p.CodeHash); err != nil { + return sdkerrors.Wrapf(err, "code verification info") + } return nil } @@ -138,7 +146,10 @@ func (p StoreCodeProposal) String() string { Description: %s Run as: %s WasmCode: %X -`, p.Title, p.Description, p.RunAs, p.WASMByteCode) + Source: %s + Builder: %s + Code Hash: %X +`, p.Title, p.Description, p.RunAs, p.WASMByteCode, p.Source, p.Builder, p.CodeHash) } // MarshalYAML pretty prints the wasm byte code @@ -149,12 +160,18 @@ func (p StoreCodeProposal) MarshalYAML() (interface{}, error) { RunAs string `yaml:"run_as"` WASMByteCode string `yaml:"wasm_byte_code"` InstantiatePermission *AccessConfig `yaml:"instantiate_permission"` + Source string `yaml:"source"` + Builder string `yaml:"builder"` + CodeHash string `yaml:"code_hash"` }{ Title: p.Title, Description: p.Description, RunAs: p.RunAs, WASMByteCode: base64.StdEncoding.EncodeToString(p.WASMByteCode), InstantiatePermission: p.InstantiatePermission, + Source: p.Source, + Builder: p.Builder, + CodeHash: hex.EncodeToString(p.CodeHash), }, nil } @@ -259,6 +276,9 @@ func NewStoreAndInstantiateContractProposal( description string, runAs string, wasmBz []byte, + source string, + builder string, + codeHash []byte, permission *AccessConfig, unpinCode bool, admin string, @@ -271,6 +291,9 @@ func NewStoreAndInstantiateContractProposal( Description: description, RunAs: runAs, WASMByteCode: wasmBz, + Source: source, + Builder: builder, + CodeHash: codeHash, InstantiatePermission: permission, UnpinCode: unpinCode, Admin: admin, @@ -307,6 +330,10 @@ func (p StoreAndInstantiateContractProposal) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "code bytes %s", err.Error()) } + if err := ValidateVerificationInfo(p.Source, p.Builder, p.CodeHash); err != nil { + return sdkerrors.Wrap(err, "code info") + } + if p.InstantiatePermission != nil { if err := p.InstantiatePermission.ValidateBasic(); err != nil { return sdkerrors.Wrap(err, "instantiate permission") @@ -339,13 +366,16 @@ func (p StoreAndInstantiateContractProposal) String() string { Description: %s Run as: %s WasmCode: %X + Source: %s + Builder: %s + Code Hash: %X Instantiate permission: %s Unpin code: %t Admin: %s Label: %s Msg: %q Funds: %s -`, p.Title, p.Description, p.RunAs, p.WASMByteCode, p.InstantiatePermission, p.UnpinCode, p.Admin, p.Label, p.Msg, p.Funds) +`, p.Title, p.Description, p.RunAs, p.WASMByteCode, p.Source, p.Builder, p.CodeHash, p.InstantiatePermission, p.UnpinCode, p.Admin, p.Label, p.Msg, p.Funds) } // MarshalYAML pretty prints the wasm byte code and the init message @@ -355,6 +385,9 @@ func (p StoreAndInstantiateContractProposal) MarshalYAML() (interface{}, error) Description string `yaml:"description"` RunAs string `yaml:"run_as"` WASMByteCode string `yaml:"wasm_byte_code"` + Source string `yaml:"source"` + Builder string `yaml:"builder"` + CodeHash string `yaml:"code_hash"` InstantiatePermission *AccessConfig `yaml:"instantiate_permission"` UnpinCode bool `yaml:"unpin_code"` Admin string `yaml:"admin"` @@ -370,6 +403,9 @@ func (p StoreAndInstantiateContractProposal) MarshalYAML() (interface{}, error) UnpinCode: p.UnpinCode, Admin: p.Admin, Label: p.Label, + Source: p.Source, + Builder: p.Builder, + CodeHash: hex.EncodeToString(p.CodeHash), Msg: string(p.Msg), Funds: p.Funds, }, nil diff --git a/x/wasm/types/proposal.pb.go b/x/wasm/types/proposal.pb.go index 27a9ed0b9f..dbce4e7172 100644 --- a/x/wasm/types/proposal.pb.go +++ b/x/wasm/types/proposal.pb.go @@ -17,9 +17,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) @@ -44,6 +43,14 @@ type StoreCodeProposal struct { InstantiatePermission *AccessConfig `protobuf:"bytes,7,opt,name=instantiate_permission,json=instantiatePermission,proto3" json:"instantiate_permission,omitempty"` // UnpinCode code on upload, optional UnpinCode bool `protobuf:"varint,8,opt,name=unpin_code,json=unpinCode,proto3" json:"unpin_code,omitempty"` + // Source is the URL where the code is hosted + Source string `protobuf:"bytes,9,opt,name=source,proto3" json:"source,omitempty"` + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + Builder string `protobuf:"bytes,10,opt,name=builder,proto3" json:"builder,omitempty"` + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + CodeHash []byte `protobuf:"bytes,11,opt,name=code_hash,json=codeHash,proto3" json:"code_hash,omitempty"` } func (m *StoreCodeProposal) Reset() { *m = StoreCodeProposal{} } @@ -606,6 +613,14 @@ type StoreAndInstantiateContractProposal struct { Msg RawContractMessage `protobuf:"bytes,9,opt,name=msg,proto3,casttype=RawContractMessage" json:"msg,omitempty"` // Funds coins that are transferred to the contract on instantiation Funds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,10,rep,name=funds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"funds"` + // Source is the URL where the code is hosted + Source string `protobuf:"bytes,11,opt,name=source,proto3" json:"source,omitempty"` + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + Builder string `protobuf:"bytes,12,opt,name=builder,proto3" json:"builder,omitempty"` + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + CodeHash []byte `protobuf:"bytes,13,opt,name=code_hash,json=codeHash,proto3" json:"code_hash,omitempty"` } func (m *StoreAndInstantiateContractProposal) Reset() { *m = StoreAndInstantiateContractProposal{} } @@ -663,62 +678,66 @@ func init() { func init() { proto.RegisterFile("cosmwasm/wasm/v1/proposal.proto", fileDescriptor_be6422d717c730cb) } var fileDescriptor_be6422d717c730cb = []byte{ - // 877 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0xe3, 0x44, - 0x1c, 0xcf, 0xe4, 0xc3, 0x49, 0xa6, 0x11, 0x04, 0x6f, 0xda, 0x0d, 0x05, 0xec, 0xc8, 0x8b, 0x56, - 0xbe, 0xe0, 0x90, 0x22, 0x21, 0xe0, 0x16, 0x07, 0x0e, 0x5d, 0x51, 0xa9, 0x72, 0x55, 0xad, 0x04, - 0x12, 0xd1, 0xc4, 0x9e, 0x7a, 0x2d, 0xe2, 0x19, 0xcb, 0x33, 0x6e, 0xb7, 0x6f, 0x01, 0x12, 0xe2, - 0xb4, 0x0f, 0x80, 0xb8, 0x20, 0xee, 0x3c, 0x40, 0xc5, 0x69, 0x8f, 0x2b, 0x21, 0x19, 0x36, 0x7d, - 0x83, 0x1e, 0x39, 0xa1, 0x99, 0x71, 0xb2, 0x69, 0x77, 0xdb, 0xdd, 0x15, 0x4d, 0xa5, 0xbd, 0x38, - 0x99, 0xf9, 0x7f, 0xfd, 0xe6, 0xa7, 0xff, 0x17, 0x34, 0x7d, 0xca, 0xe2, 0x23, 0xc4, 0xe2, 0xbe, - 0xfc, 0x1c, 0x0e, 0xfa, 0x49, 0x4a, 0x13, 0xca, 0xd0, 0xd4, 0x49, 0x52, 0xca, 0xa9, 0xde, 0x9e, - 0x2b, 0x38, 0xf2, 0x73, 0x38, 0xd8, 0xec, 0x84, 0x34, 0xa4, 0x52, 0xd8, 0x17, 0xff, 0x94, 0xde, - 0xa6, 0x21, 0xf4, 0x28, 0xeb, 0x4f, 0x10, 0xc3, 0xfd, 0xc3, 0xc1, 0x04, 0x73, 0x34, 0xe8, 0xfb, - 0x34, 0x22, 0x85, 0xfc, 0xfd, 0xe7, 0x02, 0xf1, 0xe3, 0x04, 0x33, 0x25, 0xb5, 0x1e, 0x95, 0xe1, - 0x3b, 0x7b, 0x9c, 0xa6, 0x78, 0x44, 0x03, 0xbc, 0x5b, 0x20, 0xd0, 0x3b, 0xb0, 0xc6, 0x23, 0x3e, - 0xc5, 0x5d, 0xd0, 0x03, 0x76, 0xd3, 0x53, 0x07, 0xbd, 0x07, 0xd7, 0x02, 0xcc, 0xfc, 0x34, 0x4a, - 0x78, 0x44, 0x49, 0xb7, 0x2c, 0x65, 0xcb, 0x57, 0xfa, 0x3a, 0xd4, 0xd2, 0x8c, 0x8c, 0x11, 0xeb, - 0x56, 0x94, 0x61, 0x9a, 0x91, 0x21, 0xd3, 0x3f, 0x85, 0x6f, 0x89, 0xd8, 0xe3, 0xc9, 0x31, 0xc7, - 0x63, 0x9f, 0x06, 0xb8, 0x5b, 0xed, 0x01, 0xbb, 0xe5, 0xb6, 0x67, 0xb9, 0xd9, 0xba, 0x3f, 0xdc, - 0xdb, 0x71, 0x8f, 0xb9, 0x04, 0xe0, 0xb5, 0x84, 0xde, 0xfc, 0xa4, 0xef, 0xc3, 0x8d, 0x88, 0x30, - 0x8e, 0x08, 0x8f, 0x10, 0xc7, 0xe3, 0x04, 0xa7, 0x71, 0xc4, 0x98, 0x88, 0x5d, 0xef, 0x01, 0x7b, - 0x6d, 0xcb, 0x70, 0x2e, 0x72, 0xe4, 0x0c, 0x7d, 0x1f, 0x33, 0x36, 0xa2, 0xe4, 0x20, 0x0a, 0xbd, - 0xf5, 0x25, 0xeb, 0xdd, 0x85, 0xb1, 0xfe, 0x01, 0x84, 0x19, 0x49, 0x22, 0xa2, 0xa0, 0x34, 0x7a, - 0xc0, 0x6e, 0x78, 0x4d, 0x79, 0x23, 0xa2, 0xde, 0xab, 0x36, 0x6a, 0x6d, 0xed, 0x5e, 0xb5, 0xa1, - 0xb5, 0xeb, 0xd6, 0x9f, 0x65, 0xf8, 0xde, 0xf6, 0x33, 0x27, 0x23, 0x4a, 0x78, 0x8a, 0x7c, 0xbe, - 0x2a, 0xa2, 0x3a, 0xb0, 0x86, 0x82, 0x38, 0x22, 0x92, 0x9f, 0xa6, 0xa7, 0x0e, 0xfa, 0x1d, 0x58, - 0x17, 0x48, 0xc7, 0x51, 0xd0, 0xad, 0xf5, 0x80, 0x5d, 0x75, 0xe1, 0x2c, 0x37, 0x35, 0x81, 0x75, - 0xfb, 0x4b, 0x4f, 0x13, 0xa2, 0xed, 0x40, 0x98, 0x4e, 0xd1, 0x04, 0x4f, 0xbb, 0x9a, 0x32, 0x95, - 0x07, 0xdd, 0x86, 0x95, 0x98, 0x85, 0x92, 0xae, 0x96, 0xbb, 0xf1, 0x6f, 0x6e, 0xea, 0x1e, 0x3a, - 0x9a, 0xbf, 0x62, 0x07, 0x33, 0x86, 0x42, 0xec, 0x09, 0x15, 0x1d, 0xc1, 0xda, 0x41, 0x46, 0x02, - 0xd6, 0x6d, 0xf4, 0x2a, 0xf6, 0xda, 0xd6, 0xbb, 0x8e, 0x4a, 0x2b, 0x47, 0xa4, 0x95, 0x53, 0xa4, - 0x95, 0x33, 0xa2, 0x11, 0x71, 0x3f, 0x3e, 0xc9, 0xcd, 0xd2, 0xaf, 0x7f, 0x9b, 0x76, 0x18, 0xf1, - 0x07, 0xd9, 0xc4, 0xf1, 0x69, 0xdc, 0x2f, 0x72, 0x50, 0xfd, 0x7c, 0xc4, 0x82, 0xef, 0x8b, 0x24, - 0x13, 0x06, 0xcc, 0x53, 0x9e, 0xad, 0x3f, 0x00, 0xbc, 0xbd, 0x13, 0x85, 0xe9, 0x75, 0x12, 0xb9, - 0x09, 0x1b, 0x7e, 0xe1, 0xab, 0x20, 0x6d, 0x71, 0x7e, 0x35, 0xde, 0x0a, 0x86, 0xb4, 0x97, 0x32, - 0x64, 0xfd, 0x04, 0x60, 0x67, 0x2f, 0x0b, 0xe8, 0x4a, 0xb0, 0x57, 0x2e, 0x60, 0x2f, 0x60, 0x55, - 0x5f, 0x0e, 0xeb, 0xc7, 0x32, 0xbc, 0xfd, 0xd5, 0x43, 0xec, 0x67, 0xab, 0x4f, 0xcf, 0xab, 0xc8, - 0x2e, 0x00, 0xd7, 0x5e, 0x23, 0xd3, 0xb4, 0x95, 0x65, 0xda, 0x23, 0x00, 0x6f, 0xed, 0x27, 0x01, - 0xe2, 0x78, 0x28, 0x2a, 0xe8, 0x7f, 0xf3, 0x31, 0x80, 0x4d, 0x82, 0x8f, 0xc6, 0xaa, 0x36, 0x25, - 0x25, 0x6e, 0xe7, 0x2c, 0x37, 0xdb, 0xc7, 0x28, 0x9e, 0x7e, 0x61, 0x2d, 0x44, 0x96, 0xd7, 0x20, - 0xf8, 0x48, 0x86, 0xbc, 0x8a, 0x2b, 0xeb, 0x01, 0xd4, 0x47, 0x53, 0x8c, 0xd2, 0xeb, 0x01, 0x77, - 0x45, 0x1a, 0x59, 0xbf, 0x01, 0xd8, 0xde, 0x55, 0x7d, 0x8d, 0x2d, 0x02, 0xdd, 0x3d, 0x17, 0xc8, - 0x6d, 0x9f, 0xe5, 0x66, 0x4b, 0xbd, 0x44, 0x5e, 0x5b, 0xf3, 0xd0, 0x9f, 0xbd, 0x20, 0xb4, 0xbb, - 0x71, 0x96, 0x9b, 0xba, 0xd2, 0x5e, 0x12, 0x5a, 0xe7, 0x21, 0x7d, 0x2e, 0x20, 0xc9, 0xca, 0x13, - 0x19, 0x54, 0xb1, 0xab, 0xae, 0x31, 0xcb, 0xcd, 0xba, 0x2a, 0x3d, 0x76, 0x96, 0x9b, 0x6f, 0x2b, - 0x0f, 0x73, 0x25, 0xcb, 0xab, 0xab, 0x72, 0x64, 0xd6, 0xef, 0x00, 0xea, 0xfb, 0xf3, 0x5e, 0xfc, - 0x86, 0x60, 0xfe, 0x19, 0x40, 0x7d, 0x79, 0xf0, 0xa8, 0xd4, 0x5b, 0xee, 0x3f, 0xe0, 0xd2, 0xfe, - 0xf3, 0xed, 0xa5, 0x33, 0xae, 0xfc, 0x2a, 0x33, 0xce, 0xad, 0x8a, 0x1a, 0xb9, 0x64, 0xd2, 0x59, - 0xa7, 0x00, 0x9a, 0x0a, 0xcc, 0xf9, 0x21, 0x76, 0x10, 0x85, 0x37, 0xc8, 0xec, 0x77, 0x70, 0x1d, - 0x49, 0xc8, 0x63, 0x5f, 0x86, 0x1e, 0x67, 0x12, 0x92, 0xa2, 0x79, 0x6d, 0xeb, 0xc3, 0xab, 0x5f, - 0xa8, 0xf0, 0x17, 0xef, 0xbc, 0x85, 0x9e, 0x93, 0x30, 0xeb, 0xaf, 0x0a, 0xbc, 0x23, 0x77, 0x98, - 0x21, 0x09, 0x6e, 0x70, 0x58, 0x5f, 0xff, 0x56, 0x53, 0xbb, 0xbe, 0xad, 0x46, 0xbb, 0xb0, 0xd5, - 0x3c, 0x5b, 0x2d, 0xea, 0xcb, 0xab, 0xc5, 0x62, 0x6b, 0x68, 0xbc, 0x60, 0x6b, 0x68, 0xbe, 0x46, - 0x2f, 0x87, 0xab, 0xea, 0xe5, 0xee, 0xd7, 0x27, 0x4f, 0x8d, 0xd2, 0x93, 0xa7, 0x46, 0xe9, 0x97, - 0x99, 0x01, 0x4e, 0x66, 0x06, 0x78, 0x3c, 0x33, 0xc0, 0x3f, 0x33, 0x03, 0xfc, 0x70, 0x6a, 0x94, - 0x1e, 0x9f, 0x1a, 0xa5, 0x27, 0xa7, 0x46, 0xe9, 0x9b, 0xbb, 0x4b, 0x6e, 0x47, 0x94, 0xc5, 0xf7, - 0xe7, 0x0b, 0x6f, 0xd0, 0x7f, 0xa8, 0x16, 0x5f, 0xe9, 0x7a, 0xa2, 0xc9, 0xb5, 0xf7, 0x93, 0xff, - 0x02, 0x00, 0x00, 0xff, 0xff, 0x50, 0x71, 0x76, 0x67, 0x7f, 0x0b, 0x00, 0x00, + // 936 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0xcf, 0xe4, 0x8f, 0xe3, 0xbc, 0x04, 0x08, 0xde, 0xb4, 0x6b, 0xba, 0x60, 0x47, 0x5e, 0xb4, + 0xca, 0x05, 0x87, 0x14, 0x09, 0x01, 0xb7, 0x38, 0x20, 0xd1, 0x15, 0x95, 0x2a, 0x57, 0xd5, 0x4a, + 0x20, 0x11, 0x4d, 0xec, 0x69, 0x62, 0x91, 0x78, 0x22, 0x8f, 0xdd, 0x6e, 0xbf, 0x05, 0x48, 0x88, + 0x13, 0x1f, 0x00, 0xed, 0x05, 0x71, 0xe7, 0x03, 0x54, 0x9c, 0xf6, 0xb8, 0x27, 0xc3, 0xa6, 0x47, + 0x6e, 0x3d, 0x72, 0x42, 0x33, 0xe3, 0x84, 0xb4, 0xbb, 0xcd, 0xee, 0x8a, 0xa6, 0xd2, 0x5e, 0x9c, + 0xbc, 0x79, 0x6f, 0xe6, 0xfd, 0xde, 0x4f, 0x6f, 0xe6, 0xfd, 0xc0, 0xf4, 0x28, 0x9b, 0x1c, 0x63, + 0x36, 0x69, 0x8b, 0xcf, 0x51, 0xa7, 0x3d, 0x8d, 0xe8, 0x94, 0x32, 0x3c, 0xb6, 0xa7, 0x11, 0x8d, + 0xa9, 0x56, 0x9f, 0x07, 0xd8, 0xe2, 0x73, 0xd4, 0xd9, 0x6a, 0x0c, 0xe9, 0x90, 0x0a, 0x67, 0x9b, + 0xff, 0x93, 0x71, 0x5b, 0x06, 0x8f, 0xa3, 0xac, 0x3d, 0xc0, 0x8c, 0xb4, 0x8f, 0x3a, 0x03, 0x12, + 0xe3, 0x4e, 0xdb, 0xa3, 0x41, 0x98, 0xf9, 0xdf, 0x7d, 0x26, 0x51, 0x7c, 0x32, 0x25, 0x4c, 0x7a, + 0xad, 0xbf, 0xf3, 0xf0, 0xf6, 0x7e, 0x4c, 0x23, 0xd2, 0xa3, 0x3e, 0xd9, 0xcb, 0x10, 0x68, 0x0d, + 0x28, 0xc5, 0x41, 0x3c, 0x26, 0x3a, 0x6a, 0xa2, 0x56, 0xc5, 0x95, 0x86, 0xd6, 0x84, 0xaa, 0x4f, + 0x98, 0x17, 0x05, 0xd3, 0x38, 0xa0, 0xa1, 0x9e, 0x17, 0xbe, 0xe5, 0x25, 0x6d, 0x03, 0x94, 0x28, + 0x09, 0xfb, 0x98, 0xe9, 0x05, 0xb9, 0x31, 0x4a, 0xc2, 0x2e, 0xd3, 0x3e, 0x86, 0x37, 0x79, 0xee, + 0xfe, 0xe0, 0x24, 0x26, 0x7d, 0x8f, 0xfa, 0x44, 0x2f, 0x36, 0x51, 0xab, 0xe6, 0xd4, 0x67, 0xa9, + 0x59, 0x7b, 0xd0, 0xdd, 0xdf, 0x75, 0x4e, 0x62, 0x01, 0xc0, 0xad, 0xf1, 0xb8, 0xb9, 0xa5, 0x1d, + 0xc0, 0x66, 0x10, 0xb2, 0x18, 0x87, 0x71, 0x80, 0x63, 0xd2, 0x9f, 0x92, 0x68, 0x12, 0x30, 0xc6, + 0x73, 0x97, 0x9b, 0xa8, 0x55, 0xdd, 0x36, 0xec, 0xcb, 0x1c, 0xd9, 0x5d, 0xcf, 0x23, 0x8c, 0xf5, + 0x68, 0x78, 0x18, 0x0c, 0xdd, 0x8d, 0xa5, 0xdd, 0x7b, 0x8b, 0xcd, 0xda, 0x7b, 0x00, 0x49, 0x38, + 0x0d, 0x42, 0x09, 0x45, 0x6d, 0xa2, 0x96, 0xea, 0x56, 0xc4, 0x8a, 0xc8, 0xba, 0x09, 0x0a, 0xa3, + 0x49, 0xe4, 0x11, 0xbd, 0x22, 0x8a, 0xc8, 0x2c, 0x4d, 0x87, 0xf2, 0x20, 0x09, 0xc6, 0x3e, 0x89, + 0x74, 0x10, 0x8e, 0xb9, 0xa9, 0xdd, 0x81, 0x0a, 0x3f, 0xaa, 0x3f, 0xc2, 0x6c, 0xa4, 0x57, 0x79, + 0x69, 0xae, 0xca, 0x17, 0xbe, 0xc4, 0x6c, 0x74, 0xbf, 0xa8, 0x96, 0xea, 0xca, 0xfd, 0xa2, 0xaa, + 0xd4, 0xcb, 0xd6, 0x1f, 0x79, 0xb8, 0xb3, 0xf3, 0x1f, 0xa6, 0x1e, 0x0d, 0xe3, 0x08, 0x7b, 0xf1, + 0xba, 0x78, 0x6f, 0x40, 0x09, 0xfb, 0x93, 0x20, 0x14, 0x74, 0x57, 0x5c, 0x69, 0x68, 0x77, 0xa1, + 0x2c, 0xd0, 0x06, 0xbe, 0x5e, 0x6a, 0xa2, 0x56, 0xd1, 0x81, 0x59, 0x6a, 0x2a, 0xbc, 0xf4, 0x9d, + 0xcf, 0x5d, 0x85, 0xbb, 0x76, 0x7c, 0xbe, 0x75, 0x8c, 0x07, 0x64, 0xac, 0x2b, 0x72, 0xab, 0x30, + 0xb4, 0x16, 0x14, 0x26, 0x6c, 0x28, 0xd8, 0xaf, 0x39, 0x9b, 0xff, 0xa4, 0xa6, 0xe6, 0xe2, 0xe3, + 0x79, 0x15, 0xbb, 0x84, 0x31, 0x3c, 0x24, 0x2e, 0x0f, 0xd1, 0x30, 0x94, 0x0e, 0x93, 0xd0, 0x67, + 0xba, 0xda, 0x2c, 0xb4, 0xaa, 0xdb, 0xef, 0xd8, 0xb2, 0x4b, 0x6d, 0xde, 0xa5, 0x76, 0xd6, 0xa5, + 0x76, 0x8f, 0x06, 0xa1, 0xf3, 0xe1, 0x69, 0x6a, 0xe6, 0x1e, 0xfd, 0x69, 0xb6, 0x86, 0x41, 0x3c, + 0x4a, 0x06, 0xb6, 0x47, 0x27, 0xed, 0xac, 0xa5, 0xe5, 0xcf, 0x07, 0xcc, 0xff, 0x2e, 0xeb, 0x59, + 0xbe, 0x81, 0xb9, 0xf2, 0x64, 0xeb, 0x77, 0x04, 0xb7, 0x77, 0x83, 0x61, 0x74, 0x9d, 0x44, 0x6e, + 0x81, 0xea, 0x65, 0x67, 0x65, 0xa4, 0x2d, 0xec, 0x97, 0xe3, 0x2d, 0x63, 0x48, 0x79, 0x21, 0x43, + 0xd6, 0x8f, 0x08, 0x1a, 0xfb, 0x89, 0x4f, 0xd7, 0x82, 0xbd, 0x70, 0x09, 0x7b, 0x06, 0xab, 0xf8, + 0x62, 0x58, 0x3f, 0xe4, 0xe1, 0xf6, 0x17, 0x0f, 0x89, 0x97, 0xac, 0xbf, 0x3d, 0x57, 0x91, 0x9d, + 0x01, 0x2e, 0xbd, 0x42, 0xa7, 0x29, 0x6b, 0xeb, 0xb4, 0x9f, 0x11, 0xdc, 0x3a, 0x98, 0xfa, 0x38, + 0x26, 0x5d, 0x7e, 0x83, 0xfe, 0x37, 0x1f, 0x1d, 0xa8, 0x84, 0xe4, 0xb8, 0x2f, 0xef, 0xa6, 0xa0, + 0xc4, 0x69, 0x9c, 0xa7, 0x66, 0xfd, 0x04, 0x4f, 0xc6, 0x9f, 0x59, 0x0b, 0x97, 0xe5, 0xaa, 0x21, + 0x39, 0x16, 0x29, 0x57, 0x71, 0x65, 0x8d, 0x40, 0xeb, 0x8d, 0x09, 0x8e, 0xae, 0x07, 0xdc, 0x8a, + 0x36, 0xb2, 0x7e, 0x45, 0x50, 0xdf, 0x93, 0xcf, 0x24, 0x5b, 0x24, 0xba, 0x77, 0x21, 0x91, 0x53, + 0x3f, 0x4f, 0xcd, 0x9a, 0xac, 0x44, 0x2c, 0x5b, 0xf3, 0xd4, 0x9f, 0x3c, 0x27, 0xb5, 0xb3, 0x79, + 0x9e, 0x9a, 0x9a, 0x8c, 0x5e, 0x72, 0x5a, 0x17, 0x21, 0x7d, 0x0a, 0x6a, 0x76, 0xf3, 0x78, 0x07, + 0x15, 0x5a, 0x45, 0xc7, 0x98, 0xa5, 0x66, 0x59, 0x5e, 0x3d, 0x76, 0x9e, 0x9a, 0x6f, 0xc9, 0x13, + 0xe6, 0x41, 0x96, 0x5b, 0x96, 0xd7, 0x91, 0x59, 0xbf, 0x21, 0xd0, 0x0e, 0xe6, 0x4f, 0xfb, 0x6b, + 0x82, 0xf9, 0x27, 0x04, 0xda, 0xf2, 0x1c, 0x93, 0xad, 0xb7, 0xfc, 0xfe, 0xa0, 0x2b, 0xdf, 0x9f, + 0x6f, 0xae, 0x1c, 0x99, 0xf9, 0x97, 0x19, 0x99, 0x4e, 0x91, 0xdf, 0x91, 0x2b, 0x06, 0xa7, 0x75, + 0x86, 0xc0, 0x94, 0x60, 0x2e, 0x0e, 0xb1, 0xc3, 0x60, 0x78, 0x83, 0xcc, 0x7e, 0x0b, 0x1b, 0x58, + 0x40, 0xee, 0x7b, 0x22, 0x75, 0x3f, 0x11, 0x90, 0x24, 0xcd, 0xd5, 0xed, 0xf7, 0x57, 0x57, 0x28, + 0xf1, 0x67, 0x75, 0xde, 0xc2, 0xcf, 0x78, 0x98, 0xf5, 0xa8, 0x08, 0x77, 0x85, 0x24, 0xea, 0x86, + 0xfe, 0x0d, 0x0e, 0xeb, 0xeb, 0x17, 0x49, 0xa5, 0xeb, 0x13, 0x49, 0xca, 0x65, 0x91, 0xb4, 0x90, + 0x16, 0xe5, 0x65, 0x69, 0xb1, 0x50, 0x0d, 0xea, 0x73, 0x54, 0x43, 0xe5, 0x15, 0xde, 0x72, 0x58, + 0xd7, 0x5b, 0xbe, 0xa4, 0xee, 0xaa, 0x57, 0xa9, 0xbb, 0xda, 0x0a, 0x75, 0xf7, 0xc6, 0x45, 0x75, + 0xe7, 0x7c, 0x75, 0xfa, 0xd4, 0xc8, 0x3d, 0x79, 0x6a, 0xe4, 0x7e, 0x99, 0x19, 0xe8, 0x74, 0x66, + 0xa0, 0xc7, 0x33, 0x03, 0xfd, 0x35, 0x33, 0xd0, 0xf7, 0x67, 0x46, 0xee, 0xf1, 0x99, 0x91, 0x7b, + 0x72, 0x66, 0xe4, 0xbe, 0xbe, 0xb7, 0x84, 0xb2, 0x47, 0xd9, 0xe4, 0xc1, 0x5c, 0x8e, 0xfb, 0xed, + 0x87, 0x52, 0x96, 0x0b, 0xa4, 0x03, 0x45, 0x88, 0xf2, 0x8f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, + 0x13, 0x9e, 0x35, 0x27, 0x1d, 0x0c, 0x00, 0x00, } func (this *StoreCodeProposal) Equal(that interface{}) bool { @@ -758,6 +777,15 @@ func (this *StoreCodeProposal) Equal(that interface{}) bool { if this.UnpinCode != that1.UnpinCode { return false } + if this.Source != that1.Source { + return false + } + if this.Builder != that1.Builder { + return false + } + if !bytes.Equal(this.CodeHash, that1.CodeHash) { + return false + } return true } @@ -1183,6 +1211,15 @@ func (this *StoreAndInstantiateContractProposal) Equal(that interface{}) bool { return false } } + if this.Source != that1.Source { + return false + } + if this.Builder != that1.Builder { + return false + } + if !bytes.Equal(this.CodeHash, that1.CodeHash) { + return false + } return true } @@ -1206,6 +1243,27 @@ func (m *StoreCodeProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CodeHash) > 0 { + i -= len(m.CodeHash) + copy(dAtA[i:], m.CodeHash) + i = encodeVarintProposal(dAtA, i, uint64(len(m.CodeHash))) + i-- + dAtA[i] = 0x5a + } + if len(m.Builder) > 0 { + i -= len(m.Builder) + copy(dAtA[i:], m.Builder) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Builder))) + i-- + dAtA[i] = 0x52 + } + if len(m.Source) > 0 { + i -= len(m.Source) + copy(dAtA[i:], m.Source) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Source))) + i-- + dAtA[i] = 0x4a + } if m.UnpinCode { i-- if m.UnpinCode { @@ -1836,6 +1894,27 @@ func (m *StoreAndInstantiateContractProposal) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l + if len(m.CodeHash) > 0 { + i -= len(m.CodeHash) + copy(dAtA[i:], m.CodeHash) + i = encodeVarintProposal(dAtA, i, uint64(len(m.CodeHash))) + i-- + dAtA[i] = 0x6a + } + if len(m.Builder) > 0 { + i -= len(m.Builder) + copy(dAtA[i:], m.Builder) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Builder))) + i-- + dAtA[i] = 0x62 + } + if len(m.Source) > 0 { + i -= len(m.Source) + copy(dAtA[i:], m.Source) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Source))) + i-- + dAtA[i] = 0x5a + } if len(m.Funds) > 0 { for iNdEx := len(m.Funds) - 1; iNdEx >= 0; iNdEx-- { { @@ -1965,6 +2044,18 @@ func (m *StoreCodeProposal) Size() (n int) { if m.UnpinCode { n += 2 } + l = len(m.Source) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Builder) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.CodeHash) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } return n } @@ -2276,6 +2367,18 @@ func (m *StoreAndInstantiateContractProposal) Size() (n int) { n += 1 + l + sovProposal(uint64(l)) } } + l = len(m.Source) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Builder) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.CodeHash) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } return n } @@ -2502,6 +2605,104 @@ func (m *StoreCodeProposal) Unmarshal(dAtA []byte) error { } } m.UnpinCode = bool(v != 0) + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Builder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Builder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeHash = append(m.CodeHash[:0], dAtA[iNdEx:postIndex]...) + if m.CodeHash == nil { + m.CodeHash = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProposal(dAtA[iNdEx:]) @@ -4757,6 +4958,104 @@ func (m *StoreAndInstantiateContractProposal) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Builder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Builder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CodeHash = append(m.CodeHash[:0], dAtA[iNdEx:postIndex]...) + if m.CodeHash == nil { + m.CodeHash = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProposal(dAtA[iNdEx:]) diff --git a/x/wasm/types/proposal_test.go b/x/wasm/types/proposal_test.go index 245184752b..581ed85d80 100644 --- a/x/wasm/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -106,6 +106,31 @@ func TestValidateStoreCodeProposal(t *testing.T) { "all good": { src: StoreCodeProposalFixture(), }, + "all good no code verification info": { + src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { + p.Source = "" + p.Builder = "" + p.CodeHash = nil + }), + }, + "source missing": { + src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { + p.Source = "" + }), + expErr: true, + }, + "builder missing": { + src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { + p.Builder = "" + }), + expErr: true, + }, + "code hash missing": { + src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { + p.CodeHash = nil + }), + expErr: true, + }, "with instantiate permission": { src: StoreCodeProposalFixture(func(p *StoreCodeProposal) { accessConfig := AccessTypeOnlyAddress.With(anyAddress) @@ -267,6 +292,31 @@ func TestValidateStoreAndInstantiateContractProposal(t *testing.T) { "all good": { src: StoreAndInstantiateContractProposalFixture(), }, + "all good no code verification info": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Source = "" + p.Builder = "" + p.CodeHash = nil + }), + }, + "source missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Source = "" + }), + expErr: true, + }, + "builder missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.Builder = "" + }), + expErr: true, + }, + "code hash missing": { + src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { + p.CodeHash = nil + }), + expErr: true, + }, "with instantiate permission": { src: StoreAndInstantiateContractProposalFixture(func(p *StoreAndInstantiateContractProposal) { accessConfig := AccessTypeOnlyAddress.With(anyAddress) @@ -647,6 +697,9 @@ func TestProposalStrings(t *testing.T) { Description: Bar Run as: cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4 WasmCode: 0102030405060708090A + Source: https://example.com/ + Builder: cosmwasm/workspace-optimizer:v0.12.8 + Code Hash: 6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D `, }, "instantiate contract": { @@ -763,6 +816,9 @@ description: Bar run_as: cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4 wasm_byte_code: AQIDBAUGBwgJCg== instantiate_permission: null +source: https://example.com/ +builder: cosmwasm/workspace-optimizer:v0.12.8 +code_hash: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d `, }, "instantiate contract": { diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index c37b6d9ddf..e62399972f 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -3,6 +3,7 @@ package types import ( "bytes" "crypto/sha256" + "encoding/hex" "encoding/json" "math/rand" @@ -200,11 +201,21 @@ func MsgExecuteContractFixture(mutators ...func(*MsgExecuteContract)) *MsgExecut func StoreCodeProposalFixture(mutators ...func(*StoreCodeProposal)) *StoreCodeProposal { const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" + wasm := []byte{0x0} + // got the value from shell sha256sum + codeHash, err := hex.DecodeString("6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D") + if err != nil { + panic(err) + } + p := &StoreCodeProposal{ Title: "Foo", Description: "Bar", RunAs: anyAddress, - WASMByteCode: []byte{0x0}, + WASMByteCode: wasm, + Source: "https://example.com/", + Builder: "cosmwasm/workspace-optimizer:v0.12.8", + CodeHash: codeHash, } for _, m := range mutators { m(p) @@ -260,6 +271,12 @@ func StoreAndInstantiateContractProposalFixture(mutators ...func(p *StoreAndInst } ) const anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" + wasm := []byte{0x0} + // got the value from shell sha256sum + codeHash, err := hex.DecodeString("6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D") + if err != nil { + panic(err) + } initMsgBz, err := json.Marshal(initMsg) if err != nil { @@ -269,7 +286,10 @@ func StoreAndInstantiateContractProposalFixture(mutators ...func(p *StoreAndInst Title: "Foo", Description: "Bar", RunAs: anyAddress, - WASMByteCode: []byte{0x0}, + WASMByteCode: wasm, + Source: "https://example.com/", + Builder: "cosmwasm/workspace-optimizer:v0.12.9", + CodeHash: codeHash, Admin: anyAddress, Label: "testing", Msg: initMsgBz, diff --git a/x/wasm/types/validation.go b/x/wasm/types/validation.go index cf6b1511b2..526a6bf55a 100644 --- a/x/wasm/types/validation.go +++ b/x/wasm/types/validation.go @@ -1,7 +1,11 @@ package types import ( + "fmt" + "net/url" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/docker/distribution/reference" ) // MaxSaltSize is the longest salt that can be used when instantiating a contract @@ -49,3 +53,27 @@ func ValidateSalt(salt []byte) error { } return nil } + +// ValidateVerificationInfo ensure source, builder and checksum constraints +func ValidateVerificationInfo(source, builder string, codeHash []byte) error { + // if any set require others to be set + if len(source) != 0 || len(builder) != 0 || codeHash != nil { + if source == "" { + return fmt.Errorf("source is required") + } + if _, err := url.ParseRequestURI(source); err != nil { + return fmt.Errorf("source: %s", err) + } + if builder == "" { + return fmt.Errorf("builder is required") + } + if _, err := reference.ParseDockerRef(builder); err != nil { + return fmt.Errorf("builder: %s", err) + } + if codeHash == nil { + return fmt.Errorf("code hash is required") + } + // code hash checksum match validation is done in the keeper, ungzipping consumes gas + } + return nil +} From 52ecb85f78a82ea7e0d9732b157f6ceea43ef840 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 29 Nov 2022 17:30:59 +0100 Subject: [PATCH 033/294] Close test dbs --- app/test_helpers.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/test_helpers.go b/app/test_helpers.go index 8c3e8c11e5..c48425f6ba 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -59,10 +59,12 @@ func setup(t testing.TB, withGenesis bool, invCheckPeriod uint, opts ...wasm.Opt snapshotDir := filepath.Join(nodeHome, "data", "snapshots") snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) require.NoError(t, err) + t.Cleanup(func() { snapshotDB.Close() }) snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) require.NoError(t, err) baseAppOpts := []func(*bam.BaseApp){bam.SetSnapshotStore(snapshotStore), bam.SetSnapshotKeepRecent(2)} db := dbm.NewMemDB() + t.Cleanup(func() { db.Close() }) app := NewWasmApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, nodeHome, invCheckPeriod, MakeEncodingConfig(), wasm.EnableAllProposals, EmptyBaseAppOptions{}, opts, baseAppOpts...) if withGenesis { return app, NewDefaultGenesisState() From f7be3ba52117ccacce6336711a1cb08f1cc96c46 Mon Sep 17 00:00:00 2001 From: Sturdy Date: Fri, 2 Dec 2022 13:31:51 +0100 Subject: [PATCH 034/294] fix: sort coins in ConvertWasmCoinsToSdkCoins --- x/wasm/keeper/handler_plugin_encoders.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index 3c4712d99b..3c7184dde4 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -331,6 +331,7 @@ func ConvertWasmCoinsToSdkCoins(coins []wasmvmtypes.Coin) (sdk.Coins, error) { } toSend = append(toSend, c) } + toSend.Sort() return toSend, nil } From a347ace2ff41539fe06c68168bc6f28d6ca9fa52 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Fri, 2 Dec 2022 14:26:01 +0100 Subject: [PATCH 035/294] Changelog for v0.30.0 (#1097) * Update changelog (cherry picked from commit e4a2bfb5616c4ce3ddbc994a17c20b6de5fccad1) * Update changelog * Update changelog * Update changelog * Update changelog * Update versions * Set release date --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++-- INTEGRATION.md | 1 + README.md | 4 +++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d347becf5e..fd4922a8a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,37 @@ ## [Unreleased](https://github.com/CosmWasm/wasmd/tree/HEAD) -[Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.29.0...HEAD) +[Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.30.0...HEAD) + +## [v0.30.0](https://github.com/CosmWasm/wasmd/tree/v0.30.0) (2022-12-02) + +[Full Changelog](https://github.com/CosmWasm/wasmd/compare/v0.29.2...v0.30.0) +* Provide source, builder and codehash information in store code proposal message[\#1072](https://github.com/CosmWasm/wasmd/pull/1072) +- Upgrade to Go v1.19 [\#1044](https://github.com/CosmWasm/wasmd/pull/1044) +- Upgrade to Cosmos-sdk to v0.45.11 [/#1096](https://github.com/CosmWasm/wasmd/pull/1096/) +- Upgrade to IBC v4.2.0 with interchain-accounts v0.2.4 [\#1088](https://github.com/CosmWasm/wasmd/pull/1088) +- Preserve contract history/ created date on genesis import [\#878](https://github.com/CosmWasm/wasmd/issues/878) +- Authz module integration - more granularity for WasmExecuteMsg authorizations [\#803](https://github.com/CosmWasm/wasmd/issues/803) +- StoreAndInstantiate gov proposal [\#785](https://github.com/CosmWasm/wasmd/issues/785) +- Start developer guide for contributors [\#654](https://github.com/CosmWasm/wasmd/issues/654) + +### Notable changes: +- IBC fee middleware is setup in `app.go`. Please note that it can be enabled with new channels only. A nice read is this [article](https://medium.com/the-interchain-foundation/ibc-relaying-as-a-service-the-in-protocol-incentivization-story-2c008861a957). +- Authz for wasm contracts can be granted via `wasmd tx wasm grant` and executed via `wasmd tx authz exec` command +- Go v1.19 required to prevent a mixed chain setup with older versions. Just to be on the safe side. +- Store code proposal types have new metadata fields added that can help to build client side tooling to verify the wasm contract in the proposal + +### Migration notes: +- See ibc-go [migration notes](https://github.com/cosmos/ibc-go/blob/v4.2.0/docs/migrations) +- See interchain-accounts [`MsgRegisterAccount.Version` field](https://github.com/cosmos/interchain-accounts-demo/compare/v0.1.0...v0.2.4#diff-ac8bca25810de6d3eef95f74fc9acf2223f3687822e6227b584e0d3b40db6566). Full diff [v0.1.0 to v0.2.4](https://github.com/cosmos/interchain-accounts-demo/compare/v0.1.0...v0.2.4) + +## [v0.29.2](https://github.com/CosmWasm/wasmd/tree/v0.29.2) (2022-11-08) + +- Fixes missing instantiate-anyof-addresses flag declaration for gov [/#1084](https://github.com/CosmWasm/wasmd/issues/1084) + +## [v0.29.1](https://github.com/CosmWasm/wasmd/tree/v0.29.1) (2022-10-14) + +- Upgrade to Cosmos-sdk to v45.9 [/#1052](https://github.com/CosmWasm/wasmd/pull/1052/) ## [v0.29.0](https://github.com/CosmWasm/wasmd/tree/v0.29.0) (2022-10-10) @@ -12,7 +42,6 @@ - Allow AccessConfig to use a list of addresses instead of just a single address [\#945](https://github.com/CosmWasm/wasmd/issues/945) - Make contract addresses predictable \("deterministic"\) [\#942](https://github.com/CosmWasm/wasmd/issues/942) - Add query for the total supply of a coin [\#903](https://github.com/CosmWasm/wasmd/pull/903) ([larry0x](https://github.com/larry0x)) -- Upgrade go to v1.19 [\#1044](https://github.com/CosmWasm/wasmd/pull/1044) - Upgrade go to v1.18 [\#866]https://github.com/CosmWasm/wasmd/pull/866/) ([faddat](https://github.com/faddat)) - Upgrade to ibc-go v3.3.0 REQUIRES [MIGRATION](https://github.com/cosmos/ibc-go/blob/v3.2.3/docs/migrations/support-denoms-with-slashes.md) [\#1016](https://github.com/CosmWasm/wasmd/pull/1016) - Upgrade to cosmos-sdk v0.45.8 [\#964](https://github.com/CosmWasm/wasmd/pull/964/) ([faddat](https://github.com/faddat)) diff --git a/INTEGRATION.md b/INTEGRATION.md index b01d1e4229..253d1f71e0 100644 --- a/INTEGRATION.md +++ b/INTEGRATION.md @@ -19,6 +19,7 @@ hardware it runs on. | wasmd | Cosmos SDK | |:-----:|:----------:| +| v0.30 | v0.45.11 | | v0.29 | v0.45.8 | | v0.28 | v0.45.5 | | v0.27 | v0.45.4 | diff --git a/README.md b/README.md index ebdc070de3..367492f4f1 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ compatibility list: | wasmd | wasmvm | cosmwasm-vm | cosmwasm-std | |-------|--------------|-------------|--------------| +| 0.30 | v1.1.0 | | 1.0-1.1 | | 0.29 | v1.1.0 | | 1.0-1.1 | | 0.28 | v1.0.0 | | 1.0-1.1 | | 0.27 | v1.0.0 | | 1.0 | @@ -115,7 +116,8 @@ The protobuf files for this project are published automatically to the [buf repo | wasmd version | buf tag | |---------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| 0.26.x | [51931206dbe09529c1819a8a2863d291035a2549](https://buf.build/cosmwasm/wasmd/tree/51931206dbe09529c1819a8a2863d291035a2549:cosmwasm/wasm/v1) | +| 0.30.x | [6508ee062011440c907de6f5c40398ea](https://buf.build/cosmwasm/wasmd/tree/6508ee062011440c907de6f5c40398ea:cosmwasm/wasm/v1) | +| 0.29.x | [51931206dbe09529c1819a8a2863d291035a2549](https://buf.build/cosmwasm/wasmd/tree/51931206dbe09529c1819a8a2863d291035a2549:cosmwasm/wasm/v1) | Generate protobuf ```shell script From bc00a6bae3beb9c03eb8dd319325c148829817c0 Mon Sep 17 00:00:00 2001 From: GNaD13 <89174180+GNaD13@users.noreply.github.com> Date: Fri, 2 Dec 2022 21:04:32 +0700 Subject: [PATCH 036/294] Add proposal instantiate 2 (#1106) * add proposal instantiate 2 * add basic validate test * test case for validate basic * add integration test * add cli * fix lint * add new func init proposal * make format --- docs/proto/proto-docs.md | 25 + proto/cosmwasm/wasm/v1/proposal.proto | 28 + x/wasm/client/cli/gov_tx.go | 66 ++ x/wasm/client/proposal_handler.go | 1 + x/wasm/keeper/proposal_handler.go | 34 + x/wasm/keeper/proposal_integration_test.go | 64 ++ x/wasm/types/authz.pb.go | 3 +- x/wasm/types/codec.go | 2 + x/wasm/types/genesis.pb.go | 3 +- x/wasm/types/ibc.pb.go | 3 +- x/wasm/types/proposal.go | 112 +++ x/wasm/types/proposal.pb.go | 763 +++++++++++++++++++-- x/wasm/types/proposal_test.go | 99 +++ x/wasm/types/query.pb.go | 3 +- x/wasm/types/query.pb.gw.go | 3 +- x/wasm/types/test_fixtures.go | 40 ++ x/wasm/types/tx.pb.go | 3 +- x/wasm/types/types.pb.go | 3 +- 18 files changed, 1172 insertions(+), 83 deletions(-) diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index abd59632e5..5609e3a0af 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -61,6 +61,7 @@ - [AccessConfigUpdate](#cosmwasm.wasm.v1.AccessConfigUpdate) - [ClearAdminProposal](#cosmwasm.wasm.v1.ClearAdminProposal) - [ExecuteContractProposal](#cosmwasm.wasm.v1.ExecuteContractProposal) + - [InstantiateContract2Proposal](#cosmwasm.wasm.v1.InstantiateContract2Proposal) - [InstantiateContractProposal](#cosmwasm.wasm.v1.InstantiateContractProposal) - [MigrateContractProposal](#cosmwasm.wasm.v1.MigrateContractProposal) - [PinCodesProposal](#cosmwasm.wasm.v1.PinCodesProposal) @@ -923,6 +924,30 @@ contract. + + +### InstantiateContract2Proposal +InstantiateContract2Proposal gov proposal content type to instantiate contract 2 + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `title` | [string](#string) | | Title is a short summary | +| `description` | [string](#string) | | Description is a human readable text | +| `run_as` | [string](#string) | | RunAs is the address that is passed to the contract's enviroment as sender | +| `admin` | [string](#string) | | Admin is an optional address that can execute migrations | +| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored WASM code | +| `label` | [string](#string) | | Label is optional metadata to be stored with a constract instance. | +| `msg` | [bytes](#bytes) | | Msg json encode message to be passed to the contract on instantiation | +| `funds` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | Funds coins that are transferred to the contract on instantiation | +| `salt` | [bytes](#bytes) | | Salt is an arbitrary value provided by the sender. Size can be 1 to 64. | +| `fix_msg` | [bool](#bool) | | FixMsg include the msg value into the hash for the predictable address. Default is false | + + + + + + ### InstantiateContractProposal diff --git a/proto/cosmwasm/wasm/v1/proposal.proto b/proto/cosmwasm/wasm/v1/proposal.proto index b8a143b672..a419fea7cc 100644 --- a/proto/cosmwasm/wasm/v1/proposal.proto +++ b/proto/cosmwasm/wasm/v1/proposal.proto @@ -60,6 +60,34 @@ message InstantiateContractProposal { ]; } +// InstantiateContract2Proposal gov proposal content type to instantiate contract 2 +message InstantiateContract2Proposal { + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's enviroment as sender + string run_as = 3; + // Admin is an optional address that can execute migrations + string admin = 4; + // CodeID is the reference to the stored WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a constract instance. + string label = 6; + // Msg json encode message to be passed to the contract on instantiation + bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + bytes salt = 9; + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + bool fix_msg = 10; +} + // MigrateContractProposal gov proposal content type to migrate a contract. message MigrateContractProposal { // Title is a short summary diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 3c8a7b9f3a..3f5ecd033f 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -3,6 +3,7 @@ package cli import ( "bytes" "crypto/sha256" + "encoding/hex" "fmt" "net/url" "strconv" @@ -199,6 +200,71 @@ func ProposalInstantiateContractCmd() *cobra.Command { return cmd } +func ProposalInstantiateContract2Cmd() *cobra.Command { + decoder := newArgDecoder(hex.DecodeString) + cmd := &cobra.Command{ + Use: "instantiate-contract-2 [code_id_int64] [json_encoded_init_args] [salt] --label [text] --title [text] --description [text] --run-as [address] --admin [address,optional] --amount [coins,optional] --fix-msg [bool,optional]", + Short: "Submit an instantiate wasm contract proposal with predictable address", + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, proposalTitle, proposalDescr, deposit, err := getProposalInfo(cmd) + if err != nil { + return err + } + + src, err := parseInstantiateArgs(args[0], args[1], clientCtx.FromAddress, cmd.Flags()) + if err != nil { + return err + } + + runAs, err := cmd.Flags().GetString(flagRunAs) + if err != nil { + return fmt.Errorf("run-as: %s", err) + } + if len(runAs) == 0 { + return errors.New("run-as address is required") + } + + salt, err := decoder.DecodeString(args[2]) + if err != nil { + return fmt.Errorf("salt: %w", err) + } + + fixMsg, err := cmd.Flags().GetBool(flagFixMsg) + if err != nil { + return fmt.Errorf("fix msg: %w", err) + } + + content := types.NewInstantiateContract2Proposal(proposalTitle, proposalDescr, runAs, src.Admin, src.CodeID, src.Label, src.Msg, src.Funds, salt, fixMsg) + + msg, err := govtypes.NewMsgSubmitProposal(content, deposit, clientCtx.GetFromAddress()) + if err != nil { + return err + } + if err = msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + SilenceUsage: true, + } + + cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") + cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") + cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract and passed to the contract as sender on proposal execution") + cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") + cmd.Flags().Bool(flagFixMsg, false, "An optional flag to include the json_encoded_init_args for the predictable address generation mode") + decoder.RegisterFlags(cmd.PersistentFlags(), "salt") + + // proposal flags + cmd.Flags().String(cli.FlagTitle, "", "Title of proposal") + cmd.Flags().String(cli.FlagDescription, "", "Description of proposal") + cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal") + return cmd +} + func ProposalStoreAndInstantiateContractCmd() *cobra.Command { cmd := &cobra.Command{ Use: "store-instantiate [wasm file] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address]" + diff --git a/x/wasm/client/proposal_handler.go b/x/wasm/client/proposal_handler.go index db51f7b3ac..286d37d197 100644 --- a/x/wasm/client/proposal_handler.go +++ b/x/wasm/client/proposal_handler.go @@ -21,4 +21,5 @@ var ProposalHandlers = []govclient.ProposalHandler{ govclient.NewProposalHandler(cli.ProposalUnpinCodesCmd, rest.UnpinCodeProposalHandler), govclient.NewProposalHandler(cli.ProposalUpdateInstantiateConfigCmd, rest.UpdateInstantiateConfigProposalHandler), govclient.NewProposalHandler(cli.ProposalStoreAndInstantiateContractCmd, rest.EmptyRestHandler), + govclient.NewProposalHandler(cli.ProposalInstantiateContract2Cmd, rest.EmptyRestHandler), } diff --git a/x/wasm/keeper/proposal_handler.go b/x/wasm/keeper/proposal_handler.go index 08f2774f3e..efcf49c481 100644 --- a/x/wasm/keeper/proposal_handler.go +++ b/x/wasm/keeper/proposal_handler.go @@ -35,6 +35,8 @@ func NewWasmProposalHandlerX(k types.ContractOpsKeeper, enabledProposalTypes []t return handleStoreCodeProposal(ctx, k, *c) case *types.InstantiateContractProposal: return handleInstantiateProposal(ctx, k, *c) + case *types.InstantiateContract2Proposal: + return handleInstantiate2Proposal(ctx, k, *c) case *types.MigrateContractProposal: return handleMigrateProposal(ctx, k, *c) case *types.SudoContractProposal: @@ -111,6 +113,38 @@ func handleInstantiateProposal(ctx sdk.Context, k types.ContractOpsKeeper, p typ return nil } +func handleInstantiate2Proposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.InstantiateContract2Proposal) error { + // Validatebasic with proposal + if err := p.ValidateBasic(); err != nil { + return err + } + + // Get runAsAddr as AccAddress + runAsAddr, err := sdk.AccAddressFromBech32(p.RunAs) + if err != nil { + return sdkerrors.Wrap(err, "run as address") + } + + // Get admin address + var adminAddr sdk.AccAddress + if p.Admin != "" { + if adminAddr, err = sdk.AccAddressFromBech32(p.Admin); err != nil { + return sdkerrors.Wrap(err, "admin") + } + } + + _, data, err := k.Instantiate2(ctx, p.CodeID, runAsAddr, adminAddr, p.Msg, p.Label, p.Funds, p.Salt, p.FixMsg) + if err != nil { + return err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeGovContractResult, + sdk.NewAttribute(types.AttributeKeyResultDataHex, hex.EncodeToString(data)), + )) + return nil +} + func handleStoreAndInstantiateContractProposal(ctx sdk.Context, k types.ContractOpsKeeper, p types.StoreAndInstantiateContractProposal) error { if err := p.ValidateBasic(); err != nil { return err diff --git a/x/wasm/keeper/proposal_integration_test.go b/x/wasm/keeper/proposal_integration_test.go index 74ef6928b9..7ea9f657d9 100644 --- a/x/wasm/keeper/proposal_integration_test.go +++ b/x/wasm/keeper/proposal_integration_test.go @@ -141,6 +141,70 @@ func TestInstantiateProposal(t *testing.T) { require.NotEmpty(t, em.Events()[2].Attributes[0]) } +func TestInstantiate2Proposal(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, "staking") + govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper + wasmKeeper.SetParams(ctx, types.Params{ + CodeUploadAccess: types.AllowNobody, + InstantiateDefaultPermission: types.AccessTypeNobody, + }) + + wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") + require.NoError(t, err) + + codeInfo := types.CodeInfoFixture(types.WithSHA256CodeHash(wasmCode)) + err = wasmKeeper.importCode(ctx, 1, codeInfo, wasmCode) + require.NoError(t, err) + + var ( + oneAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, types.ContractAddrLen) + otherAddress sdk.AccAddress = bytes.Repeat([]byte{0x2}, types.ContractAddrLen) + label string = "label" + salt []byte = []byte("mySalt") + ) + src := types.InstantiateContract2ProposalFixture(func(p *types.InstantiateContract2Proposal) { + p.CodeID = firstCodeID + p.RunAs = oneAddress.String() + p.Admin = otherAddress.String() + p.Label = label + p.Salt = salt + }) + contractAddress := BuildContractAddressPredictable(codeInfo.CodeHash, oneAddress, salt, []byte{}) + + em := sdk.NewEventManager() + + // when stored + storedProposal, err := govKeeper.SubmitProposal(ctx, src) + require.NoError(t, err) + + // and proposal execute + handler := govKeeper.Router().GetRoute(storedProposal.ProposalRoute()) + err = handler(ctx.WithEventManager(em), storedProposal.GetContent()) + require.NoError(t, err) + + cInfo := wasmKeeper.GetContractInfo(ctx, contractAddress) + require.NotNil(t, cInfo) + + assert.Equal(t, uint64(1), cInfo.CodeID) + assert.Equal(t, oneAddress.String(), cInfo.Creator) + assert.Equal(t, otherAddress.String(), cInfo.Admin) + assert.Equal(t, "label", cInfo.Label) + expHistory := []types.ContractCodeHistoryEntry{{ + Operation: types.ContractCodeHistoryOperationTypeInit, + CodeID: src.CodeID, + Updated: types.NewAbsoluteTxPosition(ctx), + Msg: src.Msg, + }} + assert.Equal(t, expHistory, wasmKeeper.GetContractHistory(ctx, contractAddress)) + // and event + require.Len(t, em.Events(), 3, "%#v", em.Events()) + require.Equal(t, types.EventTypeInstantiate, em.Events()[0].Type) + require.Equal(t, types.WasmModuleEventType, em.Events()[1].Type) + require.Equal(t, types.EventTypeGovContractResult, em.Events()[2].Type) + require.Len(t, em.Events()[2].Attributes, 1) + require.NotEmpty(t, em.Events()[2].Attributes[0]) +} + func TestInstantiateProposal_NoAdmin(t *testing.T) { ctx, keepers := CreateTestInput(t, false, "staking") govKeeper, wasmKeeper := keepers.GovKeeper, keepers.WasmKeeper diff --git a/x/wasm/types/authz.pb.go b/x/wasm/types/authz.pb.go index 549b558aa1..f98d24fa93 100644 --- a/x/wasm/types/authz.pb.go +++ b/x/wasm/types/authz.pb.go @@ -18,9 +18,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) diff --git a/x/wasm/types/codec.go b/x/wasm/types/codec.go index 64b4f28e41..d1c2b9eb92 100644 --- a/x/wasm/types/codec.go +++ b/x/wasm/types/codec.go @@ -24,6 +24,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { //nolint:staticcheck cdc.RegisterConcrete(&UnpinCodesProposal{}, "wasm/UnpinCodesProposal", nil) cdc.RegisterConcrete(&StoreCodeProposal{}, "wasm/StoreCodeProposal", nil) cdc.RegisterConcrete(&InstantiateContractProposal{}, "wasm/InstantiateContractProposal", nil) + cdc.RegisterConcrete(&InstantiateContract2Proposal{}, "wasm/InstantiateContract2Proposal", nil) cdc.RegisterConcrete(&MigrateContractProposal{}, "wasm/MigrateContractProposal", nil) cdc.RegisterConcrete(&SudoContractProposal{}, "wasm/SudoContractProposal", nil) cdc.RegisterConcrete(&ExecuteContractProposal{}, "wasm/ExecuteContractProposal", nil) @@ -65,6 +66,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { (*govtypes.Content)(nil), &StoreCodeProposal{}, &InstantiateContractProposal{}, + &InstantiateContract2Proposal{}, &MigrateContractProposal{}, &SudoContractProposal{}, &ExecuteContractProposal{}, diff --git a/x/wasm/types/genesis.pb.go b/x/wasm/types/genesis.pb.go index 3f7037985a..b080905ab4 100644 --- a/x/wasm/types/genesis.pb.go +++ b/x/wasm/types/genesis.pb.go @@ -14,9 +14,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) diff --git a/x/wasm/types/ibc.pb.go b/x/wasm/types/ibc.pb.go index bedc1954ab..370b4aef85 100644 --- a/x/wasm/types/ibc.pb.go +++ b/x/wasm/types/ibc.pb.go @@ -14,9 +14,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index 1597818597..6386f08716 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -16,6 +16,7 @@ type ProposalType string const ( ProposalTypeStoreCode ProposalType = "StoreCode" ProposalTypeInstantiateContract ProposalType = "InstantiateContract" + ProposalTypeInstantiateContract2 ProposalType = "InstantiateContract2" ProposalTypeMigrateContract ProposalType = "MigrateContract" ProposalTypeSudoContract ProposalType = "SudoContract" ProposalTypeExecuteContract ProposalType = "ExecuteContract" @@ -34,6 +35,7 @@ var DisableAllProposals []ProposalType var EnableAllProposals = []ProposalType{ ProposalTypeStoreCode, ProposalTypeInstantiateContract, + ProposalTypeInstantiateContract2, ProposalTypeMigrateContract, ProposalTypeSudoContract, ProposalTypeExecuteContract, @@ -66,6 +68,7 @@ func ConvertToProposals(keys []string) ([]ProposalType, error) { func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypeStoreCode)) govtypes.RegisterProposalType(string(ProposalTypeInstantiateContract)) + govtypes.RegisterProposalType(string(ProposalTypeInstantiateContract2)) govtypes.RegisterProposalType(string(ProposalTypeMigrateContract)) govtypes.RegisterProposalType(string(ProposalTypeSudoContract)) govtypes.RegisterProposalType(string(ProposalTypeExecuteContract)) @@ -77,6 +80,7 @@ func init() { // register new content types with the sdk govtypes.RegisterProposalType(string(ProposalTypeStoreAndInstantiateContractProposal)) govtypes.RegisterProposalTypeCodec(&StoreCodeProposal{}, "wasm/StoreCodeProposal") govtypes.RegisterProposalTypeCodec(&InstantiateContractProposal{}, "wasm/InstantiateContractProposal") + govtypes.RegisterProposalTypeCodec(&InstantiateContract2Proposal{}, "wasm/InstantiateContract2Proposal") govtypes.RegisterProposalTypeCodec(&MigrateContractProposal{}, "wasm/MigrateContractProposal") govtypes.RegisterProposalTypeCodec(&SudoContractProposal{}, "wasm/SudoContractProposal") govtypes.RegisterProposalTypeCodec(&ExecuteContractProposal{}, "wasm/ExecuteContractProposal") @@ -271,6 +275,114 @@ func (p InstantiateContractProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewInstantiateContract2Proposal( + title string, + description string, + runAs string, + admin string, + codeID uint64, + label string, + msg RawContractMessage, + funds sdk.Coins, + salt []byte, + fixMsg bool, +) *InstantiateContract2Proposal { + return &InstantiateContract2Proposal{title, description, runAs, admin, codeID, label, msg, funds, salt, fixMsg} +} + +// ProposalRoute returns the routing key of a parameter change proposal. +func (p InstantiateContract2Proposal) ProposalRoute() string { return RouterKey } + +// GetTitle returns the title of the proposal +func (p *InstantiateContract2Proposal) GetTitle() string { return p.Title } + +// GetDescription returns the human readable description of the proposal +func (p InstantiateContract2Proposal) GetDescription() string { return p.Description } + +// ProposalType returns the type +func (p InstantiateContract2Proposal) ProposalType() string { + return string(ProposalTypeInstantiateContract2) +} + +// ValidateBasic validates the proposal +func (p InstantiateContract2Proposal) ValidateBasic() error { + // Validate title and description + if err := validateProposalCommons(p.Title, p.Description); err != nil { + return err + } + // Validate run as + if _, err := sdk.AccAddressFromBech32(p.RunAs); err != nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "run as") + } + // Validate admin + if len(p.Admin) != 0 { + if _, err := sdk.AccAddressFromBech32(p.Admin); err != nil { + return err + } + } + // Validate codeid + if p.CodeID == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "code id is required") + } + // Validate label + if err := ValidateLabel(p.Label); err != nil { + return err + } + // Validate msg + if err := p.Msg.ValidateBasic(); err != nil { + return sdkerrors.Wrap(err, "payload msg") + } + // Validate funds + if !p.Funds.IsValid() { + return sdkerrors.ErrInvalidCoins + } + // Validate salt + if len(p.Salt) == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "salt is required") + } + return nil +} + +// String implements the Stringer interface. +func (p InstantiateContract2Proposal) String() string { + return fmt.Sprintf(`Instantiate Code Proposal: + Title: %s + Description: %s + Run as: %s + Admin: %s + Code id: %d + Label: %s + Msg: %q + Funds: %s + Salt: %X +`, p.Title, p.Description, p.RunAs, p.Admin, p.CodeID, p.Label, p.Msg, p.Funds, p.Salt) +} + +// MarshalYAML pretty prints the init message +func (p InstantiateContract2Proposal) MarshalYAML() (interface{}, error) { + return struct { + Title string `yaml:"title"` + Description string `yaml:"description"` + RunAs string `yaml:"run_as"` + Admin string `yaml:"admin"` + CodeID uint64 `yaml:"code_id"` + Label string `yaml:"label"` + Msg string `yaml:"msg"` + Funds sdk.Coins `yaml:"funds"` + Salt string `yaml:"salt"` + }{ + Title: p.Title, + Description: p.Description, + RunAs: p.RunAs, + Admin: p.Admin, + CodeID: p.CodeID, + Label: p.Label, + Msg: string(p.Msg), + Funds: p.Funds, + Salt: base64.StdEncoding.EncodeToString(p.Salt), + }, nil +} + func NewStoreAndInstantiateContractProposal( title string, description string, diff --git a/x/wasm/types/proposal.pb.go b/x/wasm/types/proposal.pb.go index dbce4e7172..6062ffdbfa 100644 --- a/x/wasm/types/proposal.pb.go +++ b/x/wasm/types/proposal.pb.go @@ -148,6 +148,68 @@ func (m *InstantiateContractProposal) XXX_DiscardUnknown() { var xxx_messageInfo_InstantiateContractProposal proto.InternalMessageInfo +// InstantiateContract2Proposal gov proposal content type to instantiate contract 2 +type InstantiateContract2Proposal struct { + // Title is a short summary + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + // Description is a human readable text + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // RunAs is the address that is passed to the contract's environment as sender + RunAs string `protobuf:"bytes,3,opt,name=run_as,json=runAs,proto3" json:"run_as,omitempty"` + // Admin is an optional address that can execute migrations + Admin string `protobuf:"bytes,4,opt,name=admin,proto3" json:"admin,omitempty"` + // CodeID is the reference to the stored WASM code + CodeID uint64 `protobuf:"varint,5,opt,name=code_id,json=codeId,proto3" json:"code_id,omitempty"` + // Label is optional metadata to be stored with a constract instance. + Label string `protobuf:"bytes,6,opt,name=label,proto3" json:"label,omitempty"` + // Msg json encode message to be passed to the contract on instantiation + Msg RawContractMessage `protobuf:"bytes,7,opt,name=msg,proto3,casttype=RawContractMessage" json:"msg,omitempty"` + // Funds coins that are transferred to the contract on instantiation + Funds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,8,rep,name=funds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"funds"` + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + Salt []byte `protobuf:"bytes,9,opt,name=salt,proto3" json:"salt,omitempty"` + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + FixMsg bool `protobuf:"varint,10,opt,name=fix_msg,json=fixMsg,proto3" json:"fix_msg,omitempty"` +} + +func (m *InstantiateContract2Proposal) Reset() { *m = InstantiateContract2Proposal{} } +func (*InstantiateContract2Proposal) ProtoMessage() {} +func (*InstantiateContract2Proposal) Descriptor() ([]byte, []int) { + return fileDescriptor_be6422d717c730cb, []int{2} +} + +func (m *InstantiateContract2Proposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *InstantiateContract2Proposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InstantiateContract2Proposal.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *InstantiateContract2Proposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_InstantiateContract2Proposal.Merge(m, src) +} + +func (m *InstantiateContract2Proposal) XXX_Size() int { + return m.Size() +} + +func (m *InstantiateContract2Proposal) XXX_DiscardUnknown() { + xxx_messageInfo_InstantiateContract2Proposal.DiscardUnknown(m) +} + +var xxx_messageInfo_InstantiateContract2Proposal proto.InternalMessageInfo + // MigrateContractProposal gov proposal content type to migrate a contract. type MigrateContractProposal struct { // Title is a short summary @@ -165,7 +227,7 @@ type MigrateContractProposal struct { func (m *MigrateContractProposal) Reset() { *m = MigrateContractProposal{} } func (*MigrateContractProposal) ProtoMessage() {} func (*MigrateContractProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{2} + return fileDescriptor_be6422d717c730cb, []int{3} } func (m *MigrateContractProposal) XXX_Unmarshal(b []byte) error { @@ -214,7 +276,7 @@ type SudoContractProposal struct { func (m *SudoContractProposal) Reset() { *m = SudoContractProposal{} } func (*SudoContractProposal) ProtoMessage() {} func (*SudoContractProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{3} + return fileDescriptor_be6422d717c730cb, []int{4} } func (m *SudoContractProposal) XXX_Unmarshal(b []byte) error { @@ -268,7 +330,7 @@ type ExecuteContractProposal struct { func (m *ExecuteContractProposal) Reset() { *m = ExecuteContractProposal{} } func (*ExecuteContractProposal) ProtoMessage() {} func (*ExecuteContractProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{4} + return fileDescriptor_be6422d717c730cb, []int{5} } func (m *ExecuteContractProposal) XXX_Unmarshal(b []byte) error { @@ -317,7 +379,7 @@ type UpdateAdminProposal struct { func (m *UpdateAdminProposal) Reset() { *m = UpdateAdminProposal{} } func (*UpdateAdminProposal) ProtoMessage() {} func (*UpdateAdminProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{5} + return fileDescriptor_be6422d717c730cb, []int{6} } func (m *UpdateAdminProposal) XXX_Unmarshal(b []byte) error { @@ -365,7 +427,7 @@ type ClearAdminProposal struct { func (m *ClearAdminProposal) Reset() { *m = ClearAdminProposal{} } func (*ClearAdminProposal) ProtoMessage() {} func (*ClearAdminProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{6} + return fileDescriptor_be6422d717c730cb, []int{7} } func (m *ClearAdminProposal) XXX_Unmarshal(b []byte) error { @@ -413,7 +475,7 @@ type PinCodesProposal struct { func (m *PinCodesProposal) Reset() { *m = PinCodesProposal{} } func (*PinCodesProposal) ProtoMessage() {} func (*PinCodesProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{7} + return fileDescriptor_be6422d717c730cb, []int{8} } func (m *PinCodesProposal) XXX_Unmarshal(b []byte) error { @@ -461,7 +523,7 @@ type UnpinCodesProposal struct { func (m *UnpinCodesProposal) Reset() { *m = UnpinCodesProposal{} } func (*UnpinCodesProposal) ProtoMessage() {} func (*UnpinCodesProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{8} + return fileDescriptor_be6422d717c730cb, []int{9} } func (m *UnpinCodesProposal) XXX_Unmarshal(b []byte) error { @@ -507,7 +569,7 @@ type AccessConfigUpdate struct { func (m *AccessConfigUpdate) Reset() { *m = AccessConfigUpdate{} } func (*AccessConfigUpdate) ProtoMessage() {} func (*AccessConfigUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{9} + return fileDescriptor_be6422d717c730cb, []int{10} } func (m *AccessConfigUpdate) XXX_Unmarshal(b []byte) error { @@ -556,7 +618,7 @@ type UpdateInstantiateConfigProposal struct { func (m *UpdateInstantiateConfigProposal) Reset() { *m = UpdateInstantiateConfigProposal{} } func (*UpdateInstantiateConfigProposal) ProtoMessage() {} func (*UpdateInstantiateConfigProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{10} + return fileDescriptor_be6422d717c730cb, []int{11} } func (m *UpdateInstantiateConfigProposal) XXX_Unmarshal(b []byte) error { @@ -626,7 +688,7 @@ type StoreAndInstantiateContractProposal struct { func (m *StoreAndInstantiateContractProposal) Reset() { *m = StoreAndInstantiateContractProposal{} } func (*StoreAndInstantiateContractProposal) ProtoMessage() {} func (*StoreAndInstantiateContractProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_be6422d717c730cb, []int{11} + return fileDescriptor_be6422d717c730cb, []int{12} } func (m *StoreAndInstantiateContractProposal) XXX_Unmarshal(b []byte) error { @@ -663,6 +725,7 @@ var xxx_messageInfo_StoreAndInstantiateContractProposal proto.InternalMessageInf func init() { proto.RegisterType((*StoreCodeProposal)(nil), "cosmwasm.wasm.v1.StoreCodeProposal") proto.RegisterType((*InstantiateContractProposal)(nil), "cosmwasm.wasm.v1.InstantiateContractProposal") + proto.RegisterType((*InstantiateContract2Proposal)(nil), "cosmwasm.wasm.v1.InstantiateContract2Proposal") proto.RegisterType((*MigrateContractProposal)(nil), "cosmwasm.wasm.v1.MigrateContractProposal") proto.RegisterType((*SudoContractProposal)(nil), "cosmwasm.wasm.v1.SudoContractProposal") proto.RegisterType((*ExecuteContractProposal)(nil), "cosmwasm.wasm.v1.ExecuteContractProposal") @@ -678,66 +741,69 @@ func init() { func init() { proto.RegisterFile("cosmwasm/wasm/v1/proposal.proto", fileDescriptor_be6422d717c730cb) } var fileDescriptor_be6422d717c730cb = []byte{ - // 936 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xcf, 0xe4, 0x8f, 0xe3, 0xbc, 0x04, 0x08, 0xde, 0xb4, 0x6b, 0xba, 0x60, 0x47, 0x5e, 0xb4, - 0xca, 0x05, 0x87, 0x14, 0x09, 0x01, 0xb7, 0x38, 0x20, 0xd1, 0x15, 0x95, 0x2a, 0x57, 0xd5, 0x4a, - 0x20, 0x11, 0x4d, 0xec, 0x69, 0x62, 0x91, 0x78, 0x22, 0x8f, 0xdd, 0x6e, 0xbf, 0x05, 0x48, 0x88, + // 981 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x8f, 0xd3, 0xc4, 0x71, 0x5e, 0x02, 0x84, 0xd9, 0xb4, 0x35, 0xdd, 0xc5, 0x8e, 0xbc, 0x68, + 0x95, 0x0b, 0x09, 0x29, 0x12, 0x02, 0x6e, 0x71, 0x40, 0xa2, 0x2b, 0x2a, 0x55, 0xae, 0xaa, 0x95, + 0x40, 0x22, 0x9a, 0xd8, 0x93, 0xc4, 0x22, 0xf1, 0x44, 0x1e, 0xbb, 0x7f, 0xbe, 0x05, 0x48, 0x88, 0x13, 0x1f, 0x00, 0xed, 0x05, 0x71, 0xe7, 0x03, 0x54, 0x9c, 0xf6, 0xb8, 0x27, 0xc3, 0xa6, 0x47, - 0x6e, 0x3d, 0x72, 0x42, 0x33, 0xe3, 0x84, 0xb4, 0xbb, 0xcd, 0xee, 0x8a, 0xa6, 0xd2, 0x5e, 0x9c, - 0xbc, 0x79, 0x6f, 0xe6, 0xfd, 0xde, 0x4f, 0x6f, 0xe6, 0xfd, 0xc0, 0xf4, 0x28, 0x9b, 0x1c, 0x63, - 0x36, 0x69, 0x8b, 0xcf, 0x51, 0xa7, 0x3d, 0x8d, 0xe8, 0x94, 0x32, 0x3c, 0xb6, 0xa7, 0x11, 0x8d, - 0xa9, 0x56, 0x9f, 0x07, 0xd8, 0xe2, 0x73, 0xd4, 0xd9, 0x6a, 0x0c, 0xe9, 0x90, 0x0a, 0x67, 0x9b, - 0xff, 0x93, 0x71, 0x5b, 0x06, 0x8f, 0xa3, 0xac, 0x3d, 0xc0, 0x8c, 0xb4, 0x8f, 0x3a, 0x03, 0x12, - 0xe3, 0x4e, 0xdb, 0xa3, 0x41, 0x98, 0xf9, 0xdf, 0x7d, 0x26, 0x51, 0x7c, 0x32, 0x25, 0x4c, 0x7a, - 0xad, 0xbf, 0xf3, 0xf0, 0xf6, 0x7e, 0x4c, 0x23, 0xd2, 0xa3, 0x3e, 0xd9, 0xcb, 0x10, 0x68, 0x0d, - 0x28, 0xc5, 0x41, 0x3c, 0x26, 0x3a, 0x6a, 0xa2, 0x56, 0xc5, 0x95, 0x86, 0xd6, 0x84, 0xaa, 0x4f, - 0x98, 0x17, 0x05, 0xd3, 0x38, 0xa0, 0xa1, 0x9e, 0x17, 0xbe, 0xe5, 0x25, 0x6d, 0x03, 0x94, 0x28, - 0x09, 0xfb, 0x98, 0xe9, 0x05, 0xb9, 0x31, 0x4a, 0xc2, 0x2e, 0xd3, 0x3e, 0x86, 0x37, 0x79, 0xee, - 0xfe, 0xe0, 0x24, 0x26, 0x7d, 0x8f, 0xfa, 0x44, 0x2f, 0x36, 0x51, 0xab, 0xe6, 0xd4, 0x67, 0xa9, - 0x59, 0x7b, 0xd0, 0xdd, 0xdf, 0x75, 0x4e, 0x62, 0x01, 0xc0, 0xad, 0xf1, 0xb8, 0xb9, 0xa5, 0x1d, - 0xc0, 0x66, 0x10, 0xb2, 0x18, 0x87, 0x71, 0x80, 0x63, 0xd2, 0x9f, 0x92, 0x68, 0x12, 0x30, 0xc6, - 0x73, 0x97, 0x9b, 0xa8, 0x55, 0xdd, 0x36, 0xec, 0xcb, 0x1c, 0xd9, 0x5d, 0xcf, 0x23, 0x8c, 0xf5, - 0x68, 0x78, 0x18, 0x0c, 0xdd, 0x8d, 0xa5, 0xdd, 0x7b, 0x8b, 0xcd, 0xda, 0x7b, 0x00, 0x49, 0x38, - 0x0d, 0x42, 0x09, 0x45, 0x6d, 0xa2, 0x96, 0xea, 0x56, 0xc4, 0x8a, 0xc8, 0xba, 0x09, 0x0a, 0xa3, - 0x49, 0xe4, 0x11, 0xbd, 0x22, 0x8a, 0xc8, 0x2c, 0x4d, 0x87, 0xf2, 0x20, 0x09, 0xc6, 0x3e, 0x89, - 0x74, 0x10, 0x8e, 0xb9, 0xa9, 0xdd, 0x81, 0x0a, 0x3f, 0xaa, 0x3f, 0xc2, 0x6c, 0xa4, 0x57, 0x79, - 0x69, 0xae, 0xca, 0x17, 0xbe, 0xc4, 0x6c, 0x74, 0xbf, 0xa8, 0x96, 0xea, 0xca, 0xfd, 0xa2, 0xaa, - 0xd4, 0xcb, 0xd6, 0x1f, 0x79, 0xb8, 0xb3, 0xf3, 0x1f, 0xa6, 0x1e, 0x0d, 0xe3, 0x08, 0x7b, 0xf1, - 0xba, 0x78, 0x6f, 0x40, 0x09, 0xfb, 0x93, 0x20, 0x14, 0x74, 0x57, 0x5c, 0x69, 0x68, 0x77, 0xa1, - 0x2c, 0xd0, 0x06, 0xbe, 0x5e, 0x6a, 0xa2, 0x56, 0xd1, 0x81, 0x59, 0x6a, 0x2a, 0xbc, 0xf4, 0x9d, - 0xcf, 0x5d, 0x85, 0xbb, 0x76, 0x7c, 0xbe, 0x75, 0x8c, 0x07, 0x64, 0xac, 0x2b, 0x72, 0xab, 0x30, - 0xb4, 0x16, 0x14, 0x26, 0x6c, 0x28, 0xd8, 0xaf, 0x39, 0x9b, 0xff, 0xa4, 0xa6, 0xe6, 0xe2, 0xe3, - 0x79, 0x15, 0xbb, 0x84, 0x31, 0x3c, 0x24, 0x2e, 0x0f, 0xd1, 0x30, 0x94, 0x0e, 0x93, 0xd0, 0x67, - 0xba, 0xda, 0x2c, 0xb4, 0xaa, 0xdb, 0xef, 0xd8, 0xb2, 0x4b, 0x6d, 0xde, 0xa5, 0x76, 0xd6, 0xa5, - 0x76, 0x8f, 0x06, 0xa1, 0xf3, 0xe1, 0x69, 0x6a, 0xe6, 0x1e, 0xfd, 0x69, 0xb6, 0x86, 0x41, 0x3c, - 0x4a, 0x06, 0xb6, 0x47, 0x27, 0xed, 0xac, 0xa5, 0xe5, 0xcf, 0x07, 0xcc, 0xff, 0x2e, 0xeb, 0x59, - 0xbe, 0x81, 0xb9, 0xf2, 0x64, 0xeb, 0x77, 0x04, 0xb7, 0x77, 0x83, 0x61, 0x74, 0x9d, 0x44, 0x6e, - 0x81, 0xea, 0x65, 0x67, 0x65, 0xa4, 0x2d, 0xec, 0x97, 0xe3, 0x2d, 0x63, 0x48, 0x79, 0x21, 0x43, - 0xd6, 0x8f, 0x08, 0x1a, 0xfb, 0x89, 0x4f, 0xd7, 0x82, 0xbd, 0x70, 0x09, 0x7b, 0x06, 0xab, 0xf8, - 0x62, 0x58, 0x3f, 0xe4, 0xe1, 0xf6, 0x17, 0x0f, 0x89, 0x97, 0xac, 0xbf, 0x3d, 0x57, 0x91, 0x9d, - 0x01, 0x2e, 0xbd, 0x42, 0xa7, 0x29, 0x6b, 0xeb, 0xb4, 0x9f, 0x11, 0xdc, 0x3a, 0x98, 0xfa, 0x38, - 0x26, 0x5d, 0x7e, 0x83, 0xfe, 0x37, 0x1f, 0x1d, 0xa8, 0x84, 0xe4, 0xb8, 0x2f, 0xef, 0xa6, 0xa0, - 0xc4, 0x69, 0x9c, 0xa7, 0x66, 0xfd, 0x04, 0x4f, 0xc6, 0x9f, 0x59, 0x0b, 0x97, 0xe5, 0xaa, 0x21, - 0x39, 0x16, 0x29, 0x57, 0x71, 0x65, 0x8d, 0x40, 0xeb, 0x8d, 0x09, 0x8e, 0xae, 0x07, 0xdc, 0x8a, - 0x36, 0xb2, 0x7e, 0x45, 0x50, 0xdf, 0x93, 0xcf, 0x24, 0x5b, 0x24, 0xba, 0x77, 0x21, 0x91, 0x53, - 0x3f, 0x4f, 0xcd, 0x9a, 0xac, 0x44, 0x2c, 0x5b, 0xf3, 0xd4, 0x9f, 0x3c, 0x27, 0xb5, 0xb3, 0x79, - 0x9e, 0x9a, 0x9a, 0x8c, 0x5e, 0x72, 0x5a, 0x17, 0x21, 0x7d, 0x0a, 0x6a, 0x76, 0xf3, 0x78, 0x07, - 0x15, 0x5a, 0x45, 0xc7, 0x98, 0xa5, 0x66, 0x59, 0x5e, 0x3d, 0x76, 0x9e, 0x9a, 0x6f, 0xc9, 0x13, - 0xe6, 0x41, 0x96, 0x5b, 0x96, 0xd7, 0x91, 0x59, 0xbf, 0x21, 0xd0, 0x0e, 0xe6, 0x4f, 0xfb, 0x6b, - 0x82, 0xf9, 0x27, 0x04, 0xda, 0xf2, 0x1c, 0x93, 0xad, 0xb7, 0xfc, 0xfe, 0xa0, 0x2b, 0xdf, 0x9f, - 0x6f, 0xae, 0x1c, 0x99, 0xf9, 0x97, 0x19, 0x99, 0x4e, 0x91, 0xdf, 0x91, 0x2b, 0x06, 0xa7, 0x75, - 0x86, 0xc0, 0x94, 0x60, 0x2e, 0x0e, 0xb1, 0xc3, 0x60, 0x78, 0x83, 0xcc, 0x7e, 0x0b, 0x1b, 0x58, - 0x40, 0xee, 0x7b, 0x22, 0x75, 0x3f, 0x11, 0x90, 0x24, 0xcd, 0xd5, 0xed, 0xf7, 0x57, 0x57, 0x28, - 0xf1, 0x67, 0x75, 0xde, 0xc2, 0xcf, 0x78, 0x98, 0xf5, 0xa8, 0x08, 0x77, 0x85, 0x24, 0xea, 0x86, - 0xfe, 0x0d, 0x0e, 0xeb, 0xeb, 0x17, 0x49, 0xa5, 0xeb, 0x13, 0x49, 0xca, 0x65, 0x91, 0xb4, 0x90, - 0x16, 0xe5, 0x65, 0x69, 0xb1, 0x50, 0x0d, 0xea, 0x73, 0x54, 0x43, 0xe5, 0x15, 0xde, 0x72, 0x58, - 0xd7, 0x5b, 0xbe, 0xa4, 0xee, 0xaa, 0x57, 0xa9, 0xbb, 0xda, 0x0a, 0x75, 0xf7, 0xc6, 0x45, 0x75, - 0xe7, 0x7c, 0x75, 0xfa, 0xd4, 0xc8, 0x3d, 0x79, 0x6a, 0xe4, 0x7e, 0x99, 0x19, 0xe8, 0x74, 0x66, - 0xa0, 0xc7, 0x33, 0x03, 0xfd, 0x35, 0x33, 0xd0, 0xf7, 0x67, 0x46, 0xee, 0xf1, 0x99, 0x91, 0x7b, - 0x72, 0x66, 0xe4, 0xbe, 0xbe, 0xb7, 0x84, 0xb2, 0x47, 0xd9, 0xe4, 0xc1, 0x5c, 0x8e, 0xfb, 0xed, - 0x87, 0x52, 0x96, 0x0b, 0xa4, 0x03, 0x45, 0x88, 0xf2, 0x8f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, - 0x13, 0x9e, 0x35, 0x27, 0x1d, 0x0c, 0x00, 0x00, + 0x6e, 0x3d, 0x21, 0x4e, 0x68, 0x66, 0x9c, 0x6c, 0xda, 0x6d, 0xb3, 0xbb, 0xd0, 0xac, 0x84, 0xc4, + 0x25, 0xf1, 0x9b, 0xf7, 0x66, 0xde, 0xef, 0xfd, 0xf4, 0xde, 0xf8, 0x67, 0x30, 0x5d, 0xca, 0xc6, + 0x47, 0x98, 0x8d, 0x9b, 0xe2, 0xe7, 0xb0, 0xd5, 0x9c, 0x84, 0x74, 0x42, 0x19, 0x1e, 0x35, 0x26, + 0x21, 0x8d, 0x28, 0xaa, 0xcc, 0x02, 0x1a, 0xe2, 0xe7, 0xb0, 0xb5, 0x55, 0x1d, 0xd0, 0x01, 0x15, + 0xce, 0x26, 0x7f, 0x92, 0x71, 0x5b, 0x06, 0x8f, 0xa3, 0xac, 0xd9, 0xc3, 0x8c, 0x34, 0x0f, 0x5b, + 0x3d, 0x12, 0xe1, 0x56, 0xd3, 0xa5, 0x7e, 0x90, 0xfa, 0xef, 0x3c, 0x93, 0x28, 0x3a, 0x99, 0x10, + 0x26, 0xbd, 0xd6, 0x1f, 0x59, 0x78, 0x73, 0x3f, 0xa2, 0x21, 0xe9, 0x50, 0x8f, 0xec, 0xa5, 0x08, + 0x50, 0x15, 0xf2, 0x91, 0x1f, 0x8d, 0x88, 0xae, 0xd4, 0x94, 0x7a, 0xd1, 0x91, 0x06, 0xaa, 0x41, + 0xc9, 0x23, 0xcc, 0x0d, 0xfd, 0x49, 0xe4, 0xd3, 0x40, 0xcf, 0x0a, 0xdf, 0xe2, 0x12, 0x5a, 0x07, + 0x35, 0x8c, 0x83, 0x2e, 0x66, 0xfa, 0x9a, 0xdc, 0x18, 0xc6, 0x41, 0x9b, 0xa1, 0x0f, 0xe0, 0x75, + 0x9e, 0xbb, 0xdb, 0x3b, 0x89, 0x48, 0xd7, 0xa5, 0x1e, 0xd1, 0x73, 0x35, 0xa5, 0x5e, 0xb6, 0x2b, + 0xd3, 0xc4, 0x2c, 0x3f, 0x68, 0xef, 0xef, 0xda, 0x27, 0x91, 0x00, 0xe0, 0x94, 0x79, 0xdc, 0xcc, + 0x42, 0x07, 0xb0, 0xe1, 0x07, 0x2c, 0xc2, 0x41, 0xe4, 0xe3, 0x88, 0x74, 0x27, 0x24, 0x1c, 0xfb, + 0x8c, 0xf1, 0xdc, 0x85, 0x9a, 0x52, 0x2f, 0x6d, 0x1b, 0x8d, 0xcb, 0x1c, 0x35, 0xda, 0xae, 0x4b, + 0x18, 0xeb, 0xd0, 0xa0, 0xef, 0x0f, 0x9c, 0xf5, 0x85, 0xdd, 0x7b, 0xf3, 0xcd, 0xe8, 0x6d, 0x80, + 0x38, 0x98, 0xf8, 0x81, 0x84, 0xa2, 0xd5, 0x94, 0xba, 0xe6, 0x14, 0xc5, 0x8a, 0xc8, 0xba, 0x01, + 0x2a, 0xa3, 0x71, 0xe8, 0x12, 0xbd, 0x28, 0x8a, 0x48, 0x2d, 0xa4, 0x43, 0xa1, 0x17, 0xfb, 0x23, + 0x8f, 0x84, 0x3a, 0x08, 0xc7, 0xcc, 0x44, 0xb7, 0xa1, 0xc8, 0x8f, 0xea, 0x0e, 0x31, 0x1b, 0xea, + 0x25, 0x5e, 0x9a, 0xa3, 0xf1, 0x85, 0xcf, 0x30, 0x1b, 0xde, 0xcf, 0x69, 0xf9, 0x8a, 0x7a, 0x3f, + 0xa7, 0xa9, 0x95, 0x82, 0xf5, 0x6b, 0x16, 0x6e, 0xef, 0x3c, 0xc5, 0xd4, 0xa1, 0x41, 0x14, 0x62, + 0x37, 0x5a, 0x15, 0xef, 0x55, 0xc8, 0x63, 0x6f, 0xec, 0x07, 0x82, 0xee, 0xa2, 0x23, 0x0d, 0x74, + 0x17, 0x0a, 0x02, 0xad, 0xef, 0xe9, 0xf9, 0x9a, 0x52, 0xcf, 0xd9, 0x30, 0x4d, 0x4c, 0x95, 0x97, + 0xbe, 0xf3, 0x89, 0xa3, 0x72, 0xd7, 0x8e, 0xc7, 0xb7, 0x8e, 0x70, 0x8f, 0x8c, 0x74, 0x55, 0x6e, + 0x15, 0x06, 0xaa, 0xc3, 0xda, 0x98, 0x0d, 0x04, 0xfb, 0x65, 0x7b, 0xe3, 0xaf, 0xc4, 0x44, 0x0e, + 0x3e, 0x9a, 0x55, 0xb1, 0x4b, 0x18, 0xc3, 0x03, 0xe2, 0xf0, 0x10, 0x84, 0x21, 0xdf, 0x8f, 0x03, + 0x8f, 0xe9, 0x5a, 0x6d, 0xad, 0x5e, 0xda, 0x7e, 0xab, 0x21, 0xbb, 0xb4, 0xc1, 0xbb, 0xb4, 0x91, + 0x76, 0x69, 0xa3, 0x43, 0xfd, 0xc0, 0x7e, 0xef, 0x34, 0x31, 0x33, 0x0f, 0x7f, 0x33, 0xeb, 0x03, + 0x3f, 0x1a, 0xc6, 0xbd, 0x86, 0x4b, 0xc7, 0xcd, 0xb4, 0xa5, 0xe5, 0xdf, 0xbb, 0xcc, 0xfb, 0x3a, + 0xed, 0x59, 0xbe, 0x81, 0x39, 0xf2, 0x64, 0xeb, 0xcf, 0x2c, 0xdc, 0xb9, 0x82, 0xcc, 0xed, 0xff, + 0xd9, 0xfc, 0x07, 0x6c, 0x22, 0x04, 0x39, 0x86, 0x47, 0x91, 0xe8, 0xf9, 0xb2, 0x23, 0x9e, 0xd1, + 0x26, 0x14, 0xfa, 0xfe, 0x71, 0x97, 0x83, 0x04, 0x31, 0x25, 0x6a, 0xdf, 0x3f, 0xde, 0x65, 0x03, + 0xeb, 0x17, 0x05, 0x36, 0x77, 0xfd, 0x41, 0x78, 0x93, 0x3d, 0xbc, 0x05, 0x9a, 0x9b, 0x9e, 0x95, + 0x32, 0x3c, 0xb7, 0x5f, 0x8c, 0xe4, 0x94, 0x4e, 0xf5, 0xb9, 0x74, 0x5a, 0xdf, 0x29, 0x50, 0xdd, + 0x8f, 0x3d, 0xba, 0x12, 0xec, 0x6b, 0x97, 0xb0, 0xa7, 0xb0, 0x72, 0xcf, 0x87, 0xf5, 0x6d, 0x16, + 0x36, 0x3f, 0x3d, 0x26, 0x6e, 0xbc, 0xfa, 0x9b, 0x61, 0x19, 0xd9, 0x29, 0xe0, 0xfc, 0x4b, 0xb4, + 0xa5, 0xba, 0xb2, 0x21, 0xff, 0x41, 0x81, 0x5b, 0x07, 0x13, 0x0f, 0x47, 0xa4, 0xcd, 0xc7, 0xed, + 0x5f, 0xf3, 0xd1, 0x82, 0x62, 0x40, 0x8e, 0xba, 0x72, 0x90, 0x05, 0x25, 0x76, 0xf5, 0x3c, 0x31, + 0x2b, 0x27, 0x78, 0x3c, 0xfa, 0xd8, 0x9a, 0xbb, 0x2c, 0x47, 0x0b, 0xc8, 0x91, 0x48, 0xb9, 0x8c, + 0x2b, 0x6b, 0x08, 0xa8, 0x33, 0x22, 0x38, 0xbc, 0x19, 0x70, 0x4b, 0xda, 0xc8, 0xfa, 0x49, 0x81, + 0xca, 0x9e, 0x7c, 0x43, 0xb1, 0x79, 0xa2, 0x7b, 0x17, 0x12, 0xd9, 0x95, 0xf3, 0xc4, 0x2c, 0xcb, + 0x4a, 0xc4, 0xb2, 0x35, 0x4b, 0xfd, 0xe1, 0x15, 0xa9, 0xed, 0x8d, 0xf3, 0xc4, 0x44, 0x32, 0x7a, + 0xc1, 0x69, 0x5d, 0x84, 0xf4, 0x11, 0x68, 0xe9, 0xe4, 0xf1, 0x0e, 0x5a, 0xab, 0xe7, 0x6c, 0x63, + 0x9a, 0x98, 0x05, 0x39, 0x7a, 0xec, 0x3c, 0x31, 0xdf, 0x90, 0x27, 0xcc, 0x82, 0x2c, 0xa7, 0x20, + 0xc7, 0x91, 0x59, 0x3f, 0x2b, 0x80, 0x0e, 0x66, 0x6f, 0xd5, 0xff, 0x08, 0xe6, 0xef, 0x15, 0x40, + 0x8b, 0x12, 0x42, 0xb6, 0xde, 0xe2, 0xfd, 0xa3, 0x5c, 0x7b, 0xff, 0x7c, 0x79, 0xad, 0x5a, 0xc9, + 0xbe, 0x88, 0x5a, 0xb1, 0x73, 0x7c, 0x46, 0xae, 0xd1, 0x2c, 0xd6, 0x99, 0x02, 0xa6, 0x04, 0x73, + 0xf1, 0x95, 0xd7, 0xf7, 0x07, 0xaf, 0x90, 0xd9, 0xaf, 0x60, 0x1d, 0x0b, 0xc8, 0x5d, 0x57, 0xa4, + 0xee, 0xc6, 0x02, 0x92, 0xa4, 0xb9, 0xb4, 0xfd, 0xce, 0xf2, 0x0a, 0x25, 0xfe, 0xb4, 0xce, 0x5b, + 0xf8, 0x19, 0x0f, 0xb3, 0x1e, 0xe6, 0xe0, 0xae, 0x50, 0xa3, 0xed, 0xc0, 0x7b, 0x85, 0x3a, 0xe9, + 0xe6, 0xf5, 0x69, 0xfe, 0xe6, 0xf4, 0xa9, 0x7a, 0x59, 0x9f, 0xce, 0x75, 0x48, 0x61, 0x51, 0x87, + 0xcc, 0x25, 0x86, 0x76, 0x85, 0xc4, 0x28, 0xbe, 0xc4, 0x5d, 0x0e, 0x2b, 0x93, 0x18, 0x4f, 0x85, + 0x75, 0xe9, 0x3a, 0x61, 0x5d, 0x5e, 0x22, 0xac, 0x5f, 0xbb, 0x28, 0xac, 0xed, 0xcf, 0x4f, 0x9f, + 0x18, 0x99, 0xc7, 0x4f, 0x8c, 0xcc, 0x8f, 0x53, 0x43, 0x39, 0x9d, 0x1a, 0xca, 0xa3, 0xa9, 0xa1, + 0xfc, 0x3e, 0x35, 0x94, 0x6f, 0xce, 0x8c, 0xcc, 0xa3, 0x33, 0x23, 0xf3, 0xf8, 0xcc, 0xc8, 0x7c, + 0x71, 0x6f, 0x01, 0x65, 0x87, 0xb2, 0xf1, 0x83, 0xd9, 0x97, 0x90, 0xd7, 0x3c, 0x96, 0x5f, 0x44, + 0x02, 0x69, 0x4f, 0x15, 0xdf, 0x43, 0xef, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x34, 0xb6, 0x6c, + 0x40, 0x98, 0x0d, 0x00, 0x00, } func (this *StoreCodeProposal) Equal(that interface{}) bool { @@ -840,6 +906,63 @@ func (this *InstantiateContractProposal) Equal(that interface{}) bool { return true } +func (this *InstantiateContract2Proposal) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*InstantiateContract2Proposal) + if !ok { + that2, ok := that.(InstantiateContract2Proposal) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Title != that1.Title { + return false + } + if this.Description != that1.Description { + return false + } + if this.RunAs != that1.RunAs { + return false + } + if this.Admin != that1.Admin { + return false + } + if this.CodeID != that1.CodeID { + return false + } + if this.Label != that1.Label { + return false + } + if !bytes.Equal(this.Msg, that1.Msg) { + return false + } + if len(this.Funds) != len(that1.Funds) { + return false + } + for i := range this.Funds { + if !this.Funds[i].Equal(&that1.Funds[i]) { + return false + } + } + if !bytes.Equal(this.Salt, that1.Salt) { + return false + } + if this.FixMsg != that1.FixMsg { + return false + } + return true +} + func (this *MigrateContractProposal) Equal(that interface{}) bool { if that == nil { return this == nil @@ -1401,6 +1524,107 @@ func (m *InstantiateContractProposal) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *InstantiateContract2Proposal) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InstantiateContract2Proposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InstantiateContract2Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.FixMsg { + i-- + if m.FixMsg { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x4a + } + if len(m.Funds) > 0 { + for iNdEx := len(m.Funds) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Funds[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProposal(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x3a + } + if len(m.Label) > 0 { + i -= len(m.Label) + copy(dAtA[i:], m.Label) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Label))) + i-- + dAtA[i] = 0x32 + } + if m.CodeID != 0 { + i = encodeVarintProposal(dAtA, i, uint64(m.CodeID)) + i-- + dAtA[i] = 0x28 + } + if len(m.Admin) > 0 { + i -= len(m.Admin) + copy(dAtA[i:], m.Admin) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Admin))) + i-- + dAtA[i] = 0x22 + } + if len(m.RunAs) > 0 { + i -= len(m.RunAs) + copy(dAtA[i:], m.RunAs) + i = encodeVarintProposal(dAtA, i, uint64(len(m.RunAs))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintProposal(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *MigrateContractProposal) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2101,6 +2325,55 @@ func (m *InstantiateContractProposal) Size() (n int) { return n } +func (m *InstantiateContract2Proposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.RunAs) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Admin) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if m.CodeID != 0 { + n += 1 + sovProposal(uint64(m.CodeID)) + } + l = len(m.Label) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if len(m.Funds) > 0 { + for _, e := range m.Funds { + l = e.Size() + n += 1 + l + sovProposal(uint64(l)) + } + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovProposal(uint64(l)) + } + if m.FixMsg { + n += 2 + } + return n +} + func (m *MigrateContractProposal) Size() (n int) { if m == nil { return 0 @@ -3023,6 +3296,358 @@ func (m *InstantiateContractProposal) Unmarshal(dAtA []byte) error { return nil } +func (m *InstantiateContract2Proposal) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InstantiateContract2Proposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InstantiateContract2Proposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunAs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RunAs = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Admin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeID", wireType) + } + m.CodeID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Label", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Label = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Funds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Funds = append(m.Funds, types.Coin{}) + if err := m.Funds[len(m.Funds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProposal + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProposal + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FixMsg", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProposal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.FixMsg = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipProposal(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProposal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + func (m *MigrateContractProposal) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/wasm/types/proposal_test.go b/x/wasm/types/proposal_test.go index 581ed85d80..a558744f8b 100644 --- a/x/wasm/types/proposal_test.go +++ b/x/wasm/types/proposal_test.go @@ -279,6 +279,105 @@ func TestValidateInstantiateContractProposal(t *testing.T) { } } +func TestValidateInstantiateContract2Proposal(t *testing.T) { + invalidAddress := "invalid address" + + specs := map[string]struct { + src *InstantiateContract2Proposal + expErr bool + }{ + "all good": { + src: InstantiateContract2ProposalFixture(), + }, + "without admin": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Admin = "" + }), + }, + "without init msg": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Msg = nil + }), + expErr: true, + }, + "with invalid init msg": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Msg = []byte("not a json string") + }), + expErr: true, + }, + "without init funds": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Funds = nil + }), + }, + "base data missing": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Title = "" + }), + expErr: true, + }, + "run_as missing": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.RunAs = "" + }), + expErr: true, + }, + "run_as invalid": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.RunAs = invalidAddress + }), + expErr: true, + }, + "admin invalid": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Admin = invalidAddress + }), + expErr: true, + }, + "code id empty": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.CodeID = 0 + }), + expErr: true, + }, + "label empty": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Label = "" + }), + expErr: true, + }, + "init funds negative": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Funds = sdk.Coins{{Denom: "foo", Amount: sdk.NewInt(-1)}} + }), + expErr: true, + }, + "init funds with duplicates": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Funds = sdk.Coins{{Denom: "foo", Amount: sdk.NewInt(1)}, {Denom: "foo", Amount: sdk.NewInt(2)}} + }), + expErr: true, + }, + "init with empty salt": { + src: InstantiateContract2ProposalFixture(func(p *InstantiateContract2Proposal) { + p.Salt = nil + }), + expErr: true, + }, + } + for msg, spec := range specs { + t.Run(msg, func(t *testing.T) { + err := spec.src.ValidateBasic() + if spec.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + func TestValidateStoreAndInstantiateContractProposal(t *testing.T) { var ( anyAddress sdk.AccAddress = bytes.Repeat([]byte{0x0}, ContractAddrLen) diff --git a/x/wasm/types/query.pb.go b/x/wasm/types/query.pb.go index 68b15e39fa..95175f2ae6 100644 --- a/x/wasm/types/query.pb.go +++ b/x/wasm/types/query.pb.go @@ -23,9 +23,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) diff --git a/x/wasm/types/query.pb.gw.go b/x/wasm/types/query.pb.gw.go index 4bffee3d7c..32f3fd25cd 100644 --- a/x/wasm/types/query.pb.gw.go +++ b/x/wasm/types/query.pb.gw.go @@ -25,9 +25,8 @@ import ( ) // Suppress "imported and not used" errors -var _ codes.Code - var ( + _ codes.Code _ io.Reader _ status.Status _ = runtime.String diff --git a/x/wasm/types/test_fixtures.go b/x/wasm/types/test_fixtures.go index e62399972f..1f68e4bb56 100644 --- a/x/wasm/types/test_fixtures.go +++ b/x/wasm/types/test_fixtures.go @@ -258,6 +258,46 @@ func InstantiateContractProposalFixture(mutators ...func(p *InstantiateContractP return p } +func InstantiateContract2ProposalFixture(mutators ...func(p *InstantiateContract2Proposal)) *InstantiateContract2Proposal { + var ( + anyValidAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, ContractAddrLen) + + initMsg = struct { + Verifier sdk.AccAddress `json:"verifier"` + Beneficiary sdk.AccAddress `json:"beneficiary"` + }{ + Verifier: anyValidAddress, + Beneficiary: anyValidAddress, + } + ) + const ( + anyAddress = "cosmos1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs2m6sx4" + mySalt = "myDefaultSalt" + ) + + initMsgBz, err := json.Marshal(initMsg) + if err != nil { + panic(err) + } + p := &InstantiateContract2Proposal{ + Title: "Foo", + Description: "Bar", + RunAs: anyAddress, + Admin: anyAddress, + CodeID: 1, + Label: "testing", + Msg: initMsgBz, + Funds: nil, + Salt: []byte(mySalt), + FixMsg: false, + } + + for _, m := range mutators { + m(p) + } + return p +} + func StoreAndInstantiateContractProposalFixture(mutators ...func(p *StoreAndInstantiateContractProposal)) *StoreAndInstantiateContractProposal { var ( anyValidAddress sdk.AccAddress = bytes.Repeat([]byte{0x1}, ContractAddrLen) diff --git a/x/wasm/types/tx.pb.go b/x/wasm/types/tx.pb.go index 4670ba2b0b..4aa9676b37 100644 --- a/x/wasm/types/tx.pb.go +++ b/x/wasm/types/tx.pb.go @@ -21,9 +21,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) diff --git a/x/wasm/types/types.pb.go b/x/wasm/types/types.pb.go index d53952253e..8914b69485 100644 --- a/x/wasm/types/types.pb.go +++ b/x/wasm/types/types.pb.go @@ -18,9 +18,8 @@ import ( ) // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal - var ( + _ = proto.Marshal _ = fmt.Errorf _ = math.Inf ) From 299d4223af90c495c982563b5395b000c7402a07 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Tue, 6 Dec 2022 11:51:38 +0200 Subject: [PATCH 037/294] Enable key name usage for admin (#1103) --- x/wasm/client/cli/genesis_msg.go | 9 +++++++-- x/wasm/client/cli/genesis_msg_test.go | 16 ++++++++++++++++ x/wasm/client/cli/gov_tx.go | 19 ++++++++++++++++--- x/wasm/client/cli/tx.go | 25 ++++++++++++++++++++----- 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/x/wasm/client/cli/genesis_msg.go b/x/wasm/client/cli/genesis_msg.go index b6b1321aee..674a54d1c6 100644 --- a/x/wasm/client/cli/genesis_msg.go +++ b/x/wasm/client/cli/genesis_msg.go @@ -90,12 +90,17 @@ func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator Genesi Short: "Instantiate a wasm contract", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + senderAddr, err := getActorAddress(cmd) if err != nil { return err } - msg, err := parseInstantiateArgs(args[0], args[1], senderAddr, cmd.Flags()) + msg, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, senderAddr, cmd.Flags()) if err != nil { return err } @@ -141,7 +146,7 @@ func GenesisInstantiateContractCmd(defaultNodeHome string, genesisMutator Genesi } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract.") diff --git a/x/wasm/client/cli/genesis_msg_test.go b/x/wasm/client/cli/genesis_msg_test.go index cd8a5f3b7b..335c30a246 100644 --- a/x/wasm/client/cli/genesis_msg_test.go +++ b/x/wasm/client/cli/genesis_msg_test.go @@ -161,6 +161,22 @@ func TestInstantiateContractCmd(t *testing.T) { }, expMsgCount: 2, }, + "all good with code id from genesis store messages without initial sequence and key name admin": { + srcGenesis: types.GenesisState{ + Params: types.DefaultParams(), + GenMsgs: []types.GenesisState_GenMsgs{ + {Sum: &types.GenesisState_GenMsgs_StoreCode{StoreCode: types.MsgStoreCodeFixture()}}, + }, + }, + mutator: func(cmd *cobra.Command) { + cmd.SetArgs([]string{"1", `{}`}) + flagSet := cmd.Flags() + flagSet.Set("label", "testing") + flagSet.Set("run-as", defaultTestKeyName) + flagSet.Set("admin", defaultTestKeyName) + }, + expMsgCount: 2, + }, "all good with code id from genesis store messages and sequence set": { srcGenesis: types.GenesisState{ Params: types.DefaultParams(), diff --git a/x/wasm/client/cli/gov_tx.go b/x/wasm/client/cli/gov_tx.go index 3f5ecd033f..c17f0f4086 100644 --- a/x/wasm/client/cli/gov_tx.go +++ b/x/wasm/client/cli/gov_tx.go @@ -151,7 +151,7 @@ func ProposalInstantiateContractCmd() *cobra.Command { return err } - src, err := parseInstantiateArgs(args[0], args[1], clientCtx.FromAddress, cmd.Flags()) + src, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, clientCtx.FromAddress, cmd.Flags()) if err != nil { return err } @@ -189,7 +189,7 @@ func ProposalInstantiateContractCmd() *cobra.Command { } cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract and passed to the contract as sender on proposal execution") cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") @@ -331,6 +331,19 @@ func ProposalStoreAndInstantiateContractCmd() *cobra.Command { return fmt.Errorf("you set an admin and passed --no-admin, those cannot both be true") } + if adminStr != "" { + addr, err := sdk.AccAddressFromBech32(adminStr) + if err != nil { + info, err := clientCtx.Keyring.Key(adminStr) + if err != nil { + return fmt.Errorf("admin %s", err) + } + adminStr = info.GetAddress().String() + } else { + adminStr = addr.String() + } + } + content := types.StoreAndInstantiateContractProposal{ Title: proposalTitle, Description: proposalDescr, @@ -371,7 +384,7 @@ func ProposalStoreAndInstantiateContractCmd() *cobra.Command { cmd.Flags().StringSlice(flagInstantiateByAnyOfAddress, []string{}, "Any of the addresses can instantiate a contract from the code, optional") cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") // proposal flags diff --git a/x/wasm/client/cli/tx.go b/x/wasm/client/cli/tx.go index 7d7770d086..b71b82519c 100644 --- a/x/wasm/client/cli/tx.go +++ b/x/wasm/client/cli/tx.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/version" @@ -208,7 +209,7 @@ $ %s tx wasm instantiate 1 '{"foo":"bar"}' --admin="$(%s keys show mykey -a)" \ if err != nil { return err } - msg, err := parseInstantiateArgs(args[0], args[1], clientCtx.GetFromAddress(), cmd.Flags()) + msg, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, clientCtx.GetFromAddress(), cmd.Flags()) if err != nil { return err } @@ -222,7 +223,7 @@ $ %s tx wasm instantiate 1 '{"foo":"bar"}' --admin="$(%s keys show mykey -a)" \ cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") flags.AddTxFlagsToCmd(cmd) return cmd @@ -259,7 +260,7 @@ $ %s tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --adm if err != nil { return fmt.Errorf("fix msg: %w", err) } - data, err := parseInstantiateArgs(args[0], args[1], clientCtx.GetFromAddress(), cmd.Flags()) + data, err := parseInstantiateArgs(args[0], args[1], clientCtx.Keyring, clientCtx.GetFromAddress(), cmd.Flags()) if err != nil { return err } @@ -283,7 +284,7 @@ $ %s tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --adm cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation") cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists") - cmd.Flags().String(flagAdmin, "", "Address of an admin") + cmd.Flags().String(flagAdmin, "", "Address or key name of an admin") cmd.Flags().Bool(flagNoAdmin, false, "You must set this explicitly if you don't want an admin") cmd.Flags().Bool(flagFixMsg, false, "An optional flag to include the json_encoded_init_args for the predictable address generation mode") decoder.RegisterFlags(cmd.PersistentFlags(), "salt") @@ -291,7 +292,7 @@ $ %s tx wasm instantiate2 1 '{"foo":"bar"}' $(echo -n "testing" | xxd -ps) --adm return cmd } -func parseInstantiateArgs(rawCodeID, initMsg string, sender sdk.AccAddress, flags *flag.FlagSet) (*types.MsgInstantiateContract, error) { +func parseInstantiateArgs(rawCodeID, initMsg string, kr keyring.Keyring, sender sdk.AccAddress, flags *flag.FlagSet) (*types.MsgInstantiateContract, error) { // get the id of the code to instantiate codeID, err := strconv.ParseUint(rawCodeID, 10, 64) if err != nil { @@ -317,6 +318,7 @@ func parseInstantiateArgs(rawCodeID, initMsg string, sender sdk.AccAddress, flag if err != nil { return nil, fmt.Errorf("admin: %s", err) } + noAdmin, err := flags.GetBool(flagNoAdmin) if err != nil { return nil, fmt.Errorf("no-admin: %s", err) @@ -330,6 +332,19 @@ func parseInstantiateArgs(rawCodeID, initMsg string, sender sdk.AccAddress, flag return nil, fmt.Errorf("you set an admin and passed --no-admin, those cannot both be true") } + if adminStr != "" { + addr, err := sdk.AccAddressFromBech32(adminStr) + if err != nil { + info, err := kr.Key(adminStr) + if err != nil { + return nil, fmt.Errorf("admin %s", err) + } + adminStr = info.GetAddress().String() + } else { + adminStr = addr.String() + } + } + // build and sign the transaction, then broadcast to Tendermint msg := types.MsgInstantiateContract{ Sender: sender.String(), From c5abd338e3d178fa26fac1f58642de21e6bffe34 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Fri, 9 Dec 2022 12:40:34 +0100 Subject: [PATCH 038/294] Add gov proposal simulations (#1107) * Add weights * Add helper functions to create new proposals * Add MigrateContractProposal simulation * Add SudoContractProposal simulation * Add PinContractProposal simulation * Add UnpinContractProposal simulation * Add UpdateInstantiateConfigProposal simulation * Add StoreAndInstantiateContractProposal simulation * Comment out failing simulations * Fix comments --- app/params/weights.go | 16 ++- x/wasm/simulation/proposals.go | 195 +++++++++++++++++++++++++++++++-- x/wasm/types/proposal.go | 66 +++++++++++ 3 files changed, 265 insertions(+), 12 deletions(-) diff --git a/app/params/weights.go b/app/params/weights.go index d8eed7679f..4e5452c9b2 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -28,9 +28,15 @@ const ( DefaultWeightMsgClearAdmin int = 10 DefaultWeightMsgMigrateContract int = 50 - DefaultWeightStoreCodeProposal int = 5 - DefaultWeightInstantiateContractProposal int = 5 - DefaultWeightUpdateAdminProposal int = 5 - DefaultWeightExecuteContractProposal int = 5 - DefaultWeightClearAdminProposal int = 5 + DefaultWeightStoreCodeProposal int = 5 + DefaultWeightInstantiateContractProposal int = 5 + DefaultWeightUpdateAdminProposal int = 5 + DefaultWeightExecuteContractProposal int = 5 + DefaultWeightClearAdminProposal int = 5 + DefaultWeightMigrateContractProposal int = 5 + DefaultWeightSudoContractProposal int = 5 + DefaultWeightPinCodesProposal int = 5 + DefaultWeightUnpinCodesProposal int = 5 + DefaultWeightUpdateInstantiateConfigProposal int = 5 + DefaultWeightStoreAndInstantiateContractProposal int = 5 ) diff --git a/x/wasm/simulation/proposals.go b/x/wasm/simulation/proposals.go index 585827c041..7c1582b467 100644 --- a/x/wasm/simulation/proposals.go +++ b/x/wasm/simulation/proposals.go @@ -13,11 +13,17 @@ import ( ) const ( - WeightStoreCodeProposal = "weight_store_code_proposal" - WeightInstantiateContractProposal = "weight_instantiate_contract_proposal" - WeightUpdateAdminProposal = "weight_update_admin_proposal" - WeightExeContractProposal = "weight_execute_contract_proposal" - WeightClearAdminProposal = "weight_clear_admin_proposal" + WeightStoreCodeProposal = "weight_store_code_proposal" + WeightInstantiateContractProposal = "weight_instantiate_contract_proposal" + WeightUpdateAdminProposal = "weight_update_admin_proposal" + WeightExeContractProposal = "weight_execute_contract_proposal" + WeightClearAdminProposal = "weight_clear_admin_proposal" + WeightMigrateContractProposal = "weight_migrate_contract_proposal" + WeightSudoContractProposal = "weight_sudo_contract_proposal" + WeightPinCodesProposal = "weight_pin_codes_proposal" + WeightUnpinCodesProposal = "weight_unpin_codes_proposal" + WeightUpdateInstantiateConfigProposal = "weight_update_instantiate_config_proposal" + WeightStoreAndInstantiateContractProposal = "weight_store_and_instantiate_contract_proposal" ) func ProposalContents(bk BankKeeper, wasmKeeper WasmKeeper) []simtypes.WeightedProposalContent { @@ -60,9 +66,57 @@ func ProposalContents(bk BankKeeper, wasmKeeper WasmKeeper) []simtypes.WeightedP params.DefaultWeightClearAdminProposal, SimulateClearAdminProposal( wasmKeeper, - DefaultSimulateClearAdminProposalContractSelector, + DefaultSimulateContractSelector, ), ), + simulation.NewWeightedProposalContent( + WeightMigrateContractProposal, + params.DefaultWeightMigrateContractProposal, + SimulateMigrateContractProposal( + wasmKeeper, + DefaultSimulateContractSelector, + DefaultSimulationCodeIDSelector, + ), + ), + // simulation.NewWeightedProposalContent( + // WeightSudoContractProposal, + // params.DefaultWeightSudoContractProposal, + // SimulateSudoContractProposal( + // wasmKeeper, + // DefaultSimulateContractSelector, + // ), + // ), + simulation.NewWeightedProposalContent( + WeightPinCodesProposal, + params.DefaultWeightPinCodesProposal, + SimulatePinContractProposal( + wasmKeeper, + DefaultSimulationCodeIDSelector, + ), + ), + simulation.NewWeightedProposalContent( + WeightUnpinCodesProposal, + params.DefaultWeightUnpinCodesProposal, + SimulateUnpinContractProposal( + wasmKeeper, + DefaultSimulationCodeIDSelector, + ), + ), + simulation.NewWeightedProposalContent( + WeightUpdateInstantiateConfigProposal, + params.DefaultWeightUpdateInstantiateConfigProposal, + SimulateUpdateInstantiateConfigProposal( + wasmKeeper, + DefaultSimulationCodeIDSelector, + ), + ), + // simulation.NewWeightedProposalContent( + // WeightStoreAndInstantiateContractProposal, + // params.DefaultWeightStoreAndInstantiateContractProposal, + // SimulateStoreAndInstantiateContractProposal( + // wasmKeeper, + // ), + // ), } } @@ -196,7 +250,7 @@ func SimulateUpdateAdminProposal(wasmKeeper WasmKeeper, contractSelector UpdateA type ClearAdminContractSelector func(sdk.Context, WasmKeeper) sdk.AccAddress -func DefaultSimulateClearAdminProposalContractSelector( +func DefaultSimulateContractSelector( ctx sdk.Context, wasmKeeper WasmKeeper, ) sdk.AccAddress { @@ -223,3 +277,130 @@ func SimulateClearAdminProposal(wasmKeeper WasmKeeper, contractSelector ClearAdm ) } } + +type MigrateContractProposalContractSelector func(sdk.Context, WasmKeeper) sdk.AccAddress + +// Simulate migrate contract proposal +func SimulateMigrateContractProposal(wasmKeeper WasmKeeper, contractSelector MigrateContractProposalContractSelector, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + ctAddress := contractSelector(ctx, wasmKeeper) + if ctAddress == nil { + return nil + } + + codeID := codeSelector(ctx, wasmKeeper) + if codeID == 0 { + return nil + } + + return types.NewMigrateContractProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + ctAddress.String(), + codeID, + []byte(`{}`), + ) + } +} + +type SudoContractProposalContractSelector func(sdk.Context, WasmKeeper) sdk.AccAddress + +// Simulate sudo contract proposal +func SimulateSudoContractProposal(wasmKeeper WasmKeeper, contractSelector SudoContractProposalContractSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + ctAddress := contractSelector(ctx, wasmKeeper) + if ctAddress == nil { + return nil + } + + return types.NewSudoContractProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + ctAddress.String(), + []byte(`{}`), + ) + } +} + +// Simulate pin contract proposal +func SimulatePinContractProposal(wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + codeID := codeSelector(ctx, wasmKeeper) + if codeID == 0 { + return nil + } + + return types.NewPinCodesProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + []uint64{codeID}, + ) + } +} + +// Simulate unpin contract proposal +func SimulateUnpinContractProposal(wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + codeID := codeSelector(ctx, wasmKeeper) + if codeID == 0 { + return nil + } + + return types.NewUnpinCodesProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + []uint64{codeID}, + ) + } +} + +// Simulate update instantiate config proposal +func SimulateUpdateInstantiateConfigProposal(wasmKeeper WasmKeeper, codeSelector CodeIDSelector) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + codeID := codeSelector(ctx, wasmKeeper) + if codeID == 0 { + return nil + } + + simAccount, _ := simtypes.RandomAcc(r, accs) + permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission + config := permission.With(simAccount.Address) + + configUpdate := types.AccessConfigUpdate{ + CodeID: codeID, + InstantiatePermission: config, + } + + return types.NewUpdateInstantiateConfigProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + configUpdate, + ) + } +} + +func SimulateStoreAndInstantiateContractProposal(wasmKeeper WasmKeeper) simtypes.ContentSimulatorFn { + return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { + simAccount, _ := simtypes.RandomAcc(r, accs) + adminAccount, _ := simtypes.RandomAcc(r, accs) + + wasmBz := testdata.ReflectContractWasm() + permission := wasmKeeper.GetParams(ctx).InstantiateDefaultPermission.With(simAccount.Address) + + return types.NewStoreAndInstantiateContractProposal( + simtypes.RandStringOfLength(r, 10), + simtypes.RandStringOfLength(r, 10), + simAccount.Address.String(), + wasmBz, + "", + "", + []byte{}, + &permission, + false, + adminAccount.Address.String(), + simtypes.RandStringOfLength(r, 10), + []byte(`{}`), + sdk.Coins{}, + ) + } +} diff --git a/x/wasm/types/proposal.go b/x/wasm/types/proposal.go index 6386f08716..96e2c9b510 100644 --- a/x/wasm/types/proposal.go +++ b/x/wasm/types/proposal.go @@ -523,6 +523,22 @@ func (p StoreAndInstantiateContractProposal) MarshalYAML() (interface{}, error) }, nil } +func NewMigrateContractProposal( + title string, + description string, + contract string, + codeID uint64, + msg RawContractMessage, +) *MigrateContractProposal { + return &MigrateContractProposal{ + Title: title, + Description: description, + Contract: contract, + CodeID: codeID, + Msg: msg, + } +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p MigrateContractProposal) ProposalRoute() string { return RouterKey } @@ -580,6 +596,20 @@ func (p MigrateContractProposal) MarshalYAML() (interface{}, error) { }, nil } +func NewSudoContractProposal( + title string, + description string, + contract string, + msg RawContractMessage, +) *SudoContractProposal { + return &SudoContractProposal{ + Title: title, + Description: description, + Contract: contract, + Msg: msg, + } +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p SudoContractProposal) ProposalRoute() string { return RouterKey } @@ -790,6 +820,18 @@ func (p ClearAdminProposal) String() string { `, p.Title, p.Description, p.Contract) } +func NewPinCodesProposal( + title string, + description string, + codeIDs []uint64, +) *PinCodesProposal { + return &PinCodesProposal{ + Title: title, + Description: description, + CodeIDs: codeIDs, + } +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p PinCodesProposal) ProposalRoute() string { return RouterKey } @@ -822,6 +864,18 @@ func (p PinCodesProposal) String() string { `, p.Title, p.Description, p.CodeIDs) } +func NewUnpinCodesProposal( + title string, + description string, + codeIDs []uint64, +) *UnpinCodesProposal { + return &UnpinCodesProposal{ + Title: title, + Description: description, + CodeIDs: codeIDs, + } +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p UnpinCodesProposal) ProposalRoute() string { return RouterKey } @@ -876,6 +930,18 @@ func validateProposalCommons(title, description string) error { return nil } +func NewUpdateInstantiateConfigProposal( + title string, + description string, + accessConfigUpdates ...AccessConfigUpdate, +) *UpdateInstantiateConfigProposal { + return &UpdateInstantiateConfigProposal{ + Title: title, + Description: description, + AccessConfigUpdates: accessConfigUpdates, + } +} + // ProposalRoute returns the routing key of a parameter change proposal. func (p UpdateInstantiateConfigProposal) ProposalRoute() string { return RouterKey } From f3ebd929cc83592b387b5535c6480a9365a65572 Mon Sep 17 00:00:00 2001 From: pinosu <95283998+pinosu@users.noreply.github.com> Date: Fri, 9 Dec 2022 13:20:49 +0100 Subject: [PATCH 039/294] Remove genesis msgs (#1104) * Remove genesis msgs * Remove genesis msgs cli * Refactor InitGenesis function --- cmd/wasmd/genwasm.go | 27 - cmd/wasmd/root.go | 1 - docs/proto/proto-docs.md | 931 +++++++++++++------------- proto/cosmwasm/wasm/v1/genesis.proto | 18 - proto/cosmwasm/wasm/v1/proposal.proto | 5 +- scripts/protocgen.sh | 2 - x/wasm/client/cli/genesis_msg.go | 531 --------------- x/wasm/client/cli/genesis_msg_test.go | 748 --------------------- x/wasm/client/cli/gov_tx.go | 2 +- x/wasm/genesis_test.go | 2 +- x/wasm/keeper/genesis.go | 18 +- x/wasm/keeper/genesis_test.go | 160 +---- x/wasm/module.go | 2 +- x/wasm/simulation/genesis.go | 1 - x/wasm/types/genesis.go | 28 +- x/wasm/types/genesis.pb.go | 563 ++-------------- x/wasm/types/genesis_test.go | 24 - x/wasm/types/proposal.pb.go | 3 +- x/wasm/types/test_fixtures.go | 6 +- 19 files changed, 514 insertions(+), 2558 deletions(-) delete mode 100644 cmd/wasmd/genwasm.go delete mode 100644 x/wasm/client/cli/genesis_msg.go delete mode 100644 x/wasm/client/cli/genesis_msg_test.go diff --git a/cmd/wasmd/genwasm.go b/cmd/wasmd/genwasm.go deleted file mode 100644 index fba3d503d2..0000000000 --- a/cmd/wasmd/genwasm.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/spf13/cobra" - - wasmcli "github.com/CosmWasm/wasmd/x/wasm/client/cli" -) - -func AddGenesisWasmMsgCmd(defaultNodeHome string) *cobra.Command { - txCmd := &cobra.Command{ - Use: "add-wasm-genesis-message", - Short: "Wasm genesis subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - genesisIO := wasmcli.NewDefaultGenesisIO() - txCmd.AddCommand( - wasmcli.GenesisStoreCodeCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisInstantiateContractCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisExecuteContractCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisListContractsCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisListCodesCmd(defaultNodeHome, genesisIO), - ) - return txCmd -} diff --git a/cmd/wasmd/root.go b/cmd/wasmd/root.go index 99889afb45..eeaf39aad5 100644 --- a/cmd/wasmd/root.go +++ b/cmd/wasmd/root.go @@ -99,7 +99,6 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), AddGenesisAccountCmd(app.DefaultNodeHome), - AddGenesisWasmMsgCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), // testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index 5609e3a0af..54d3c82f17 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -28,29 +28,10 @@ - [AccessType](#cosmwasm.wasm.v1.AccessType) - [ContractCodeHistoryOperationType](#cosmwasm.wasm.v1.ContractCodeHistoryOperationType) -- [cosmwasm/wasm/v1/tx.proto](#cosmwasm/wasm/v1/tx.proto) - - [MsgClearAdmin](#cosmwasm.wasm.v1.MsgClearAdmin) - - [MsgClearAdminResponse](#cosmwasm.wasm.v1.MsgClearAdminResponse) - - [MsgExecuteContract](#cosmwasm.wasm.v1.MsgExecuteContract) - - [MsgExecuteContractResponse](#cosmwasm.wasm.v1.MsgExecuteContractResponse) - - [MsgInstantiateContract](#cosmwasm.wasm.v1.MsgInstantiateContract) - - [MsgInstantiateContract2](#cosmwasm.wasm.v1.MsgInstantiateContract2) - - [MsgInstantiateContract2Response](#cosmwasm.wasm.v1.MsgInstantiateContract2Response) - - [MsgInstantiateContractResponse](#cosmwasm.wasm.v1.MsgInstantiateContractResponse) - - [MsgMigrateContract](#cosmwasm.wasm.v1.MsgMigrateContract) - - [MsgMigrateContractResponse](#cosmwasm.wasm.v1.MsgMigrateContractResponse) - - [MsgStoreCode](#cosmwasm.wasm.v1.MsgStoreCode) - - [MsgStoreCodeResponse](#cosmwasm.wasm.v1.MsgStoreCodeResponse) - - [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) - - [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) - - - [Msg](#cosmwasm.wasm.v1.Msg) - - [cosmwasm/wasm/v1/genesis.proto](#cosmwasm/wasm/v1/genesis.proto) - [Code](#cosmwasm.wasm.v1.Code) - [Contract](#cosmwasm.wasm.v1.Contract) - [GenesisState](#cosmwasm.wasm.v1.GenesisState) - - [GenesisState.GenMsgs](#cosmwasm.wasm.v1.GenesisState.GenMsgs) - [Sequence](#cosmwasm.wasm.v1.Sequence) - [cosmwasm/wasm/v1/ibc.proto](#cosmwasm/wasm/v1/ibc.proto) @@ -99,6 +80,24 @@ - [Query](#cosmwasm.wasm.v1.Query) +- [cosmwasm/wasm/v1/tx.proto](#cosmwasm/wasm/v1/tx.proto) + - [MsgClearAdmin](#cosmwasm.wasm.v1.MsgClearAdmin) + - [MsgClearAdminResponse](#cosmwasm.wasm.v1.MsgClearAdminResponse) + - [MsgExecuteContract](#cosmwasm.wasm.v1.MsgExecuteContract) + - [MsgExecuteContractResponse](#cosmwasm.wasm.v1.MsgExecuteContractResponse) + - [MsgInstantiateContract](#cosmwasm.wasm.v1.MsgInstantiateContract) + - [MsgInstantiateContract2](#cosmwasm.wasm.v1.MsgInstantiateContract2) + - [MsgInstantiateContract2Response](#cosmwasm.wasm.v1.MsgInstantiateContract2Response) + - [MsgInstantiateContractResponse](#cosmwasm.wasm.v1.MsgInstantiateContractResponse) + - [MsgMigrateContract](#cosmwasm.wasm.v1.MsgMigrateContract) + - [MsgMigrateContractResponse](#cosmwasm.wasm.v1.MsgMigrateContractResponse) + - [MsgStoreCode](#cosmwasm.wasm.v1.MsgStoreCode) + - [MsgStoreCodeResponse](#cosmwasm.wasm.v1.MsgStoreCodeResponse) + - [MsgUpdateAdmin](#cosmwasm.wasm.v1.MsgUpdateAdmin) + - [MsgUpdateAdminResponse](#cosmwasm.wasm.v1.MsgUpdateAdminResponse) + + - [Msg](#cosmwasm.wasm.v1.Msg) + - [Scalar Value Types](#scalar-value-types) @@ -447,356 +446,408 @@ ContractCodeHistoryOperationType actions that caused a code change - +